Skip to content

Commit

Permalink
fix: refactored measurements inner working (#4171)
Browse files Browse the repository at this point in the history
* fix: refactored measurements inner working
* ref: use extension functions to query db

Closes #4145

Co-authored-by: naivekook <tanakov.dev@gmail.com>
  • Loading branch information
VaiTon and naivekook committed Aug 24, 2021
1 parent 76e189e commit ba334af
Show file tree
Hide file tree
Showing 45 changed files with 1,522 additions and 1,399 deletions.
Expand Up @@ -9,23 +9,21 @@ class CalculatedNutrimentsGridAdapter(private val nutrimentListItems: List<Nutri
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NutrimentViewHolder {
val isViewTypeHeader = viewType == TYPE_HEADER
val layoutResourceId = if (isViewTypeHeader) R.layout.nutrition_fact_header_calc else R.layout.nutriment_item_list
val v = LayoutInflater.from(parent.context).inflate(layoutResourceId, parent, false)
val view = LayoutInflater.from(parent.context).inflate(layoutResourceId, parent, false)

return if (isViewTypeHeader) {
val displayServing = nutrimentListItems
.map { it.servingValue }
.any { it.isNotBlank() }
NutrimentViewHolder.NutrimentHeaderViewHolder(v, displayServing)
val displayServing = nutrimentListItems.any { !it.servingValueStr.isNullOrBlank() }
NutrimentViewHolder.NutrimentHeaderViewHolder(view, displayServing)
} else {
NutrimentViewHolder.NutrimentListViewHolder(v)
NutrimentViewHolder.NutrimentListViewHolder(view)
}
}

override fun onBindViewHolder(holder: NutrimentViewHolder, position: Int) {
if (holder !is NutrimentViewHolder.NutrimentListViewHolder) return

val item = nutrimentListItems[position]
holder.fillNutrimentValue(item)
holder.fillServingValue(item)
holder.fillNutriment(item)
holder.setIsRecyclable(false)
}

Expand Down
Expand Up @@ -12,23 +12,19 @@ import openfoodfacts.github.scrachx.openfood.models.NutrimentListItem
* @author herau
*/
open class NutrimentsGridAdapter(
private val nutrimentListItems: List<NutrimentListItem>
private val nutrimentListItems: List<NutrimentListItem>
) : RecyclerView.Adapter<NutrimentsGridAdapter.NutrimentViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NutrimentViewHolder {
val isViewTypeHeader = viewType == TYPE_HEADER
val layoutResourceId = if (isViewTypeHeader) R.layout.nutriment_item_list_header else R.layout.nutriment_item_list
val v = LayoutInflater.from(parent.context).inflate(layoutResourceId, parent, false)
val view = LayoutInflater.from(parent.context).inflate(layoutResourceId, parent, false)

return if (isViewTypeHeader) {
var displayServing = false
for (nutriment in nutrimentListItems) {
val servingValue = nutriment.servingValue
if (servingValue.isBlank()) displayServing = true
}
NutrimentViewHolder.NutrimentHeaderViewHolder(v, displayServing)
val displayServing = nutrimentListItems.any { !it.servingValueStr.isNullOrBlank() }
NutrimentViewHolder.NutrimentHeaderViewHolder(view, displayServing)
} else {
NutrimentViewHolder.NutrimentListViewHolder(v)
NutrimentViewHolder.NutrimentListViewHolder(view)
}
}

Expand All @@ -40,8 +36,7 @@ open class NutrimentsGridAdapter(
}
is NutrimentViewHolder.NutrimentListViewHolder -> {
val item = nutrimentListItems[position]
holder.fillNutrimentValue(item)
holder.fillServingValue(item)
holder.fillNutriment(item)
}
}
}
Expand Down Expand Up @@ -69,25 +64,42 @@ open class NutrimentsGridAdapter(
private val vNutrimentServingValue: TextView = v.findViewById(R.id.nutriment_serving_value)
private val vNutrimentValue: TextView = v.findViewById(R.id.nutriment_value)

fun fillNutrimentValue(item: NutrimentListItem) {
fun fillNutriment(item: NutrimentListItem) {
fillNutrimentName(item)
fillNutrimentValue(item)
fillServingValue(item)
}


private fun fillNutrimentName(item: NutrimentListItem) {
vNutrimentName.text = item.title
vNutrimentValue.append("${item.modifier} ${item.value} ${item.unit}")
}

fun fillServingValue(item: NutrimentListItem) {
val servingValue = item.servingValue
if (servingValue.isBlank()) {
private fun fillNutrimentValue(item: NutrimentListItem) {
val value = item.value
if (value == null) {
vNutrimentValue.visibility = View.INVISIBLE
} else {
vNutrimentValue.visibility = View.VISIBLE
vNutrimentValue.text = "${item.modifierStr} $value ${item.unitStr}"
}
}

private fun fillServingValue(item: NutrimentListItem) {
val servingValue = item.servingValueStr
if (servingValue == null) {
vNutrimentServingValue.visibility = View.GONE
} else {
vNutrimentServingValue.append(String.format("%s %s %s",
item.modifier,
servingValue,
item.unit))
vNutrimentServingValue.visibility = View.VISIBLE
vNutrimentServingValue.text = "${item.modifierStr} $servingValue ${item.unitStr}"
}
}
}

internal class NutrimentHeaderViewHolder(itemView: View, displayServing: Boolean) : NutrimentViewHolder(itemView) {
internal class NutrimentHeaderViewHolder(
itemView: View,
displayServing: Boolean
) : NutrimentViewHolder(itemView) {
val vNutrimentValue: TextView = itemView.findViewById(R.id.nutriment_value)
private val nutrimentServingValue: TextView = itemView.findViewById(R.id.nutriment_serving_value)

Expand Down
@@ -1,6 +1,5 @@
package openfoodfacts.github.scrachx.openfood.features.additives

import android.text.SpannableStringBuilder
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.text.style.DynamicDrawableSpan
Expand All @@ -9,10 +8,10 @@ import android.view.View
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.text.bold
import androidx.core.text.buildSpannedString
import androidx.core.text.color
import androidx.core.text.inSpans
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.fasterxml.jackson.databind.JsonNode
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -44,14 +43,14 @@ object AdditiveFragmentHelper {
) = additivesView.run {
movementMethod = LinkMovementMethod.getInstance()
isClickable = true
text = SpannableStringBuilder()
.bold { append(fragment.getString(R.string.txtAdditives)) }
.apply {
additives.forEach {
append("\n")
append(getAdditiveTag(it, apiClientForWikiData, fragment, fragment))
}
text = buildSpannedString {
bold { append(fragment.getString(R.string.txtAdditives)) }

additives.forEach {
append("\n")
append(getAdditiveTag(it, apiClientForWikiData, fragment))
}
}
}

/**
Expand All @@ -64,14 +63,13 @@ object AdditiveFragmentHelper {
private fun getAdditiveTag(
additive: AdditiveName,
wikidataClient: WikiDataApiClient,
fragment: BaseFragment,
lifecycleOwner: LifecycleOwner
fragment: BaseFragment
): CharSequence {
val activity = fragment.requireActivity()
val clickableSpan = object : ClickableSpan() {
override fun onClick(view: View) {
if (additive.isWikiDataIdPresent) {
lifecycleOwner.lifecycleScope.launch {
fragment.lifecycleScope.launch {
val result = wikidataClient.getEntityData(additive.wikiDataId)
getOnWikiResponse(activity, additive)(result)
}
Expand All @@ -81,30 +79,31 @@ object AdditiveFragmentHelper {
}
}

return SpannableStringBuilder().also {
it.inSpans(clickableSpan) { append(additive.name) }
return buildSpannedString {
inSpans(clickableSpan) { append(additive.name) }

// if the additive has an overexposure risk ("high" or "moderate") then append the warning message to it
if (additive.hasOverexposureData()) {
val isHighRisk = additive.overexposureRisk.equals("high", true)

val riskIcon = (
if (isHighRisk) ContextCompat.getDrawable(activity, R.drawable.ic_additive_high_risk)
else ContextCompat.getDrawable(activity, R.drawable.ic_additive_moderate_risk)
)?.apply {
setBounds(0, 0, this.intrinsicWidth, this.intrinsicHeight)
}!!
val riskIcon = if (isHighRisk)
ContextCompat.getDrawable(activity, R.drawable.ic_additive_high_risk)!!
else
ContextCompat.getDrawable(activity, R.drawable.ic_additive_moderate_risk)!!
riskIcon.setBounds(0, 0, riskIcon.intrinsicWidth, riskIcon.intrinsicHeight)

val riskWarningStr =
if (isHighRisk) fragment.getString(R.string.overexposure_high)
else fragment.getString(R.string.overexposure_moderate)

val riskWarningColor =
if (isHighRisk) ContextCompat.getColor(activity, R.color.overexposure_high)
else ContextCompat.getColor(activity, R.color.overexposure_moderate)

it.append(" ")
it.inSpans(ImageSpan(riskIcon, DynamicDrawableSpan.ALIGN_BOTTOM)) { it.append("-") }
it.append(" ")
it.color(riskWarningColor) { append(riskWarningStr) }
append(" ")
inSpans(ImageSpan(riskIcon, DynamicDrawableSpan.ALIGN_BOTTOM)) { append("-") }
append(" ")
color(riskWarningColor) { append(riskWarningStr) }
}
}
}
Expand Down
Expand Up @@ -19,7 +19,6 @@ import android.Manifest.permission
import android.app.Activity
import android.content.pm.PackageManager.PERMISSION_GRANTED
import android.os.Build
import android.text.SpannableStringBuilder
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
Expand All @@ -28,6 +27,7 @@ import android.widget.TextView
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat.checkSelfPermission
import androidx.core.text.bold
import androidx.core.text.buildSpannedString
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.squareup.picasso.Picasso
Expand Down Expand Up @@ -149,21 +149,23 @@ class ProductCompareAdapter(

// Quantity
if (!product.quantity.isNullOrBlank()) {
holder.binding.productComparisonQuantity.text = SpannableStringBuilder()
.bold { append(activity.getString(R.string.compare_quantity)) }
.append(" ")
.append(product.quantity)
holder.binding.productComparisonQuantity.text = buildSpannedString {
bold { append(activity.getString(R.string.compare_quantity)) }
append(" ")
append(product.quantity)
}
} else {
holder.binding.productComparisonQuantity.visibility = View.INVISIBLE
}

// Brands
val brands = product.brands
if (!brands.isNullOrBlank()) {
holder.binding.productComparisonBrand.text = SpannableStringBuilder()
.bold { append(activity.getString(R.string.compare_brands)) }
.append(" ")
.append(brands.split(",").joinToString(", ") { it.trim() })
holder.binding.productComparisonBrand.text = buildSpannedString {
bold { append(activity.getString(R.string.compare_brands)) }
append(" ")
append(brands.split(",").joinToString(", ") { it.trim() })
}
} else {
//TODO: product brand placeholder goes here
}
Expand Down Expand Up @@ -202,10 +204,11 @@ class ProductCompareAdapter(
private fun loadAdditives(additiveNames: List<AdditiveName>, view: TextView) {
if (additiveNames.isEmpty()) return

view.text = SpannableStringBuilder()
.bold { append(activity.getString(R.string.compare_additives)) }
.append("\n")
.append(additiveNames.joinToString("\n") { it.name })
view.text = buildSpannedString {
bold { append(activity.getString(R.string.compare_additives)) }
append("\n")
append(additiveNames.joinToString("\n") { it.name })
}

updateCardsHeight()
}
Expand All @@ -229,42 +232,42 @@ class ProductCompareAdapter(
}

if (fat != null || salt != null || saturatedFat != null || sugars != null) {
val fatNutriment = nutriments[Nutriments.FAT]
val fatNutriment = nutriments[Nutriment.FAT]
if (fat != null && fatNutriment != null) {
val fatNutrimentLevel = fat.getLocalize(activity)
levelItems += NutrientLevelItem(
activity.getString(R.string.compare_fat),
fatNutriment.displayStringFor100g,
fatNutriment.getPer100gDisplayString(),
fatNutrimentLevel,
fat.getImgRes()
)
}
val saturatedFatNutriment = nutriments[Nutriments.SATURATED_FAT]
val saturatedFatNutriment = nutriments[Nutriment.SATURATED_FAT]
if (saturatedFat != null && saturatedFatNutriment != null) {
val saturatedFatLocalize = saturatedFat.getLocalize(activity)
levelItems += NutrientLevelItem(
activity.getString(R.string.compare_saturated_fat),
saturatedFatNutriment.displayStringFor100g,
saturatedFatNutriment.getPer100gDisplayString(),
saturatedFatLocalize,
saturatedFat.getImgRes()
)
}
val sugarsNutriment = nutriments[Nutriments.SUGARS]
val sugarsNutriment = nutriments[Nutriment.SUGARS]
if (sugars != null && sugarsNutriment != null) {
val sugarsLocalize = sugars.getLocalize(activity)
levelItems += NutrientLevelItem(
activity.getString(R.string.compare_sugars),
sugarsNutriment.displayStringFor100g,
sugarsNutriment.getPer100gDisplayString(),
sugarsLocalize,
sugars.getImgRes()
)
}
val saltNutriment = nutriments[Nutriments.SALT]
val saltNutriment = nutriments[Nutriment.SALT]
if (salt != null && saltNutriment != null) {
val saltLocalize = salt.getLocalize(activity)
levelItems += NutrientLevelItem(
activity.getString(R.string.compare_salt),
saltNutriment.displayStringFor100g,
saltNutriment.getPer100gDisplayString(),
saltLocalize,
salt.getImgRes()
)
Expand Down
Expand Up @@ -252,9 +252,10 @@ class EditIngredientsFragment : ProductEditFragment() {
* @param tag Tag associated with the allergen
*/
private fun getTracesName(languageCode: String, tag: String): String {
return daoSession.allergenNameDao!!.queryBuilder()
.where(AllergenNameDao.Properties.AllergenTag.eq(tag), AllergenNameDao.Properties.LanguageCode.eq(languageCode))
.unique()?.name ?: tag
return daoSession.allergenNameDao.unique {
where(AllergenNameDao.Properties.AllergenTag.eq(tag))
where(AllergenNameDao.Properties.LanguageCode.eq(languageCode))
}?.name ?: tag
}

override fun onDestroyView() {
Expand Down
Expand Up @@ -6,6 +6,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import openfoodfacts.github.scrachx.openfood.models.DaoSession
import openfoodfacts.github.scrachx.openfood.models.entities.allergen.AllergenNameDao
import openfoodfacts.github.scrachx.openfood.utils.LocaleManager
import openfoodfacts.github.scrachx.openfood.utils.list
import javax.inject.Inject

@HiltViewModel
Expand All @@ -15,12 +16,10 @@ class EditIngredientsViewModel @Inject constructor(
) : ViewModel() {

val allergens = liveData {
daoSession.allergenNameDao.queryBuilder()
.where(AllergenNameDao.Properties.LanguageCode.eq(localeManager.getLanguage()))
.orderDesc(AllergenNameDao.Properties.Name)
.list()
.map { it.name }
.let { emit(it) }
daoSession.allergenNameDao.list {
where(AllergenNameDao.Properties.LanguageCode.eq(localeManager.getLanguage()))
orderDesc(AllergenNameDao.Properties.Name)
}?.map { it.name }.let { emit(it) }
}

}

0 comments on commit ba334af

Please sign in to comment.