Skip to content

Commit

Permalink
chore: throw error if cache path is not a dir
Browse files Browse the repository at this point in the history
refactor: minors in EditIngredientsFragment.kt

refactor: use only an instance of KEY_PRODUCT

design: increase traces NachoTextView height from 40dp to 48dp

design: remove icon from "extract ingredient" button in fragment_add_product_ingredients.xml

refactor: extract confirmation dialog fun in ProductEditActivity.kt

refactor: extract getUpdatedFieldsMap in ProductEditActivity.kt
  • Loading branch information
VaiTon committed Oct 24, 2021
1 parent 82fb4dd commit 2861d23
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 61 deletions.
Expand Up @@ -135,29 +135,34 @@ class ProductEditActivity : BaseActivity() {
}

override fun onBackPressed() {
// If the user changed something, alert before exiting
if (getUpdatedFieldsMap().isNotEmpty()) showExitConfirmDialog()
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
android.R.id.home -> {
if (getUpdatedFieldsMap().isNotEmpty()) {
showExitConfirmDialog()
true
} else false
}
R.id.save_product -> {
checkFieldsThenSave()
true
}
else -> super.onOptionsItemSelected(item)
}
}

private fun showExitConfirmDialog() {
MaterialAlertDialogBuilder(this)
.setMessage(R.string.save_product)
.setPositiveButton(R.string.txtSave) { _, _ -> checkFieldsThenSave() }
.setNegativeButton(R.string.txtPictureNeededDialogNo) { _, _ -> super.onBackPressed() }
.setNegativeButton(R.string.txt_discard) { _, _ -> super.onBackPressed() }
.show()
}

override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
android.R.id.home -> {
MaterialAlertDialogBuilder(this)
.setMessage(R.string.save_product)
.setPositiveButton(R.string.txtSave) { _, _ -> checkFieldsThenSave() }
.setNegativeButton(R.string.txt_discard) { _, _ -> finish() }
.show()
true
}
R.id.save_product -> {
checkFieldsThenSave()
true
}
else -> super.onOptionsItemSelected(item)
}

