From 1f4ecc06ad91dc63d6cb4387c18a09fc2464177d Mon Sep 17 00:00:00 2001 From: Avior Date: Sat, 7 Jan 2023 22:36:18 +0100 Subject: [PATCH] fix: Water animation down is not working (#22) --- .../dzeio/openhealth/ui/home/HomeFragment.kt | 55 +++++++++++----- .../dzeio/openhealth/ui/home/HomeViewModel.kt | 66 ++++++++++--------- .../openhealth/ui/weight/EditWeightDialog.kt | 6 +- .../ui/weight/EditWeightDialogViewModel.kt | 60 +++++++++++++++++ 4 files changed, 136 insertions(+), 51 deletions(-) create mode 100644 app/src/main/java/com/dzeio/openhealth/ui/weight/EditWeightDialogViewModel.kt diff --git a/app/src/main/java/com/dzeio/openhealth/ui/home/HomeFragment.kt b/app/src/main/java/com/dzeio/openhealth/ui/home/HomeFragment.kt index ba4aeb2..9199d7c 100644 --- a/app/src/main/java/com/dzeio/openhealth/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/dzeio/openhealth/ui/home/HomeFragment.kt @@ -21,6 +21,7 @@ import com.dzeio.openhealth.utils.GraphUtils import com.google.android.material.color.MaterialColors import dagger.hilt.android.AndroidEntryPoint import kotlin.math.max +import kotlin.math.min @AndroidEntryPoint class HomeFragment : BaseFragment(HomeViewModel::class.java) { @@ -43,6 +44,10 @@ class HomeFragment : BaseFragment(HomeViewMo ) } + /** + * Water Intake + */ + binding.fragmentHomeWaterAdd.setOnClickListener { val water = viewModel.water.value if (water == null || !water.isToday()) { @@ -75,14 +80,17 @@ class HomeFragment : BaseFragment(HomeViewMo } } + // handle button to go to weight home binding.listWeight.setOnClickListener { findNavController().navigate(HomeFragmentDirections.actionNavHomeToNavListWeight()) } + // handle button to go to water intake home binding.gotoWaterHome.setOnClickListener { findNavController().navigate(HomeFragmentDirections.actionNavHomeToNavWaterHome()) } + // Make a line Chart using the graph library GraphUtils.lineChartSetup( binding.weightGraph, MaterialColors.getColor( @@ -95,6 +103,7 @@ class HomeFragment : BaseFragment(HomeViewMo ) ) + // Update the water intake Graph when the water intake changes viewModel.water.observe(viewLifecycleOwner) { if (it != null) { updateWater(it.value) @@ -103,29 +112,41 @@ class HomeFragment : BaseFragment(HomeViewMo } } + // Update the steps Graph when the steps count changes viewModel.steps.observe(viewLifecycleOwner) { binding.stepsCurrent.text = it.toString() } + // Update the steps Graph when the goal changes viewModel.stepsGoal.observe(viewLifecycleOwner) { + if (it == null) { + binding.stepsTotal.text = "" + return@observe + } binding.stepsTotal.text = it.toString() } + // update the graph when the weight changes viewModel.weights.observe(viewLifecycleOwner) { if (it != null) { updateGraph(it) } } + // update the graph when the goal weight change viewModel.goalWeight.observe(viewLifecycleOwner) { if (viewModel.weights.value != null) updateGraph(viewModel.weights.value!!) } + // update the graph when the weight unit change viewModel.massUnit.observe(viewLifecycleOwner) { if (viewModel.weights.value != null) updateGraph(viewModel.weights.value!!) } } + /** + * Function that update the graph for the weight + */ private fun updateGraph(list: List) { WeightChart.setup( binding.weightGraph, @@ -134,40 +155,37 @@ class HomeFragment : BaseFragment(HomeViewMo viewModel.massUnit.value!!, viewModel.goalWeight.value ) - -// legend.apply { -// isEnabled = true -// form = Legend.LegendForm.LINE -// -// if (goal != null) { -// val legendEntry = LegendEntry().apply { -// label = "Weight Goal" -// formColor = Color.RED -// } -// setCustom(arrayOf(legendEntry)) -// } -// } } + /** + * the waterintake old value to keep for value update + */ private var oldValue = 0f + /** + * function that update the water count in the home page + */ private fun updateWater(newValue: Int) { + // get the current Unit val waterUnit = Units.Volume.find(settings.getString("water_unit", "milliliter") ?: "Milliliter") + // Update the count binding.fragmentHomeWaterCurrent.text = String.format( resources.getString(waterUnit.unit), (newValue * waterUnit.modifier).toInt() ) + // TODO: move it elsewhere binding.fragmentHomeWaterTotal.text = String.format( resources.getString(waterUnit.unit), viewModel.dailyWaterIntake ) + // get the with/height of the ImageView var width = 1500 var height = 750 @@ -177,6 +195,7 @@ class HomeFragment : BaseFragment(HomeViewMo } + // Prepare the update animation val animator = ValueAnimator.ofInt( this.oldValue.toInt(), newValue @@ -186,7 +205,6 @@ class HomeFragment : BaseFragment(HomeViewMo this.oldValue = (it.animatedValue as Int).toFloat() val value = 100 * it.animatedValue as Int / viewModel.dailyWaterIntake.toFloat() -// Log.d("Test2", "${this.oldValue}") val graph = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888) val canvas = Canvas(graph) @@ -209,9 +227,10 @@ class HomeFragment : BaseFragment(HomeViewMo 3f ) + // Draw the big Arc DrawUtils.drawArc( canvas, - max(value, 1f), + min(max(value, 0.01f), 100f), rect, MaterialColors.getColor( requireView(), @@ -219,9 +238,15 @@ class HomeFragment : BaseFragment(HomeViewMo ), 6f ) + + // save the canvas canvas.save() + + // send it binding.background.setImageBitmap(graph) } + + // start the animation animator.start() } } diff --git a/app/src/main/java/com/dzeio/openhealth/ui/home/HomeViewModel.kt b/app/src/main/java/com/dzeio/openhealth/ui/home/HomeViewModel.kt index 30c1659..dcab8ca 100644 --- a/app/src/main/java/com/dzeio/openhealth/ui/home/HomeViewModel.kt +++ b/app/src/main/java/com/dzeio/openhealth/ui/home/HomeViewModel.kt @@ -1,6 +1,5 @@ package com.dzeio.openhealth.ui.home -import android.content.SharedPreferences import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope @@ -11,7 +10,6 @@ import com.dzeio.openhealth.data.water.Water import com.dzeio.openhealth.data.water.WaterRepository import com.dzeio.openhealth.data.weight.Weight import com.dzeio.openhealth.data.weight.WeightRepository -import com.dzeio.openhealth.units.UnitFactory import com.dzeio.openhealth.units.Units import com.dzeio.openhealth.utils.Configuration import dagger.hilt.android.lifecycle.HiltViewModel @@ -24,51 +22,73 @@ class HomeViewModel @Inject internal constructor( private val weightRepository: WeightRepository, private val waterRepository: WaterRepository, stepRepository: StepRepository, - settings: SharedPreferences, config: Configuration ) : BaseViewModel() { private val _steps = MutableLiveData(0) + + /** + * Steps taken today by the user + */ val steps: LiveData = _steps - private val _stepsGoal: MutableLiveData = MutableLiveData() - val stepsGoal: LiveData = _stepsGoal + /** + * Number of steps the use should do today + */ + val stepsGoal: LiveData = config.getInt(Settings.STEPS_GOAL).toLiveData() private val _water = MutableLiveData(null) + + /** + * Quantity of water the user drank today + */ val water: LiveData = _water private val _weights = MutableLiveData?>(null) + + /** + * The list of weight of the user + */ val weights: LiveData?> = _weights + /** + * The size of a cup for the quick water intake add + */ var waterCupSize = config.getInt("water_cup_size").toLiveData() - var waterUnit = - UnitFactory.volume(settings.getString("water_unit", "milliliter") ?: "Milliliter") + /** + * The unit used to display the water intake of the user + */ + var waterUnit = Units.Volume.find(config.getString("water_unit").value ?: "ml") private val _massUnit = MutableLiveData(Units.Mass.KILOGRAM) + + /** + * The Mass unit used by the user + */ val massUnit: LiveData = _massUnit + /** + * the User weight goal + */ val goalWeight = config.getFloat(Settings.WEIGHT_GOAL).toLiveData() - val dailyWaterIntake: Int = - ((settings.getString("water_intake", "1200")?.toFloatOrNull() ?: 1200f) * waterUnit.modifier) - .toInt() + val dailyWaterIntake: Float = (config.getFloat("water_intake").value ?: 1200f) * waterUnit.modifier init { + // Fetch today's water intake viewModelScope.launch { waterRepository.todayWater().collectLatest { _water.postValue(it) } } + // Fetch the user weights viewModelScope.launch { _steps.postValue(stepRepository.todaySteps()) } - this._stepsGoal.postValue( - config.getInt(Settings.STEPS_GOAL).value - ) - + // fetch the user weights viewModelScope.launch { weightRepository.getWeights().collectLatest { _weights.postValue(it) @@ -86,24 +106,6 @@ class HomeViewModel @Inject internal constructor( } } - /** - * @deprecated - */ - fun fetchWeights() = weightRepository.getWeights() - - /** - * @deprecated - */ - fun lastWeight() = weightRepository.lastWeight() - - fun fetchWeight(id: Long) = weightRepository.getWeight(id) - - suspend fun deleteWeight(weight: Weight) = weightRepository.deleteWeight(weight) - - suspend fun addWeight(weight: Weight) = weightRepository.addWeight(weight) - - fun fetchTodayWater() = waterRepository.todayWater() - fun updateWater(water: Water) { viewModelScope.launch { waterRepository.addWater(water) diff --git a/app/src/main/java/com/dzeio/openhealth/ui/weight/EditWeightDialog.kt b/app/src/main/java/com/dzeio/openhealth/ui/weight/EditWeightDialog.kt index de59f88..6967c9a 100644 --- a/app/src/main/java/com/dzeio/openhealth/ui/weight/EditWeightDialog.kt +++ b/app/src/main/java/com/dzeio/openhealth/ui/weight/EditWeightDialog.kt @@ -20,12 +20,10 @@ import com.google.android.material.datepicker.MaterialDatePicker import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.timepicker.MaterialTimePicker import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.flow.collect -import java.util.* @AndroidEntryPoint class EditWeightDialog : - BaseFullscreenDialog(HomeViewModel::class.java) { + BaseFullscreenDialog(HomeViewModel::class.java) { override val bindingInflater: (LayoutInflater) -> DialogEditWeightBinding = DialogEditWeightBinding::inflate @@ -146,4 +144,4 @@ class EditWeightDialog : } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/dzeio/openhealth/ui/weight/EditWeightDialogViewModel.kt b/app/src/main/java/com/dzeio/openhealth/ui/weight/EditWeightDialogViewModel.kt new file mode 100644 index 0000000..6e639ad --- /dev/null +++ b/app/src/main/java/com/dzeio/openhealth/ui/weight/EditWeightDialogViewModel.kt @@ -0,0 +1,60 @@ +package com.dzeio.openhealth.ui.weight + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.viewModelScope +import com.dzeio.openhealth.Settings +import com.dzeio.openhealth.core.BaseViewModel +import com.dzeio.openhealth.data.water.Water +import com.dzeio.openhealth.data.weight.Weight +import com.dzeio.openhealth.data.weight.WeightRepository +import com.dzeio.openhealth.units.Units +import com.dzeio.openhealth.utils.Configuration +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.launch +import javax.inject.Inject + +@AndroidEntryPoint +class EditWeightDialogViewModel @Inject internal constructor( + private val weightRepository: WeightRepository, + config: Configuration +) : BaseViewModel() { + + private val _water = MutableLiveData(null) + + /** + * Quantity of water the user drank today + */ + val water: LiveData = _water + + private val _weights = MutableLiveData?>(null) + + private val _massUnit = MutableLiveData(Units.Mass.KILOGRAM) + + init { + + // fetch the user weights + viewModelScope.launch { + weightRepository.getWeights().collectLatest { + _weights.postValue(it) + } + } + + config.getString(Settings.MASS_UNIT).apply { + addObserver { + if (it == null) return@addObserver + _massUnit.postValue(Units.Mass.find(it)) + } + if (value != null) { + _massUnit.postValue(Units.Mass.find(value!!)) + } + } + } + + fun fetchWeight(id: Long) = weightRepository.getWeight(id) + + suspend fun deleteWeight(weight: Weight) = weightRepository.deleteWeight(weight) + + suspend fun addWeight(weight: Weight) = weightRepository.addWeight(weight) +}