mirror of
https://github.com/dzeiocom/OpenHealth.git
synced 2025-06-07 15:29:55 +00:00
feat(app): Add weight goal #88
This commit is contained in:
parent
218d23f223
commit
1e0988d5b2
@ -16,4 +16,10 @@ object Settings {
|
|||||||
*/
|
*/
|
||||||
const val APP_LANGUAGE = "com.dzeio.open-health.app.language"
|
const val APP_LANGUAGE = "com.dzeio.open-health.app.language"
|
||||||
|
|
||||||
|
/***************************
|
||||||
|
* Weight related settings *
|
||||||
|
***************************/
|
||||||
|
|
||||||
|
const val WEIGHT_GOAL = "com.dzeio.open-health.weight.goal"
|
||||||
|
|
||||||
}
|
}
|
@ -1,61 +1,17 @@
|
|||||||
package com.dzeio.openhealth.core
|
package com.dzeio.openhealth.core
|
||||||
|
|
||||||
import android.app.Dialog
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.fragment.app.DialogFragment
|
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.viewbinding.ViewBinding
|
import androidx.viewbinding.ViewBinding
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
|
|
||||||
abstract class BaseDialog<VM : BaseViewModel, VB : ViewBinding>(private val viewModelClass: Class<VM>) : DialogFragment() {
|
/**
|
||||||
|
* Base dialog
|
||||||
|
*
|
||||||
|
* note: Dialog crash app with viewmodel error? add @AndroidEntryPoint
|
||||||
|
*/
|
||||||
|
abstract class BaseDialog<VM : BaseViewModel, VB : ViewBinding>(private val viewModelClass: Class<VM>) :
|
||||||
|
BaseSimpleDialog<VB>() {
|
||||||
|
|
||||||
val viewModel by lazy {
|
val viewModel by lazy {
|
||||||
ViewModelProvider(this)[viewModelClass]
|
ViewModelProvider(this)[viewModelClass]
|
||||||
}
|
}
|
||||||
|
|
||||||
private var _binding: VB? = null
|
|
||||||
val binding get() = _binding!!
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Setup everything!
|
|
||||||
*/
|
|
||||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
|
||||||
return activity?.let { act ->
|
|
||||||
val builder = MaterialAlertDialogBuilder(requireContext())
|
|
||||||
|
|
||||||
_binding = bindingInflater(act.layoutInflater)
|
|
||||||
|
|
||||||
builder.setView(binding.root)
|
|
||||||
|
|
||||||
onBuilderInit(builder)
|
|
||||||
|
|
||||||
val dialog = builder.create()
|
|
||||||
|
|
||||||
onDialogInit(dialog)
|
|
||||||
|
|
||||||
onCreated()
|
|
||||||
|
|
||||||
dialog
|
|
||||||
} ?: throw IllegalStateException("Activity cannot be null")
|
|
||||||
}
|
|
||||||
|
|
||||||
open fun onBuilderInit(builder: MaterialAlertDialogBuilder): Unit {}
|
|
||||||
|
|
||||||
open fun onDialogInit(dialog: AlertDialog): Unit {}
|
|
||||||
|
|
||||||
open fun onCreated(): Unit {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to inflate the Fragment Bindings
|
|
||||||
*/
|
|
||||||
abstract val bindingInflater: (LayoutInflater) -> VB
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy binding
|
|
||||||
*/
|
|
||||||
override fun onDestroyView() {
|
|
||||||
super.onDestroyView()
|
|
||||||
_binding = null
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package com.dzeio.openhealth.core
|
||||||
|
|
||||||
|
import android.app.Dialog
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import androidx.viewbinding.ViewBinding
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
|
||||||
|
abstract class BaseSimpleDialog<VB : ViewBinding> : DialogFragment() {
|
||||||
|
|
||||||
|
private var _binding: VB? = null
|
||||||
|
val binding get() = _binding!!
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup everything!
|
||||||
|
*/
|
||||||
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
|
return activity?.let { act ->
|
||||||
|
val builder = MaterialAlertDialogBuilder(requireContext())
|
||||||
|
|
||||||
|
_binding = bindingInflater(act.layoutInflater)
|
||||||
|
|
||||||
|
builder.setView(binding.root)
|
||||||
|
|
||||||
|
onBuilderInit(builder)
|
||||||
|
|
||||||
|
val dialog = builder.create()
|
||||||
|
|
||||||
|
onDialogInit(dialog)
|
||||||
|
|
||||||
|
onCreated()
|
||||||
|
|
||||||
|
dialog
|
||||||
|
} ?: throw IllegalStateException("Activity cannot be null")
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun onBuilderInit(builder: MaterialAlertDialogBuilder) {}
|
||||||
|
|
||||||
|
open fun onDialogInit(dialog: AlertDialog) {}
|
||||||
|
|
||||||
|
open fun onCreated() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to inflate the Fragment Bindings
|
||||||
|
*/
|
||||||
|
abstract val bindingInflater: (LayoutInflater) -> VB
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy binding
|
||||||
|
*/
|
||||||
|
override fun onDestroyView() {
|
||||||
|
super.onDestroyView()
|
||||||
|
_binding = null
|
||||||
|
}
|
||||||
|
}
|
48
app/src/main/java/com/dzeio/openhealth/core/Observable.kt
Normal file
48
app/src/main/java/com/dzeio/openhealth/core/Observable.kt
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package com.dzeio.openhealth.core
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.MutableLiveData
|
||||||
|
|
||||||
|
open class Observable<T>(baseValue: T) {
|
||||||
|
|
||||||
|
private val functionObservers: ArrayList<(T) -> Unit> = ArrayList()
|
||||||
|
|
||||||
|
|
||||||
|
fun addObserver(fn: (T) -> Unit) {
|
||||||
|
if (!functionObservers.contains(fn)) {
|
||||||
|
functionObservers.add(fn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeObserver(fn: (T) -> Unit) {
|
||||||
|
if (functionObservers.contains(fn)) {
|
||||||
|
functionObservers.remove(fn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open var value: T = baseValue
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
notifyObservers()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun notifyObservers() {
|
||||||
|
|
||||||
|
// Notify Functions
|
||||||
|
for (fn in functionObservers) {
|
||||||
|
notifyObserver(fn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun notifyObserver(observer: (T) -> Unit) {
|
||||||
|
observer.invoke(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toLiveData(): LiveData<T> {
|
||||||
|
val ld = MutableLiveData(value)
|
||||||
|
addObserver {
|
||||||
|
ld.postValue(it)
|
||||||
|
}
|
||||||
|
return ld
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ package com.dzeio.openhealth.di
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
|
import com.dzeio.openhealth.utils.Configuration
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
@ -19,4 +20,10 @@ class SystemModule {
|
|||||||
fun provideSettings(@ApplicationContext context: Context): SharedPreferences {
|
fun provideSettings(@ApplicationContext context: Context): SharedPreferences {
|
||||||
return PreferenceManager.getDefaultSharedPreferences(context)
|
return PreferenceManager.getDefaultSharedPreferences(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
fun provideConfig(sharedPreferences: SharedPreferences): Configuration {
|
||||||
|
return Configuration(sharedPreferences)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,8 +136,10 @@ object WeightChart {
|
|||||||
limit.lineWidth = 1f
|
limit.lineWidth = 1f
|
||||||
limit.textColor = Color.BLACK
|
limit.textColor = Color.BLACK
|
||||||
|
|
||||||
|
axisRight.removeAllLimitLines()
|
||||||
axisRight.addLimitLine(limit)
|
axisRight.addLimitLine(limit)
|
||||||
}
|
}
|
||||||
|
invalidate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,6 +108,15 @@ class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewMo
|
|||||||
updateWater(0)
|
updateWater(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewModel.goalWeight.observe(viewLifecycleOwner) {
|
||||||
|
lifecycleScope.launchWhenStarted {
|
||||||
|
viewModel.fetchWeights().collectLatest {
|
||||||
|
updateGraph(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateGraph(list: List<Weight>) {
|
private fun updateGraph(list: List<Weight>) {
|
||||||
@ -116,7 +125,7 @@ class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewMo
|
|||||||
requireView(),
|
requireView(),
|
||||||
list,
|
list,
|
||||||
viewModel.weightUnit,
|
viewModel.weightUnit,
|
||||||
viewModel.goalWeight?.toFloat()
|
viewModel.goalWeight.value
|
||||||
)
|
)
|
||||||
|
|
||||||
// legend.apply {
|
// legend.apply {
|
||||||
|
@ -6,22 +6,25 @@ import androidx.lifecycle.LiveData
|
|||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.dzeio.openhealth.Application.Companion.TAG
|
import com.dzeio.openhealth.Application.Companion.TAG
|
||||||
|
import com.dzeio.openhealth.Settings
|
||||||
import com.dzeio.openhealth.core.BaseViewModel
|
import com.dzeio.openhealth.core.BaseViewModel
|
||||||
import com.dzeio.openhealth.data.water.Water
|
import com.dzeio.openhealth.data.water.Water
|
||||||
import com.dzeio.openhealth.data.water.WaterRepository
|
import com.dzeio.openhealth.data.water.WaterRepository
|
||||||
import com.dzeio.openhealth.data.weight.Weight
|
import com.dzeio.openhealth.data.weight.Weight
|
||||||
import com.dzeio.openhealth.data.weight.WeightRepository
|
import com.dzeio.openhealth.data.weight.WeightRepository
|
||||||
import com.dzeio.openhealth.units.UnitFactory
|
import com.dzeio.openhealth.units.UnitFactory
|
||||||
|
import com.dzeio.openhealth.utils.Configuration
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import javax.inject.Inject
|
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class HomeViewModel @Inject internal constructor(
|
class HomeViewModel @Inject internal constructor(
|
||||||
private val weightRepository: WeightRepository,
|
private val weightRepository: WeightRepository,
|
||||||
private val waterRepository: WaterRepository,
|
private val waterRepository: WaterRepository,
|
||||||
settings: SharedPreferences
|
settings: SharedPreferences,
|
||||||
|
config: Configuration
|
||||||
) : BaseViewModel() {
|
) : BaseViewModel() {
|
||||||
|
|
||||||
private val _water = MutableLiveData<Water?>(null)
|
private val _water = MutableLiveData<Water?>(null)
|
||||||
@ -35,8 +38,7 @@ class HomeViewModel @Inject internal constructor(
|
|||||||
var weightUnit =
|
var weightUnit =
|
||||||
UnitFactory.mass(settings.getString("weight_unit", "kilogram") ?: "kilogram")
|
UnitFactory.mass(settings.getString("weight_unit", "kilogram") ?: "kilogram")
|
||||||
|
|
||||||
val goalWeight: Int? =
|
val goalWeight = config.getFloat(Settings.WEIGHT_GOAL).toLiveData()
|
||||||
(settings.getString("weight_goal", null)?.toIntOrNull())
|
|
||||||
|
|
||||||
val dailyWaterIntake: Int =
|
val dailyWaterIntake: Int =
|
||||||
((settings.getString("water_intake", "1200")?.toFloatOrNull() ?: 1200f) * waterUnit.modifier)
|
((settings.getString("water_intake", "1200")?.toFloatOrNull() ?: 1200f) * waterUnit.modifier)
|
||||||
|
@ -20,7 +20,7 @@ import java.util.Locale
|
|||||||
class SettingsFragment : PreferenceFragmentCompat() {
|
class SettingsFragment : PreferenceFragmentCompat() {
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
const val TAG = "${Application.TAG}/SttngsFrgmnt"
|
const val TAG = "${Application.TAG}/SettingsFragment"
|
||||||
}
|
}
|
||||||
|
|
||||||
val settings: SharedPreferences by lazy {
|
val settings: SharedPreferences by lazy {
|
||||||
@ -31,12 +31,12 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||||||
setPreferencesFromResource(R.xml.preferences, rootKey)
|
setPreferencesFromResource(R.xml.preferences, rootKey)
|
||||||
|
|
||||||
// Force only numbers on Goal
|
// Force only numbers on Goal
|
||||||
val weightGoal = findPreference<EditTextPreference>("weight_goal")
|
val weightGoal = findPreference<EditTextPreference>(Settings.WEIGHT_GOAL)
|
||||||
weightGoal?.apply {
|
weightGoal?.apply {
|
||||||
setOnBindEditTextListener {
|
setOnBindEditTextListener {
|
||||||
it.inputType = InputType.TYPE_CLASS_NUMBER
|
it.inputType = InputType.TYPE_CLASS_NUMBER
|
||||||
}
|
}
|
||||||
val value = settings.getString("weight_goal", null)
|
val value = settings.getString(Settings.WEIGHT_GOAL, null)
|
||||||
val modifier = UnitFactory.mass(settings.getString("weight_unit", null) ?: "kilogram")
|
val modifier = UnitFactory.mass(settings.getString("weight_unit", null) ?: "kilogram")
|
||||||
if (value != null && value.isNotEmpty()) {
|
if (value != null && value.isNotEmpty()) {
|
||||||
text = (value.toFloat() * modifier.modifier).toString()
|
text = (value.toFloat() * modifier.modifier).toString()
|
||||||
@ -45,7 +45,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||||||
val alue = ((newValue as String).toInt() / modifier.modifier).toInt().toString()
|
val alue = ((newValue as String).toInt() / modifier.modifier).toInt().toString()
|
||||||
settings.edit()
|
settings.edit()
|
||||||
.putString(
|
.putString(
|
||||||
"weight_goal",
|
Settings.WEIGHT_GOAL,
|
||||||
alue
|
alue
|
||||||
)
|
)
|
||||||
.apply()
|
.apply()
|
||||||
@ -61,7 +61,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||||||
setOnPreferenceChangeListener { _, newValue ->
|
setOnPreferenceChangeListener { _, newValue ->
|
||||||
val unit = settings.getString("weight_unit", "kilogram")
|
val unit = settings.getString("weight_unit", "kilogram")
|
||||||
?: return@setOnPreferenceChangeListener true
|
?: return@setOnPreferenceChangeListener true
|
||||||
val goal = settings.getString("weight_goal", null)
|
val goal = settings.getString(Settings.WEIGHT_GOAL, null)
|
||||||
?: return@setOnPreferenceChangeListener true
|
?: return@setOnPreferenceChangeListener true
|
||||||
val modifier = UnitFactory.mass(newValue as String)
|
val modifier = UnitFactory.mass(newValue as String)
|
||||||
val oldModifier = UnitFactory.mass(unit)
|
val oldModifier = UnitFactory.mass(unit)
|
||||||
@ -69,7 +69,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
|
|||||||
(goal.toFloat() / oldModifier.modifier * modifier.modifier).toInt().toString()
|
(goal.toFloat() / oldModifier.modifier * modifier.modifier).toInt().toString()
|
||||||
settings.edit()
|
settings.edit()
|
||||||
.putString(
|
.putString(
|
||||||
"weight_goal",
|
Settings.WEIGHT_GOAL,
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
.apply()
|
.apply()
|
||||||
|
@ -10,10 +10,10 @@ import com.dzeio.openhealth.databinding.DialogAddWeightBinding
|
|||||||
import com.dzeio.openhealth.ui.home.HomeViewModel
|
import com.dzeio.openhealth.ui.home.HomeViewModel
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class AddWeightDialog : BaseDialog<HomeViewModel, DialogAddWeightBinding>(HomeViewModel::class.java) {
|
class AddWeightDialog :
|
||||||
|
BaseDialog<HomeViewModel, DialogAddWeightBinding>(HomeViewModel::class.java) {
|
||||||
|
|
||||||
override val bindingInflater: (LayoutInflater) -> DialogAddWeightBinding = DialogAddWeightBinding::inflate
|
override val bindingInflater: (LayoutInflater) -> DialogAddWeightBinding = DialogAddWeightBinding::inflate
|
||||||
|
|
||||||
|
@ -2,7 +2,11 @@ package com.dzeio.openhealth.ui.weight
|
|||||||
|
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.*
|
import android.view.LayoutInflater
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.MenuItem
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
@ -36,10 +40,16 @@ class ListWeightFragment :
|
|||||||
// FIXME: deprecated
|
// FIXME: deprecated
|
||||||
setHasOptionsMenu(true)
|
setHasOptionsMenu(true)
|
||||||
|
|
||||||
if (viewModel.goalWeight != null) {
|
if (viewModel.goalWeight.value != null) {
|
||||||
binding.goalButton.setText(R.string.edit_goal)
|
binding.goalButton.setText(R.string.edit_goal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.goalButton.setOnClickListener {
|
||||||
|
findNavController().navigate(
|
||||||
|
ListWeightFragmentDirections.actionNavListWeightToNavWeightDialog(WeightDialog.DialogTypes.EDIT_GOAL.ordinal)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
val recycler = binding.list
|
val recycler = binding.list
|
||||||
|
|
||||||
val manager = LinearLayoutManager(requireContext())
|
val manager = LinearLayoutManager(requireContext())
|
||||||
@ -70,6 +80,14 @@ class ListWeightFragment :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewModel.goalWeight.observe(viewLifecycleOwner) {
|
||||||
|
viewLifecycleOwner.lifecycleScope.launchWhenCreated {
|
||||||
|
viewModel.fetchWeights().collectLatest {
|
||||||
|
updateGraph(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GraphUtils.lineChartSetup(
|
GraphUtils.lineChartSetup(
|
||||||
binding.chart,
|
binding.chart,
|
||||||
MaterialColors.getColor(
|
MaterialColors.getColor(
|
||||||
@ -89,7 +107,7 @@ class ListWeightFragment :
|
|||||||
requireView(),
|
requireView(),
|
||||||
list,
|
list,
|
||||||
viewModel.weightUnit,
|
viewModel.weightUnit,
|
||||||
viewModel.goalWeight?.toFloat(),
|
viewModel.goalWeight.value,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,29 @@
|
|||||||
package com.dzeio.openhealth.ui.weight
|
package com.dzeio.openhealth.ui.weight
|
||||||
|
|
||||||
import android.content.SharedPreferences
|
import com.dzeio.openhealth.Settings
|
||||||
import com.dzeio.openhealth.core.BaseViewModel
|
import com.dzeio.openhealth.core.BaseViewModel
|
||||||
import com.dzeio.openhealth.data.weight.WeightRepository
|
import com.dzeio.openhealth.data.weight.WeightRepository
|
||||||
import com.dzeio.openhealth.units.UnitFactory
|
import com.dzeio.openhealth.units.UnitFactory
|
||||||
|
import com.dzeio.openhealth.utils.Configuration
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class ListWeightViewModel @Inject internal constructor(
|
class ListWeightViewModel @Inject internal constructor(
|
||||||
private val weightRepository: WeightRepository,
|
private val weightRepository: WeightRepository,
|
||||||
settings: SharedPreferences
|
private val settings: Configuration
|
||||||
) : BaseViewModel() {
|
) : BaseViewModel() {
|
||||||
|
|
||||||
var weightUnit =
|
private val _goalWeight = settings.getFloat(Settings.WEIGHT_GOAL)
|
||||||
UnitFactory.mass(settings.getString("weight_unit", "kilogram") ?: "kilogram")
|
|
||||||
|
|
||||||
val goalWeight: Float? =
|
var weightUnit =
|
||||||
(settings.getString("weight_goal", null)?.toFloatOrNull())
|
UnitFactory.mass(settings.getString("weight_unit").value ?: "kilogram")
|
||||||
|
|
||||||
|
val goalWeight = _goalWeight.toLiveData()
|
||||||
|
|
||||||
fun fetchWeights() = weightRepository.getWeights()
|
fun fetchWeights() = weightRepository.getWeights()
|
||||||
|
|
||||||
|
fun setWeightGoal(value: Float) {
|
||||||
|
_goalWeight.value = value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
111
app/src/main/java/com/dzeio/openhealth/ui/weight/WeightDialog.kt
Normal file
111
app/src/main/java/com/dzeio/openhealth/ui/weight/WeightDialog.kt
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
package com.dzeio.openhealth.ui.weight
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import androidx.navigation.fragment.navArgs
|
||||||
|
import com.dzeio.openhealth.R
|
||||||
|
import com.dzeio.openhealth.core.BaseDialog
|
||||||
|
import com.dzeio.openhealth.databinding.DialogAddWeightBinding
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
class WeightDialog :
|
||||||
|
BaseDialog<WeightDialogViewModel, DialogAddWeightBinding>(WeightDialogViewModel::class.java) {
|
||||||
|
|
||||||
|
private val args: WeightDialogArgs by navArgs()
|
||||||
|
|
||||||
|
override val bindingInflater: (LayoutInflater) -> DialogAddWeightBinding =
|
||||||
|
DialogAddWeightBinding::inflate
|
||||||
|
|
||||||
|
override fun onBuilderInit(builder: MaterialAlertDialogBuilder) {
|
||||||
|
super.onBuilderInit(builder)
|
||||||
|
|
||||||
|
val dialogType = DialogTypes.values()[args.dialogType]
|
||||||
|
|
||||||
|
builder.apply {
|
||||||
|
setTitle(dialogType.title)
|
||||||
|
setIcon(dialogType.icon)
|
||||||
|
setPositiveButton(R.string.validate) { dialog, _ ->
|
||||||
|
runAction(0)
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
setNegativeButton(R.string.cancel) { dialog, _ ->
|
||||||
|
runAction(1)
|
||||||
|
dialog.cancel()
|
||||||
|
}
|
||||||
|
if (dialogType.thirdText != null) {
|
||||||
|
setNeutralButton(dialogType.thirdText) { dialog, _ ->
|
||||||
|
runAction(2)
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreated() {
|
||||||
|
super.onCreated()
|
||||||
|
setValue(0f)
|
||||||
|
|
||||||
|
if (args.dialogType == DialogTypes.EDIT_GOAL.ordinal) {
|
||||||
|
Log.d("TAG", viewModel.toString())
|
||||||
|
Log.d("TAG", viewModel.goalWeight.value.toString())
|
||||||
|
viewModel.goalWeight.observe(this) {
|
||||||
|
if (it != null) setValue(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// init form
|
||||||
|
binding.kg.maxValue = 999
|
||||||
|
binding.kg.minValue = 0
|
||||||
|
|
||||||
|
binding.gram.maxValue = 9
|
||||||
|
binding.gram.minValue = 0
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setValue(value: Float) {
|
||||||
|
Log.d("TAG", "Setting dialog value to $value")
|
||||||
|
val kg = value.toInt()
|
||||||
|
val g = (value - kg) * 10
|
||||||
|
|
||||||
|
binding.kg.value = kg
|
||||||
|
binding.gram.value = g.toInt()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getValue(): Float {
|
||||||
|
var finalValue: Float = binding.kg.value.toFloat()
|
||||||
|
finalValue += binding.gram.value.toFloat() / 10
|
||||||
|
return finalValue
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param click 0 = validate, 1 = cancel, 2 = third option
|
||||||
|
*/
|
||||||
|
private fun runAction(click: Int) {
|
||||||
|
when (DialogTypes.values()[args.dialogType]) {
|
||||||
|
DialogTypes.EDIT_GOAL -> {
|
||||||
|
if (click == 1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (click == 2) {
|
||||||
|
viewModel.setWeightGoal(null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
viewModel.setWeightGoal(getValue())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class DialogTypes(
|
||||||
|
val title: String,
|
||||||
|
val icon: Drawable? = null,
|
||||||
|
val thirdText: Int? = null
|
||||||
|
) {
|
||||||
|
EDIT_GOAL("Edit Goal", null, R.string.goal_remove)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.dzeio.openhealth.ui.weight
|
||||||
|
|
||||||
|
import com.dzeio.openhealth.Settings
|
||||||
|
import com.dzeio.openhealth.core.BaseViewModel
|
||||||
|
import com.dzeio.openhealth.data.weight.WeightRepository
|
||||||
|
import com.dzeio.openhealth.units.UnitFactory
|
||||||
|
import com.dzeio.openhealth.utils.Configuration
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
class WeightDialogViewModel @Inject internal constructor(
|
||||||
|
private val weightRepository: WeightRepository,
|
||||||
|
private val settings: Configuration
|
||||||
|
) : BaseViewModel() {
|
||||||
|
|
||||||
|
private val _goalWeight = settings.getFloat(Settings.WEIGHT_GOAL)
|
||||||
|
|
||||||
|
var weightUnit =
|
||||||
|
UnitFactory.mass(settings.getString("weight_unit").value ?: "kilogram")
|
||||||
|
|
||||||
|
val goalWeight = _goalWeight.toLiveData()
|
||||||
|
|
||||||
|
fun setWeightGoal(value: Float?) {
|
||||||
|
_goalWeight.value = value
|
||||||
|
}
|
||||||
|
}
|
177
app/src/main/java/com/dzeio/openhealth/utils/Configuration.kt
Normal file
177
app/src/main/java/com/dzeio/openhealth/utils/Configuration.kt
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
package com.dzeio.openhealth.utils
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.core.content.edit
|
||||||
|
import com.dzeio.openhealth.Application
|
||||||
|
import com.dzeio.openhealth.core.Observable
|
||||||
|
|
||||||
|
class Configuration(
|
||||||
|
private val prefs: SharedPreferences
|
||||||
|
) : SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
|
private val cache: HashMap<String, Field<*>> = HashMap()
|
||||||
|
|
||||||
|
private companion object {
|
||||||
|
const val TAG = "${Application.TAG}/Config"
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
prefs.registerOnSharedPreferenceChangeListener(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getString(key: String): StringField {
|
||||||
|
if (cache[key] == null) {
|
||||||
|
Log.d(TAG, "$key does not exist in cache, creating new instance")
|
||||||
|
cache[key] = StringField(key)
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "$key in cache")
|
||||||
|
}
|
||||||
|
return cache[key] as StringField
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getLong(key: String): LongField {
|
||||||
|
if (cache[key] == null) {
|
||||||
|
Log.d(TAG, "$key does not exist in cache, creating new instance")
|
||||||
|
cache[key] = LongField(key)
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "$key in cache")
|
||||||
|
}
|
||||||
|
return cache[key] as LongField
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getBoolean(key: String): BooleanField {
|
||||||
|
if (cache[key] == null) {
|
||||||
|
Log.d(TAG, "$key does not exist in cache, creating new instance")
|
||||||
|
cache[key] = BooleanField(key)
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "$key in cache")
|
||||||
|
}
|
||||||
|
return cache[key] as BooleanField
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getInt(key: String): IntField {
|
||||||
|
if (cache[key] == null) {
|
||||||
|
Log.d(TAG, "$key does not exist in cache, creating new instance")
|
||||||
|
cache[key] = IntField(key)
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "$key in cache")
|
||||||
|
}
|
||||||
|
return cache[key] as IntField
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getFloat(key: String): FloatField {
|
||||||
|
if (cache[key] == null) {
|
||||||
|
Log.d(TAG, "$key does not exist in cache, creating new instance")
|
||||||
|
cache[key] = FloatField(key)
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "$key in cache")
|
||||||
|
}
|
||||||
|
return cache[key] as FloatField
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getStringSet(key: String): StringSetField {
|
||||||
|
if (cache[key] == null) {
|
||||||
|
Log.d(TAG, "$key does not exist in cache, creating new instance")
|
||||||
|
cache[key] = StringSetField(key)
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "$key in cache")
|
||||||
|
}
|
||||||
|
return cache[key] as StringSetField
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSharedPreferenceChanged(u: SharedPreferences, key: String) {
|
||||||
|
Log.d(TAG, "configuration update for key: $key")
|
||||||
|
cache[key]?.needUpdate = true
|
||||||
|
cache[key]?.notifyObservers()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class Field<T>(
|
||||||
|
baseValue: T
|
||||||
|
) : Observable<T>(baseValue) {
|
||||||
|
abstract fun exists(): Boolean
|
||||||
|
abstract fun internalGet(): T
|
||||||
|
abstract fun internalSet(value: T)
|
||||||
|
var needUpdate = true
|
||||||
|
|
||||||
|
override var value: T = baseValue
|
||||||
|
get() {
|
||||||
|
if (needUpdate) {
|
||||||
|
field = if (!exists()) {
|
||||||
|
null as T
|
||||||
|
} else {
|
||||||
|
internalGet()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return field
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
if (field == value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
field = value
|
||||||
|
internalSet(value)
|
||||||
|
notifyObservers()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class StringField(
|
||||||
|
private val key: String,
|
||||||
|
private val defaultValue: String? = null
|
||||||
|
) : Field<String?>(defaultValue) {
|
||||||
|
override fun exists(): Boolean = prefs.contains(key)
|
||||||
|
override fun internalGet(): String? = prefs.getString(key, defaultValue)
|
||||||
|
override fun internalSet(value: String?) =
|
||||||
|
prefs.edit { if (value == null) remove(key) else putString(key, value) }
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class BooleanField(
|
||||||
|
private val key: String,
|
||||||
|
private val defaultValue: Boolean = false
|
||||||
|
) : Field<Boolean?>(defaultValue) {
|
||||||
|
override fun exists(): Boolean = prefs.contains(key)
|
||||||
|
override fun internalGet(): Boolean = prefs.getBoolean(key, defaultValue)
|
||||||
|
override fun internalSet(value: Boolean?) =
|
||||||
|
prefs.edit { if (value == null) remove(key) else putBoolean(key, value) }
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class IntField(
|
||||||
|
private val key: String,
|
||||||
|
private val defaultValue: Int = -1
|
||||||
|
) : Field<Int?>(defaultValue) {
|
||||||
|
override fun exists(): Boolean = prefs.contains(key)
|
||||||
|
override fun internalGet(): Int = prefs.getInt(key, defaultValue)
|
||||||
|
override fun internalSet(value: Int?) =
|
||||||
|
prefs.edit { if (value == null) remove(key) else putInt(key, value) }
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class FloatField(
|
||||||
|
private val key: String,
|
||||||
|
private val defaultValue: Float = -1f
|
||||||
|
) : Field<Float?>(defaultValue) {
|
||||||
|
override fun exists(): Boolean = prefs.contains(key)
|
||||||
|
override fun internalGet(): Float = prefs.getFloat(key, defaultValue)
|
||||||
|
override fun internalSet(value: Float?) =
|
||||||
|
prefs.edit { if (value == null) remove(key) else putFloat(key, value) }
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class LongField(
|
||||||
|
private val key: String,
|
||||||
|
private val defaultValue: Long = -1
|
||||||
|
) : Field<Long?>(defaultValue) {
|
||||||
|
override fun exists(): Boolean = prefs.contains(key)
|
||||||
|
override fun internalGet(): Long = prefs.getLong(key, defaultValue)
|
||||||
|
override fun internalSet(value: Long?) =
|
||||||
|
prefs.edit { if (value == null) remove(key) else putLong(key, value) }
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class StringSetField(
|
||||||
|
private val key: String,
|
||||||
|
private val defaultValue: MutableSet<String>? = null
|
||||||
|
) : Field<MutableSet<String>?>(defaultValue) {
|
||||||
|
override fun exists(): Boolean = prefs.contains(key)
|
||||||
|
override fun internalGet(): MutableSet<String>? = prefs.getStringSet(key, defaultValue)
|
||||||
|
override fun internalSet(value: MutableSet<String>?) =
|
||||||
|
prefs.edit { if (value == null) remove(key) else putStringSet(key, value) }
|
||||||
|
}
|
||||||
|
}
|
22
app/src/main/res/layout/dialog_weight.xml
Normal file
22
app/src/main/res/layout/dialog_weight.xml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<android.widget.NumberPicker
|
||||||
|
android:id="@+id/kg"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<android.widget.NumberPicker
|
||||||
|
android:id="@+id/gram"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:progress="0" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -4,6 +4,10 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/mobile_navigation"
|
android:id="@+id/mobile_navigation"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
app:enterAnim="@android:anim/slide_in_left"
|
||||||
|
app:exitAnim="@android:anim/slide_out_right"
|
||||||
|
app:popEnterAnim="@android:anim/slide_in_left"
|
||||||
|
app:popExitAnim="@android:anim/slide_out_right"
|
||||||
app:startDestination="@+id/nav_home">
|
app:startDestination="@+id/nav_home">
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
@ -13,18 +17,10 @@
|
|||||||
tools:layout="@layout/fragment_home">
|
tools:layout="@layout/fragment_home">
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_nav_home_to_nav_list_weight"
|
android:id="@+id/action_nav_home_to_nav_list_weight"
|
||||||
app:destination="@id/nav_list_weight"
|
app:destination="@id/nav_list_weight" />
|
||||||
app:enterAnim="@android:anim/slide_in_left"
|
|
||||||
app:exitAnim="@android:anim/slide_out_right"
|
|
||||||
app:popEnterAnim="@android:anim/slide_in_left"
|
|
||||||
app:popExitAnim="@android:anim/slide_out_right" />
|
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_nav_home_to_nav_water_home"
|
android:id="@+id/action_nav_home_to_nav_water_home"
|
||||||
app:destination="@id/nav_water_home"
|
app:destination="@id/nav_water_home" />
|
||||||
app:enterAnim="@android:anim/slide_in_left"
|
|
||||||
app:exitAnim="@android:anim/slide_out_right"
|
|
||||||
app:popEnterAnim="@android:anim/slide_in_left"
|
|
||||||
app:popExitAnim="@android:anim/slide_out_right" />
|
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_nav_home_to_nav_add_weight_dialog"
|
android:id="@+id/action_nav_home_to_nav_add_weight_dialog"
|
||||||
app:destination="@id/nav_add_weight_dialog" />
|
app:destination="@id/nav_add_weight_dialog" />
|
||||||
@ -47,14 +43,13 @@
|
|||||||
tools:layout="@layout/fragment_list_weight">
|
tools:layout="@layout/fragment_list_weight">
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_nav_list_weight_to_nav_edit_weight"
|
android:id="@+id/action_nav_list_weight_to_nav_edit_weight"
|
||||||
app:destination="@id/nav_edit_weight"
|
app:destination="@id/nav_edit_weight" />
|
||||||
app:enterAnim="@android:anim/slide_in_left"
|
|
||||||
app:exitAnim="@android:anim/slide_out_right"
|
|
||||||
app:popEnterAnim="@android:anim/slide_in_left"
|
|
||||||
app:popExitAnim="@android:anim/slide_out_right" />
|
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_nav_list_weight_to_nav_add_weight_dialog"
|
android:id="@+id/action_nav_list_weight_to_nav_add_weight_dialog"
|
||||||
app:destination="@id/nav_add_weight_dialog" />
|
app:destination="@id/nav_add_weight_dialog" />
|
||||||
|
<action
|
||||||
|
android:id="@+id/action_nav_list_weight_to_nav_weight_dialog"
|
||||||
|
app:destination="@id/nav_weight_dialog" />
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
@ -76,27 +71,15 @@
|
|||||||
tools:layout="@layout/fragment_main_water_home">
|
tools:layout="@layout/fragment_main_water_home">
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_nav_water_home_to_nav_water_edit"
|
android:id="@+id/action_nav_water_home_to_nav_water_edit"
|
||||||
app:destination="@id/nav_water_edit"
|
app:destination="@id/nav_water_edit" />
|
||||||
app:enterAnim="@android:anim/slide_in_left"
|
|
||||||
app:exitAnim="@android:anim/slide_out_right"
|
|
||||||
app:popEnterAnim="@android:anim/slide_in_left"
|
|
||||||
app:popExitAnim="@android:anim/slide_out_right" />
|
|
||||||
<action
|
<action
|
||||||
android:id="@+id/action_nav_water_home_to_nav_water_size_dialog"
|
android:id="@+id/action_nav_water_home_to_nav_water_size_dialog"
|
||||||
app:destination="@id/nav_water_size_dialog"
|
app:destination="@id/nav_water_size_dialog" />
|
||||||
app:enterAnim="@android:anim/slide_in_left"
|
|
||||||
app:exitAnim="@android:anim/slide_out_right"
|
|
||||||
app:popEnterAnim="@android:anim/slide_in_left"
|
|
||||||
app:popExitAnim="@android:anim/slide_out_right" />
|
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
<dialog
|
<dialog
|
||||||
android:id="@+id/nav_water_size_dialog"
|
android:id="@+id/nav_water_size_dialog"
|
||||||
android:name="com.dzeio.openhealth.ui.water.WaterSizeSelectorDialog"
|
android:name="com.dzeio.openhealth.ui.water.WaterSizeSelectorDialog"
|
||||||
app:enterAnim="@android:anim/slide_in_left"
|
|
||||||
app:exitAnim="@android:anim/slide_out_right"
|
|
||||||
app:popEnterAnim="@android:anim/slide_in_left"
|
|
||||||
app:popExitAnim="@android:anim/slide_out_right"
|
|
||||||
tools:layout="@layout/dialog_water_size_selector">
|
tools:layout="@layout/dialog_water_size_selector">
|
||||||
|
|
||||||
</dialog>
|
</dialog>
|
||||||
@ -104,10 +87,6 @@
|
|||||||
<dialog
|
<dialog
|
||||||
android:id="@+id/nav_add_weight_dialog"
|
android:id="@+id/nav_add_weight_dialog"
|
||||||
android:name="com.dzeio.openhealth.ui.weight.AddWeightDialog"
|
android:name="com.dzeio.openhealth.ui.weight.AddWeightDialog"
|
||||||
app:enterAnim="@android:anim/slide_in_left"
|
|
||||||
app:exitAnim="@android:anim/slide_out_right"
|
|
||||||
app:popEnterAnim="@android:anim/slide_in_left"
|
|
||||||
app:popExitAnim="@android:anim/slide_out_right"
|
|
||||||
tools:layout="@layout/dialog_water_size_selector">
|
tools:layout="@layout/dialog_water_size_selector">
|
||||||
|
|
||||||
</dialog>
|
</dialog>
|
||||||
@ -115,21 +94,13 @@
|
|||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/nav_settings"
|
android:id="@+id/nav_settings"
|
||||||
android:name="com.dzeio.openhealth.ui.settings.SettingsFragment"
|
android:name="com.dzeio.openhealth.ui.settings.SettingsFragment"
|
||||||
android:label="@string/page_settings"
|
android:label="@string/page_settings">
|
||||||
app:enterAnim="@android:anim/slide_in_left"
|
|
||||||
app:exitAnim="@android:anim/slide_out_right"
|
|
||||||
app:popEnterAnim="@android:anim/slide_in_left"
|
|
||||||
app:popExitAnim="@android:anim/slide_out_right">
|
|
||||||
|
|
||||||
</fragment>
|
</fragment>
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/nav_water_edit"
|
android:id="@+id/nav_water_edit"
|
||||||
android:name="com.dzeio.openhealth.ui.water.EditWaterDialog"
|
android:name="com.dzeio.openhealth.ui.water.EditWaterDialog"
|
||||||
app:enterAnim="@android:anim/slide_in_left"
|
|
||||||
app:exitAnim="@android:anim/slide_out_right"
|
|
||||||
app:popEnterAnim="@android:anim/slide_in_left"
|
|
||||||
app:popExitAnim="@android:anim/slide_out_right"
|
|
||||||
tools:layout="@layout/dialog_water_edit_water">
|
tools:layout="@layout/dialog_water_edit_water">
|
||||||
|
|
||||||
<argument
|
<argument
|
||||||
@ -141,10 +112,6 @@
|
|||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/nav_extension"
|
android:id="@+id/nav_extension"
|
||||||
android:name="com.dzeio.openhealth.ui.extension.ExtensionFragment"
|
android:name="com.dzeio.openhealth.ui.extension.ExtensionFragment"
|
||||||
app:enterAnim="@android:anim/slide_in_left"
|
|
||||||
app:exitAnim="@android:anim/slide_out_right"
|
|
||||||
app:popEnterAnim="@android:anim/slide_in_left"
|
|
||||||
app:popExitAnim="@android:anim/slide_out_right"
|
|
||||||
tools:layout="@layout/fragment_extension">
|
tools:layout="@layout/fragment_extension">
|
||||||
|
|
||||||
<argument
|
<argument
|
||||||
@ -184,4 +151,15 @@
|
|||||||
android:name="com.dzeio.openhealth.ui.steps.StepsHomeFragment"
|
android:name="com.dzeio.openhealth.ui.steps.StepsHomeFragment"
|
||||||
android:label="@string/menu_steps"
|
android:label="@string/menu_steps"
|
||||||
tools:layout="@layout/fragment_steps_home" />
|
tools:layout="@layout/fragment_steps_home" />
|
||||||
|
|
||||||
|
<dialog
|
||||||
|
android:id="@+id/nav_weight_dialog"
|
||||||
|
android:name="com.dzeio.openhealth.ui.weight.WeightDialog"
|
||||||
|
tools:layout="@layout/dialog_weight"
|
||||||
|
>
|
||||||
|
|
||||||
|
<argument
|
||||||
|
android:name="dialog_type"
|
||||||
|
app:argType="integer" />
|
||||||
|
</dialog>
|
||||||
</navigation>
|
</navigation>
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
<string name="menu_browse">Browse</string>
|
<string name="menu_browse">Browse</string>
|
||||||
<string name="menu_activity">Activity</string>
|
<string name="menu_activity">Activity</string>
|
||||||
<string name="add_goal">Ajouter un objectif</string>
|
<string name="add_goal">Ajouter un objectif</string>
|
||||||
|
<string name="goal_remove">Supprimer l\'objectif</string>
|
||||||
<string name="edit_goal">Modifier l\'objectif</string>
|
<string name="edit_goal">Modifier l\'objectif</string>
|
||||||
<string name="edit_daily_goal">Modifier le but journalier</string>
|
<string name="edit_daily_goal">Modifier le but journalier</string>
|
||||||
<string name="permission_declined">Vous avez décliné une permission, vous ne pouvez pas utiliser cette extension suaf si vous réactivez la permission manuellement</string>
|
<string name="permission_declined">Vous avez décliné une permission, vous ne pouvez pas utiliser cette extension suaf si vous réactivez la permission manuellement</string>
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
<string name="menu_activity">Activity</string>
|
<string name="menu_activity">Activity</string>
|
||||||
|
|
||||||
<string name="add_goal">Add Goal</string>
|
<string name="add_goal">Add Goal</string>
|
||||||
|
<string name="goal_remove">Remove Goal</string>
|
||||||
<string name="edit_goal">Modify Goal</string>
|
<string name="edit_goal">Modify Goal</string>
|
||||||
<string name="permission_declined">You declined a permission, you can\'t use this extension unless you enable it manually</string>
|
<string name="permission_declined">You declined a permission, you can\'t use this extension unless you enable it manually</string>
|
||||||
<string name="edit_daily_goal">Modifiy daily goal</string>
|
<string name="edit_daily_goal">Modifiy daily goal</string>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
|
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<locale android:name="en"/>
|
<locale android:name="en" />
|
||||||
<locale android:name="fr"/>
|
<locale android:name="fr" />
|
||||||
</locale-config>
|
</locale-config>
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
android:title="Height" />
|
android:title="Height" />
|
||||||
|
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
android:key="weight_goal"
|
android:key="com.dzeio.open-health.weight.goal"
|
||||||
android:selectAllOnFocus="true"
|
android:selectAllOnFocus="true"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:digits="0123456789"
|
android:digits="0123456789"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user