private fun selectPage(position: Int) = when (position) {
1 -> updateTimelineIndicator(2, 1, 0)
2 -> updateTimelineIndicator(2, 2, 1)
Expand Down Expand Up @@ -234,7 +239,7 @@ class ProductEditActivity : BaseActivity() {

private fun setupViewPager(viewPager: ViewPager2) {
// Initialize fragments
fragmentsBundle.putSerializable("product", mProduct)
fragmentsBundle.putSerializable(KEY_PRODUCT, mProduct)

editOverviewFragment.arguments = fragmentsBundle
ingredientsFragment.arguments = fragmentsBundle
Expand All @@ -261,9 +266,6 @@ class ProductEditActivity : BaseActivity() {
viewPager.adapter = adapterResult
}

private fun createTextPlain(code: String) =
RequestBody.create(OpenFoodAPIClient.MIME_TEXT, code)

private fun getLoginPasswordInfo(): Map<String, RequestBody> {
val map = hashMapOf<String, RequestBody>()
val settings = getLoginPreferences()
Expand All @@ -281,15 +283,20 @@ class ProductEditActivity : BaseActivity() {
}

private suspend fun saveProduct() {
productDetails += editOverviewFragment.getUpdatedFieldsMap()
productDetails += ingredientsFragment.getUpdatedFieldsMap()
if (isFlavors(OFF, OPFF)) {
productDetails += nutritionFactsFragment.getUpdatedFieldsMap()
}
productDetails += getLoginInfoMap()
productDetails += getUpdatedFieldsMap() + getLoginInfoMap()
saveProductOffline()
}

private fun getUpdatedFieldsMap(): Map<String, String?> {
val updatedValues = editOverviewFragment.getUpdatedFieldsMap().toMutableMap()
updatedValues += ingredientsFragment.getUpdatedFieldsMap()

if (isFlavors(OFF, OPFF))
updatedValues += nutritionFactsFragment.getUpdatedFieldsMap()

return updatedValues
}

fun proceed() = if (binding.viewpager.currentItem < 2) {
binding.viewpager.setCurrentItem(binding.viewpager.currentItem + 1, true)
} else checkFieldsThenSave()
Expand Down Expand Up @@ -529,7 +536,9 @@ class ProductEditActivity : BaseActivity() {


suspend fun performOCR(code: String, imageField: String) {
withContext(Main) { ingredientsFragment.showOCRProgress() }
withContext(Main) {
ingredientsFragment.showOCRProgress()
}

val node = withContext(IO) {
try {
Expand Down Expand Up @@ -641,6 +650,7 @@ class ProductEditActivity : BaseActivity() {

const val KEY_EDIT_OFFLINE_PRODUCT = "edit_offline_product"
const val KEY_EDIT_PRODUCT = "edit_product"
const val KEY_PRODUCT = "product"

const val KEY_IS_EDITING = "is_edition"
const val KEY_STATE = "state"
Expand Down Expand Up @@ -693,5 +703,8 @@ class ProductEditActivity : BaseActivity() {
context.startActivity(this)
}
}

private fun createTextPlain(code: String) =
RequestBody.create(OpenFoodAPIClient.MIME_TEXT, code)
}
}
Expand Up @@ -24,6 +24,7 @@ import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.Toast
import androidx.core.net.toFile
import androidx.core.view.isGone
import androidx.core.widget.doAfterTextChanged
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
Expand Down Expand Up @@ -286,6 +287,7 @@ class EditIngredientsFragment : ProductEditFragment() {
private fun preFillValuesForOffline(prod: OfflineSavedProduct) {
productDetails = prod.productDetails.toMutableMap()

// Load ingredients image
getImageIngredients()?.let {
binding.imageProgress.visibility = View.VISIBLE
picasso
Expand Down Expand Up @@ -317,11 +319,16 @@ class EditIngredientsFragment : ProductEditFragment() {
* Automatically load suggestions for allergen names
*/
private fun loadAutoSuggestions(allergens: List<String>) {
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)
binding.traces.setAdapter(
ArrayAdapter(
requireActivity(),
android.R.layout.simple_dropdown_item_1line,
allergens
)
)
}


Expand Down Expand Up @@ -381,11 +388,7 @@ class EditIngredientsFragment : ProductEditFragment() {
}

private fun toggleOCRButtonVisibility() {
if (binding.ingredientsList.isEmpty()) {
binding.btnExtractIngredients.visibility = View.VISIBLE
} else {
binding.btnExtractIngredients.visibility = View.GONE
}
binding.ingredientsList.isGone = binding.ingredientsList.isNotEmpty()
}

/**
Expand All @@ -399,8 +402,7 @@ class EditIngredientsFragment : ProductEditFragment() {
?.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
targetMap[ApiFields.Keys.ADD_TRACES.substring(4)] = binding.traces.chipValues.joinToString(",")
}
}

Expand Down
Expand Up @@ -10,6 +10,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import openfoodfacts.github.scrachx.openfood.R
import openfoodfacts.github.scrachx.openfood.databinding.CalculateDetailsBinding
import openfoodfacts.github.scrachx.openfood.features.adapters.CalculatedNutrimentsGridAdapter
import openfoodfacts.github.scrachx.openfood.features.product.edit.ProductEditActivity.Companion.KEY_PRODUCT
import openfoodfacts.github.scrachx.openfood.features.shared.BaseActivity
import openfoodfacts.github.scrachx.openfood.models.*
import openfoodfacts.github.scrachx.openfood.models.MeasurementUnit
Expand Down Expand Up @@ -191,7 +192,6 @@ class CalculateDetailsActivity : BaseActivity() {
}

companion object {
private const val KEY_PRODUCT = "product"
private const val KEY_SPINNER_VALUE = "spinnerValue"
private const val KEY_WEIGHT = "weight"

Expand Down
Expand Up @@ -47,6 +47,8 @@ import openfoodfacts.github.scrachx.openfood.R
import openfoodfacts.github.scrachx.openfood.analytics.AnalyticsEvent
import openfoodfacts.github.scrachx.openfood.analytics.MatomoAnalytics
import openfoodfacts.github.scrachx.openfood.databinding.ActivityProductListsBinding
import openfoodfacts.github.scrachx.openfood.features.product.edit.ProductEditActivity
import openfoodfacts.github.scrachx.openfood.features.product.edit.ProductEditActivity.Companion.KEY_PRODUCT
import openfoodfacts.github.scrachx.openfood.features.productlist.ProductListActivity
import openfoodfacts.github.scrachx.openfood.features.productlist.ProductListActivity.Companion.KEY_LIST_ID
import openfoodfacts.github.scrachx.openfood.features.productlist.ProductListActivity.Companion.KEY_LIST_NAME
Expand Down Expand Up @@ -309,7 +311,6 @@ class ProductListsActivity : BaseActivity(), SwipeController.Actions {
}

companion object {
private const val KEY_PRODUCT = "product"

@JvmStatic
fun start(context: Context, productToAdd: Product) = context.startActivity(
Expand Down
Expand Up @@ -6,8 +6,9 @@ import android.content.IntentFilter
import android.content.pm.PackageManager
import android.os.BatteryManager
import android.util.Log
import androidx.preference.PreferenceManager
import androidx.preference.PreferenceManager.getDefaultSharedPreferences
import java.io.File
import java.io.IOException
import kotlin.math.ceil

private const val LOG_TAG = "ContextExt"
Expand All @@ -18,23 +19,23 @@ private const val LOG_TAG = "ContextExt"
* @return true if battery is low or false if battery in not low
*/
fun Context.isBatteryLevelLow(percent: Int = 15): Boolean {
val ifilter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
val batteryStatus = registerReceiver(null, ifilter) ?: throw IllegalStateException("cannot get battery level")
val filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
val batteryStatus = registerReceiver(null, filter) ?: throw IllegalStateException("cannot get battery level")

val level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
val scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1)

val batteryPct = level / scale.toFloat() * 100
val batteryPct = level.toFloat() / scale * 100
Log.i("BATTERYSTATUS", batteryPct.toString())
return ceil(batteryPct.toDouble()) <= percent
return ceil(batteryPct) <= percent
}

fun Context.isDisableImageLoad(defValue: Boolean = false) = PreferenceManager.getDefaultSharedPreferences(this)
.getBoolean("disableImageLoad", defValue)

fun Context.isLowBatteryMode() = isDisableImageLoad() && isBatteryLevelLow()

fun Context.isFastAdditionMode(defValue: Boolean = false) = PreferenceManager.getDefaultSharedPreferences(this)
fun Context.isDisableImageLoad(defValue: Boolean = false) = getDefaultSharedPreferences(this)
.getBoolean("disableImageLoad", defValue)

fun Context.isFastAdditionMode(defValue: Boolean = false) = getDefaultSharedPreferences(this)
.getBoolean("fastAdditionMode", defValue)

fun Context.dpsToPixel(dps: Int) = dps.toPx(this)
Expand All @@ -53,6 +54,7 @@ fun Context.getVersionName(): String = try {
}

fun Context.isHardwareCameraInstalled() = isHardwareCameraInstalled(this)

fun Context.clearCameraCache() {
(getCameraCacheLocation().listFiles() ?: return).forEach {
if (it.delete()) Log.i(LOG_TAG, "Deleted cached photo '${it.absolutePath}'.")
Expand All @@ -61,14 +63,19 @@ fun Context.clearCameraCache() {
}

fun Context.getCameraCacheLocation(): File {
var cacheDir = cacheDir
if (Utils.isExternalStorageWritable()) {
cacheDir = externalCacheDir
}
// Prefer external storage, photos are not sensible.
// From android docs:
// > If you need to store sensitive data only temporarily,
// > you should use the app's designated cache directory
// > within internal storage to save the data
val cacheDir = if (Utils.isExternalStorageWritable()) externalCacheDir else cacheDir

val picDir = File(cacheDir, "EasyImage")
if (!picDir.exists()) {
if (picDir.exists()) {
check(picDir.isDirectory) { "Path '$picDir' is not a directory." }
} else {
if (picDir.mkdirs()) Log.i(LOG_TAG, "Directory '${picDir.absolutePath}' created.")
else Log.i(LOG_TAG, "Couldn't create directory '${picDir.absolutePath}'.")
else throw IOException("Couldn't create directory '${picDir.absolutePath}'.")
}
return picDir
}
16 changes: 9 additions & 7 deletions app/src/main/res/layout/fragment_add_product_ingredients.xml
Expand Up @@ -48,7 +48,6 @@
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:layout_marginTop="8dp"
android:background="?android:selectableItemBackground"
app:layout_constraintStart_toStartOf="parent"
Expand Down Expand Up @@ -163,12 +162,12 @@
android:layout_height="wrap_content"
android:text="@string/extract_ingredients"
android:visibility="gone"
app:drawableLeftCompat="@drawable/ic_compare_arrows_black_18dp"
app:layout_constraintBottom_toBottomOf="@id/ingredients_list"
app:layout_constraintEnd_toEndOf="@id/ingredients_list"
app:layout_constraintStart_toStartOf="@id/ingredients_list"
app:layout_constraintTop_toBottomOf="@id/traces"
app:layout_constraintTop_toTopOf="@id/ingredients_list" />
app:layout_constraintTop_toTopOf="@id/ingredients_list"
tools:visibility="visible" />

<ImageView
android:id="@+id/ingredients_list_verified"
Expand All @@ -191,7 +190,8 @@
app:layout_constraintBottom_toBottomOf="@id/ingredients_list"
app:layout_constraintEnd_toEndOf="@id/ingredients_list"
app:layout_constraintStart_toStartOf="@id/ingredients_list"
app:layout_constraintTop_toTopOf="@id/ingredients_list" />
app:layout_constraintTop_toTopOf="@id/ingredients_list"
tools:visibility="visible" />

<TextView
android:id="@+id/ocr_progress_text"
Expand All @@ -202,7 +202,8 @@
android:visibility="gone"
app:layout_constraintEnd_toEndOf="@id/ocr_progress"
app:layout_constraintStart_toStartOf="@id/ocr_progress"
app:layout_constraintTop_toBottomOf="@id/ocr_progress" />
app:layout_constraintTop_toBottomOf="@id/ocr_progress"
tools:visibility="visible" />

<Button
android:id="@+id/btn_looks_good"
Expand Down Expand Up @@ -287,7 +288,7 @@
<com.hootsuite.nachos.NachoTextView
android:id="@+id/traces"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_height="48dp"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginTop="@dimen/spacing_small"
android:layout_marginRight="@dimen/activity_horizontal_margin"
Expand All @@ -302,7 +303,8 @@
app:chipTextColor="@color/grey_50"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/hint_traces" />
app:layout_constraintTop_toBottomOf="@id/hint_traces"
tools:ignore="SpeakableTextPresentCheck" />

<Button
android:id="@+id/btn_next"
Expand Down

0 comments on commit 2861d23

Please sign in to comment.