From 8253e3a3c33b28547fccc030f3a1b9bad72514b7 Mon Sep 17 00:00:00 2001 From: VaiTon Date: Sun, 16 May 2021 12:38:00 +0200 Subject: [PATCH] ref: use viewmodel for EditIngredientsFragment.kt feat: add dokka to build.gradle.kts --- app/build.gradle.kts | 2 + .../product/edit/ProductEditActivity.kt | 7 +- .../EditIngredientsFragment.kt} | 268 +++++++++--------- .../ingredients/EditIngredientsViewModel.kt | 26 ++ ...iewFragment.kt => EditOverviewFragment.kt} | 8 +- ...wViewModel.kt => EditOverviewViewModel.kt} | 2 +- .../scrachx/openfood/utils/EditTextUtils.kt | 1 + .../fragment_add_product_ingredients.xml | 2 +- .../layout/fragment_add_product_overview.xml | 2 +- 9 files changed, 181 insertions(+), 137 deletions(-) rename app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/{ProductEditIngredientsFragment.kt => ingredients/EditIngredientsFragment.kt} (65%) create mode 100644 app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ingredients/EditIngredientsViewModel.kt rename app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/overview/{ProductEditOverviewFragment.kt => EditOverviewFragment.kt} (99%) rename app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/overview/{OverviewViewModel.kt => EditOverviewViewModel.kt} (97%) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e77b4a0bd3cf..47ff2cacfbe1 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -21,6 +21,7 @@ plugins { id("kotlin-parcelize") id("kotlin-kapt") id("dagger.hilt.android.plugin") + id("org.jetbrains.dokka") version "1.4.32" } fun obtainTestBuildType(): String { @@ -35,6 +36,7 @@ fun obtainTestBuildType(): String { dependencies { // Kotlin implementation("org.jetbrains.kotlin:kotlin-stdlib:${rootProject.extra["kotlinVersion"]}") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0-RC") diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditActivity.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditActivity.kt index 01b56978195e..bd38cc78bdcb 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditActivity.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditActivity.kt @@ -46,7 +46,8 @@ import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsEvent import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics import openfoodfacts.github.scrachx.openfood.databinding.ActivityEditProductBinding import openfoodfacts.github.scrachx.openfood.features.product.ProductFragmentPagerAdapter -import openfoodfacts.github.scrachx.openfood.features.product.edit.overview.ProductEditOverviewFragment +import openfoodfacts.github.scrachx.openfood.features.product.edit.ingredients.EditIngredientsFragment +import openfoodfacts.github.scrachx.openfood.features.product.edit.overview.EditOverviewFragment import openfoodfacts.github.scrachx.openfood.features.shared.BaseActivity import openfoodfacts.github.scrachx.openfood.images.IMG_ID import openfoodfacts.github.scrachx.openfood.images.ProductImage @@ -99,8 +100,8 @@ class ProductEditActivity : BaseActivity() { private val addProductPhotosFragment = ProductEditPhotosFragment() private val nutritionFactsFragment = ProductEditNutritionFactsFragment() - private val ingredientsFragment = ProductEditIngredientsFragment() - private val editOverviewFragment = ProductEditOverviewFragment() + private val ingredientsFragment = EditIngredientsFragment() + private val editOverviewFragment = EditOverviewFragment() private val imagesFilePath = arrayOfNulls(3) diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditIngredientsFragment.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ingredients/EditIngredientsFragment.kt similarity index 65% rename from app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditIngredientsFragment.kt rename to app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ingredients/EditIngredientsFragment.kt index 4f5f6604b5f4..f0e1b692cc24 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ProductEditIngredientsFragment.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ingredients/EditIngredientsFragment.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package openfoodfacts.github.scrachx.openfood.features.product.edit +package openfoodfacts.github.scrachx.openfood.features.product.edit.ingredients import android.content.Intent import android.content.SharedPreferences @@ -25,6 +25,7 @@ import android.widget.ArrayAdapter import android.widget.Toast import androidx.core.net.toFile import androidx.core.widget.doAfterTextChanged +import androidx.fragment.app.viewModels import com.hootsuite.nachos.terminator.ChipTerminatorHandler import com.hootsuite.nachos.validator.ChipifyingNachoValidator import com.squareup.picasso.Callback @@ -37,23 +38,22 @@ import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsEvent import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsView import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics import openfoodfacts.github.scrachx.openfood.databinding.FragmentAddProductIngredientsBinding +import openfoodfacts.github.scrachx.openfood.features.product.edit.ProductEditActivity import openfoodfacts.github.scrachx.openfood.features.product.edit.ProductEditActivity.Companion.KEY_PERFORM_OCR import openfoodfacts.github.scrachx.openfood.features.product.edit.ProductEditActivity.Companion.KEY_SEND_UPDATED +import openfoodfacts.github.scrachx.openfood.features.product.edit.ProductEditFragment import openfoodfacts.github.scrachx.openfood.images.ProductImage import openfoodfacts.github.scrachx.openfood.models.DaoSession import openfoodfacts.github.scrachx.openfood.models.Product import openfoodfacts.github.scrachx.openfood.models.ProductImageField import openfoodfacts.github.scrachx.openfood.models.entities.OfflineSavedProduct -import openfoodfacts.github.scrachx.openfood.models.entities.allergen.AllergenName import openfoodfacts.github.scrachx.openfood.models.entities.allergen.AllergenNameDao import openfoodfacts.github.scrachx.openfood.network.ApiFields import openfoodfacts.github.scrachx.openfood.network.ApiFields.Keys.lcIngredientsKey import openfoodfacts.github.scrachx.openfood.network.OpenFoodAPIClient import openfoodfacts.github.scrachx.openfood.utils.* import openfoodfacts.github.scrachx.openfood.utils.FileDownloader.download -import org.greenrobot.greendao.async.AsyncOperationListener import java.io.File -import java.util.* import javax.inject.Inject /** @@ -62,10 +62,12 @@ import javax.inject.Inject * @see R.layout.fragment_add_product_ingredients */ @AndroidEntryPoint -class ProductEditIngredientsFragment : ProductEditFragment() { +class EditIngredientsFragment : ProductEditFragment() { private var _binding: FragmentAddProductIngredientsBinding? = null private val binding get() = _binding!! + private val viewModel: EditIngredientsViewModel by viewModels() + @Inject lateinit var daoSession: DaoSession @@ -98,10 +100,9 @@ class ProductEditIngredientsFragment : ProductEditFragment() { hideImageProgress(false, getString(R.string.image_uploaded_successfully)) } } - private var mAllergenNameDao: AllergenNameDao? = null + private var photoFile: File? = null private var code: String? = null - private val allergens: MutableList = ArrayList() private var mOfflineSavedProduct: OfflineSavedProduct? = null private var productDetails = mutableMapOf() private var imagePath: String? = null @@ -118,11 +119,15 @@ class ProductEditIngredientsFragment : ProductEditFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + val intent = if (activity == null) null else requireActivity().intent - if (intent != null && intent.getBooleanExtra(ProductEditActivity.KEY_MODIFY_NUTRITION_PROMPT, false) && !intent - .getBooleanExtra(ProductEditActivity.KEY_MODIFY_CATEGORY_PROMPT, false)) { - (activity as ProductEditActivity?)!!.proceed() + if (intent != null + && intent.getBooleanExtra(ProductEditActivity.KEY_MODIFY_NUTRITION_PROMPT, false) + && !intent.getBooleanExtra(ProductEditActivity.KEY_MODIFY_CATEGORY_PROMPT, false) + ) { + (activity as ProductEditActivity).proceed() } + binding.btnAddImageIngredients.setOnClickListener { addIngredientsImage() } binding.btnEditImageIngredients.setOnClickListener { editIngredientsImage() } binding.btnNext.setOnClickListener { next() } @@ -132,43 +137,48 @@ class ProductEditIngredientsFragment : ProductEditFragment() { binding.ingredientsList.doAfterTextChanged { toggleOCRButtonVisibility() } val bundle = arguments - if (bundle != null) { - mAllergenNameDao = daoSession.allergenNameDao - product = getProductFromArgs() - mOfflineSavedProduct = getEditOfflineProductFromArgs() - if (product != null) { - code = product!!.code - } - if (isEditingFromArgs && product != null) { - code = product!!.code - preFillProductValues() - } else if (mOfflineSavedProduct != null) { - code = mOfflineSavedProduct!!.barcode - preFillValuesForOffline() - } else { - // Fast addition - val enabled = sharedPreferences.getBoolean("fastAdditionMode", false) - enableFastAdditionMode(enabled) - } - if (bundle.getBoolean(KEY_PERFORM_OCR)) extractIngredients() - - if (bundle.getBoolean(KEY_SEND_UPDATED)) editIngredientsImage() - } else { + if (bundle == null) { Toast.makeText(activity, R.string.error_adding_ingredients, Toast.LENGTH_SHORT).show() + requireActivity().finish() + return + } + + product = getProductFromArgs() + + mOfflineSavedProduct = getEditOfflineProductFromArgs() + if (product != null) { + code = product!!.code + } + + if (isEditingFromArgs && product != null) { + code = product!!.code + preFillProductValues() + } else if (mOfflineSavedProduct != null) { + code = mOfflineSavedProduct!!.barcode + preFillValuesForOffline() + } else { + // Fast addition + val enabled = requireContext().isFastAdditionMode() + enableFastAdditionMode(enabled) } - val imageIngredients = getImageIngredients() - if (binding.ingredientsList.isEmpty() && !imageIngredients.isNullOrEmpty()) { + if (bundle.getBoolean(KEY_PERFORM_OCR)) extractIngredients() + + if (bundle.getBoolean(KEY_SEND_UPDATED)) editIngredientsImage() + + val ingredientsImg = getImageIngredients() + if (binding.ingredientsList.isEmpty() && !ingredientsImg.isNullOrEmpty()) { binding.btnExtractIngredients.visibility = View.VISIBLE - imagePath = imageIngredients + imagePath = ingredientsImg } else if (isEditingFromArgs - && binding.ingredientsList.isEmpty() - && !product!!.imageIngredientsUrl.isNullOrEmpty()) { + && binding.ingredientsList.isEmpty() + && !product!!.imageIngredientsUrl.isNullOrEmpty() + ) { binding.btnExtractIngredients.visibility = View.VISIBLE } - loadAutoSuggestions() + viewModel.allergens.observe(viewLifecycleOwner) { loadAutoSuggestions(it) } if (activity is ProductEditActivity && (activity as ProductEditActivity).initialValues != null) { getAllDetails((activity as ProductEditActivity).initialValues!!) @@ -185,7 +195,7 @@ class ProductEditIngredientsFragment : ProductEditFragment() { private fun getAddProductActivity() = activity as ProductEditActivity? private fun extractTracesChipValues(product: Product?): List = - product?.tracesTags?.map { getTracesName(localeManager.getLanguage(), it) } ?: emptyList() + product?.tracesTags?.map { getTracesName(localeManager.getLanguage(), it) } ?: emptyList() /** * Pre fill the fields of the product which are already present on the server. @@ -213,13 +223,13 @@ class ProductEditIngredientsFragment : ProductEditFragment() { binding.imageProgress.visibility = View.VISIBLE imagePath = newImageIngredientsUrl picasso - .load(newImageIngredientsUrl) - .resize(dps50ToPixels, dps50ToPixels) - .centerInside() - .into(binding.btnAddImageIngredients, object : Callback { - override fun onSuccess() = imageLoaded() - override fun onError(ex: Exception) = imageLoaded() - }) + .load(newImageIngredientsUrl) + .resize(dps50ToPixels, dps50ToPixels) + .centerInside() + .into(binding.btnAddImageIngredients, object : Callback { + override fun onSuccess() = imageLoaded() + override fun onError(ex: Exception) = imageLoaded() + }) } } @@ -238,10 +248,9 @@ class ProductEditIngredientsFragment : ProductEditFragment() { * @param tag Tag associated with the allergen */ private fun getTracesName(languageCode: String, tag: String): String { - val allergenName = mAllergenNameDao!!.queryBuilder() - .where(AllergenNameDao.Properties.AllergenTag.eq(tag), AllergenNameDao.Properties.LanguageCode.eq(languageCode)) - .unique() - return allergenName?.name ?: tag + return daoSession.allergenNameDao!!.queryBuilder() + .where(AllergenNameDao.Properties.AllergenTag.eq(tag), AllergenNameDao.Properties.LanguageCode.eq(languageCode)) + .unique()?.name ?: tag } override fun onDestroyView() { @@ -270,24 +279,28 @@ class ProductEditIngredientsFragment : ProductEditFragment() { * Pre fill the fields if the product is already present in SavedProductOffline db. */ private fun preFillValuesForOffline() { - productDetails = mOfflineSavedProduct!!.productDetails.toMutableMap() - if (getImageIngredients() != null) { + val prod = mOfflineSavedProduct!! + + productDetails = prod.productDetails.toMutableMap() + + getImageIngredients()?.let { binding.imageProgress.visibility = View.VISIBLE picasso - .load(LOCALE_FILE_SCHEME + getImageIngredients()) - .resize(dps50ToPixels, dps50ToPixels) - .centerInside() - .into(binding.btnAddImageIngredients, object : Callback { - override fun onSuccess() { - binding.imageProgress.visibility = View.GONE - } - - override fun onError(ex: Exception) { - binding.imageProgress.visibility = View.GONE - } - }) + .load(LOCALE_FILE_SCHEME + it) + .resize(dps50ToPixels, dps50ToPixels) + .centerInside() + .into(binding.btnAddImageIngredients, object : Callback { + override fun onSuccess() { + binding.imageProgress.visibility = View.GONE + } + + override fun onError(ex: Exception) { + binding.imageProgress.visibility = View.GONE + } + }) } - mOfflineSavedProduct!!.ingredients.let { + + prod.ingredients.let { if (!it.isNullOrEmpty()) binding.ingredientsList.setText(it) } @@ -301,28 +314,15 @@ class ProductEditIngredientsFragment : ProductEditFragment() { /** * Automatically load suggestions for allergen names */ - private fun loadAutoSuggestions() { - val asyncSessionAllergens = daoSession.startAsyncSession() - val allergenNameDao = daoSession.allergenNameDao - val appLanguageCode = localeManager.getLanguage() - - asyncSessionAllergens.listenerMainThread = AsyncOperationListener { operation -> - val allergenNames = operation.result as List - allergens.clear() - allergenNames.forEach { allergens += it.name } - - val adapter = ArrayAdapter(requireActivity(), android.R.layout.simple_dropdown_item_1line, allergens) - binding.traces.addChipTerminator(',', ChipTerminatorHandler.BEHAVIOR_CHIPIFY_CURRENT_TOKEN) - binding.traces.setNachoValidator(ChipifyingNachoValidator()) - binding.traces.enableEditChipOnTouch(false, true) - binding.traces.setAdapter(adapter) - } - - asyncSessionAllergens.queryList(allergenNameDao.queryBuilder() - .where(AllergenNameDao.Properties.LanguageCode.eq(appLanguageCode)) - .orderDesc(AllergenNameDao.Properties.Name).build()) + private fun loadAutoSuggestions(allergens: List) { + val adapter = ArrayAdapter(requireActivity(), android.R.layout.simple_dropdown_item_1line, allergens) + binding.traces.addChipTerminator(',', ChipTerminatorHandler.BEHAVIOR_CHIPIFY_CURRENT_TOKEN) + binding.traces.setNachoValidator(ChipifyingNachoValidator()) + binding.traces.enableEditChipOnTouch(false, true) + binding.traces.setAdapter(adapter) } + override fun doOnPhotosPermissionGranted() = editIngredientsImage() private fun addIngredientsImage() { @@ -331,11 +331,11 @@ class ProductEditIngredientsFragment : ProductEditFragment() { photoFile != null -> cropRotateImage(photoFile!!, getString(R.string.ingredients_picture)) else -> { download(requireContext(), imagePath!!, client) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe { uri -> - photoFile = uri.toFile() - cropRotateImage(uri, getString(R.string.ingredients_picture)) - }.addTo(disp) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { uri -> + photoFile = uri.toFile() + cropRotateImage(uri, getString(R.string.ingredients_picture)) + }.addTo(disp) } } } @@ -350,16 +350,22 @@ class ProductEditIngredientsFragment : ProductEditFragment() { } private fun extractIngredients() { - (activity as? ProductEditActivity)?.let { - val imagePath = imagePath - if (imagePath != null && (!isEditingFromArgs || newImageSelected)) { - photoFile = File(imagePath) - val image = ProductImage(code!!, ProductImageField.INGREDIENTS, photoFile!!, localeManager.getLanguage()) - image.filePath = imagePath - (activity as ProductEditActivity).addToPhotoMap(image, 1) - } else if (imagePath != null) { - (activity as ProductEditActivity).performOCR(code!!, "ingredients_" + (activity as ProductEditActivity).getProductLanguageForEdition()) + (activity as? ProductEditActivity)?.let { activity -> + + imagePath?.let { imagePath -> + if (!isEditingFromArgs || newImageSelected) { + photoFile = File(imagePath) + val image = ProductImage(code!!, ProductImageField.INGREDIENTS, photoFile!!, localeManager.getLanguage()) + image.filePath = imagePath + activity.addToPhotoMap(image, 1) + } else { + activity.performOCR( + code!!, + "ingredients_" + activity.getProductLanguageForEdition() + ) + } } + } } @@ -382,13 +388,16 @@ class ProductEditIngredientsFragment : ProductEditFragment() { */ private fun getAllDetails(targetMap: MutableMap) { binding.traces.chipifyAllUnterminatedTokens() - if (activity is ProductEditActivity) { - val languageCode = (activity as ProductEditActivity).getProductLanguageForEdition() - val lc = if (!languageCode.isNullOrEmpty()) languageCode else ApiFields.Defaults.DEFAULT_LANGUAGE + (activity as? ProductEditActivity)?.let { activity -> + + val lc = activity.getProductLanguageForEdition() + ?.takeUnless { it.isEmpty() } ?: ApiFields.Defaults.DEFAULT_LANGUAGE + targetMap[lcIngredientsKey(lc)] = binding.ingredientsList.text.toString() val string = binding.traces.chipValues.joinToString(",") targetMap[ApiFields.Keys.ADD_TRACES.substring(4)] = string } + } /** @@ -398,14 +407,19 @@ class ProductEditIngredientsFragment : ProductEditFragment() { binding.traces.chipifyAllUnterminatedTokens() if (activity !is ProductEditActivity) return - if (binding.ingredientsList.isNotEmpty() && binding.ingredientsList.isContentDifferent(if (product != null) product!!.ingredientsText else null)) { - val languageCode = (activity as ProductEditActivity).getProductLanguageForEdition() - val lc = if (!languageCode.isNullOrEmpty()) languageCode else ApiFields.Defaults.DEFAULT_LANGUAGE - targetMap[lcIngredientsKey(lc)] = binding.ingredientsList.text.toString() - } - if (binding.traces.chipValues.isNotEmpty() && binding.traces.areChipsDifferent(extractTracesChipValues(product))) { - targetMap[ApiFields.Keys.ADD_TRACES] = binding.traces.chipValues.joinToString(",") - } + binding.ingredientsList + .takeIf { it.isContentDifferent(product?.ingredientsText) } + ?.let { + val languageCode = (activity as ProductEditActivity).getProductLanguageForEdition() + val lc = if (!languageCode.isNullOrEmpty()) languageCode else ApiFields.Defaults.DEFAULT_LANGUAGE + targetMap[lcIngredientsKey(lc)] = it.getContent() + } + + binding.traces + .takeIf { it.isNotEmpty() && it.areChipsDifferent(extractTracesChipValues(product)) } + ?.let { + targetMap[ApiFields.Keys.ADD_TRACES] = it.chipValues.joinToString(",") + } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { @@ -435,12 +449,13 @@ class ProductEditIngredientsFragment : ProductEditFragment() { binding.imageProgressText.visibility = View.GONE binding.btnAddImageIngredients.visibility = View.VISIBLE binding.btnEditImageIngredients.visibility = View.VISIBLE + if (!errorInUploading) { - Picasso.get() - .load(photoFile!!) - .resize(dps50ToPixels, dps50ToPixels) - .centerInside() - .into(binding.btnAddImageIngredients) + picasso + .load(photoFile!!) + .resize(dps50ToPixels, dps50ToPixels) + .centerInside() + .into(binding.btnAddImageIngredients) } } @@ -451,19 +466,18 @@ class ProductEditIngredientsFragment : ProductEditFragment() { * @param ocrResult resultant string obtained after OCR of image */ fun setIngredients(status: String?, ocrResult: String?) { - if (activity != null && !requireActivity().isFinishing) { - when (status) { - "set" -> { - binding.ingredientsList.setText(ocrResult) - loadIngredientsImage() - } - "0" -> { - binding.ingredientsList.setText(ocrResult) - binding.btnLooksGood.visibility = View.VISIBLE - binding.btnSkipIngredients.visibility = View.VISIBLE - } - else -> Toast.makeText(activity, R.string.unable_to_extract_ingredients, Toast.LENGTH_SHORT).show() + if (activity == null || requireActivity().isFinishing) return + when (status) { + "set" -> { + binding.ingredientsList.setText(ocrResult) + loadIngredientsImage() + } + "0" -> { + binding.ingredientsList.setText(ocrResult) + binding.btnLooksGood.visibility = View.VISIBLE + binding.btnSkipIngredients.visibility = View.VISIBLE } + else -> Toast.makeText(activity, R.string.unable_to_extract_ingredients, Toast.LENGTH_SHORT).show() } } diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ingredients/EditIngredientsViewModel.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ingredients/EditIngredientsViewModel.kt new file mode 100644 index 000000000000..69b5109b910c --- /dev/null +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/ingredients/EditIngredientsViewModel.kt @@ -0,0 +1,26 @@ +package openfoodfacts.github.scrachx.openfood.features.product.edit.ingredients + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.liveData +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 javax.inject.Inject + +@HiltViewModel +class EditIngredientsViewModel @Inject constructor( + private val daoSession: DaoSession, + private val localeManager: LocaleManager +) : 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) } + } + +} \ No newline at end of file diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/overview/ProductEditOverviewFragment.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/overview/EditOverviewFragment.kt similarity index 99% rename from app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/overview/ProductEditOverviewFragment.kt rename to app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/overview/EditOverviewFragment.kt index 8434ee47eaa1..0875a7514f23 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/overview/ProductEditOverviewFragment.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/overview/EditOverviewFragment.kt @@ -81,7 +81,7 @@ import javax.inject.Inject * Product Overview fragment of AddProductActivity */ @AndroidEntryPoint -class ProductEditOverviewFragment : ProductEditFragment() { +class EditOverviewFragment : ProductEditFragment() { private var _binding: FragmentAddProductOverviewBinding? = null private val binding get() = _binding!! @@ -485,7 +485,7 @@ class ProductEditOverviewFragment : ProductEditFragment() { @Inject lateinit var daoSession: DaoSession - private val viewModel: OverviewViewModel by viewModels() + private val viewModel: EditOverviewViewModel by viewModels() /** * Auto load suggestions into various NachoTextViews @@ -583,14 +583,14 @@ class ProductEditOverviewFragment : ProductEditFragment() { binding.name.isActivated = false } .doOnError { - Log.e(ProductEditOverviewFragment::class.java.simpleName, "Error retrieving product state from server api.", it) + Log.e(EditOverviewFragment::class.java.simpleName, "Error retrieving product state from server api.", it) binding.name.setText(StringUtils.EMPTY) binding.name.isActivated = true } .subscribe { productState -> if (productState.status != 1L) { Log.e( - ProductEditOverviewFragment::class.simpleName, + EditOverviewFragment::class.simpleName, "Retrieved product with code ${productState.code}, but status was not successful." ) binding.name.setText(StringUtils.EMPTY) diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/overview/OverviewViewModel.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/overview/EditOverviewViewModel.kt similarity index 97% rename from app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/overview/OverviewViewModel.kt rename to app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/overview/EditOverviewViewModel.kt index c44ff4820a46..3835e8b9d1c1 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/overview/OverviewViewModel.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/features/product/edit/overview/EditOverviewViewModel.kt @@ -13,7 +13,7 @@ import openfoodfacts.github.scrachx.openfood.utils.LocaleManager import javax.inject.Inject @HiltViewModel -class OverviewViewModel @Inject constructor( +class EditOverviewViewModel @Inject constructor( private val daoSession: DaoSession, private val localeManager: LocaleManager ) : ViewModel() { diff --git a/app/src/main/java/openfoodfacts/github/scrachx/openfood/utils/EditTextUtils.kt b/app/src/main/java/openfoodfacts/github/scrachx/openfood/utils/EditTextUtils.kt index 246c17f3f4ea..892586485aae 100644 --- a/app/src/main/java/openfoodfacts/github/scrachx/openfood/utils/EditTextUtils.kt +++ b/app/src/main/java/openfoodfacts/github/scrachx/openfood/utils/EditTextUtils.kt @@ -11,6 +11,7 @@ fun EditText?.getContent() = this?.text?.toString() * @return true if the edit text string value is not empty */ fun EditText?.isNotEmpty() = !isEmpty() + fun EditText.isContentDifferent(toCompare: String?): Boolean { val fieldValue = getContent() return !(fieldValue.isNullOrEmpty() && toCompare.isNullOrEmpty() diff --git a/app/src/main/res/layout/fragment_add_product_ingredients.xml b/app/src/main/res/layout/fragment_add_product_ingredients.xml index 4503187fcf6c..ddfae686de2f 100644 --- a/app/src/main/res/layout/fragment_add_product_ingredients.xml +++ b/app/src/main/res/layout/fragment_add_product_ingredients.xml @@ -14,7 +14,7 @@ android:clipToPadding="false" android:isScrollContainer="false" app:layout_behavior="@string/appbar_scrolling_view_behavior" - tools:context=".features.product.edit.ProductEditIngredientsFragment"> + tools:context=".features.product.edit.ingredients.EditIngredientsFragment"> + tools:context=".features.product.edit.overview.EditOverviewFragment">