update add ing profile menu
This commit is contained in:
parent
bc63ed83bb
commit
3db5b052a7
@ -14,7 +14,7 @@ import com.example.stepdrink.ui.navigation.NavGraph
|
||||
import com.example.stepdrink.ui.theme.StepDrinkTheme
|
||||
import com.example.stepdrink.viewmodel.StepViewModel
|
||||
import com.example.stepdrink.viewmodel.WaterViewModel
|
||||
|
||||
import com.example.stepdrink.viewmodel.ProfileViewModel
|
||||
class MainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@ -28,11 +28,13 @@ class MainActivity : ComponentActivity() {
|
||||
val navController = rememberNavController()
|
||||
val stepViewModel: StepViewModel = viewModel()
|
||||
val waterViewModel: WaterViewModel = viewModel()
|
||||
val profileViewModel: ProfileViewModel = viewModel()
|
||||
|
||||
NavGraph(
|
||||
navController = navController,
|
||||
stepViewModel = stepViewModel,
|
||||
waterViewModel = waterViewModel
|
||||
waterViewModel = waterViewModel,
|
||||
profileViewModel = profileViewModel
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
package com.example.stepdrink.data.local
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.datastore.preferences.core.intPreferencesKey
|
||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import androidx.datastore.preferences.preferencesDataStore
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
|
||||
|
||||
class PreferencesManager(private val context: Context) {
|
||||
|
||||
companion object {
|
||||
val USER_NAME = stringPreferencesKey("user_name")
|
||||
val STEP_GOAL = intPreferencesKey("step_goal")
|
||||
val WATER_GOAL = intPreferencesKey("water_goal")
|
||||
}
|
||||
|
||||
val userName: Flow<String> = context.dataStore.data.map { preferences ->
|
||||
preferences[USER_NAME] ?: "Pengguna"
|
||||
}
|
||||
|
||||
val stepGoal: Flow<Int> = context.dataStore.data.map { preferences ->
|
||||
preferences[STEP_GOAL] ?: 10000
|
||||
}
|
||||
|
||||
val waterGoal: Flow<Int> = context.dataStore.data.map { preferences ->
|
||||
preferences[WATER_GOAL] ?: 2000
|
||||
}
|
||||
|
||||
suspend fun saveUserName(name: String) {
|
||||
context.dataStore.edit { preferences ->
|
||||
preferences[USER_NAME] = name
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun saveStepGoal(goal: Int) {
|
||||
context.dataStore.edit { preferences ->
|
||||
preferences[STEP_GOAL] = goal
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun saveWaterGoal(goal: Int) {
|
||||
context.dataStore.edit { preferences ->
|
||||
preferences[WATER_GOAL] = goal
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,14 +7,17 @@ import androidx.navigation.compose.composable
|
||||
import com.example.stepdrink.ui.screen.home.HomeScreen
|
||||
import com.example.stepdrink.ui.screen.steps.StepsScreen
|
||||
import com.example.stepdrink.ui.screen.water.WaterScreen
|
||||
import com.example.stepdrink.ui.screen.profile.ProfileScreen
|
||||
import com.example.stepdrink.viewmodel.StepViewModel
|
||||
import com.example.stepdrink.viewmodel.WaterViewModel
|
||||
import com.example.stepdrink.viewmodel.ProfileViewModel
|
||||
|
||||
@Composable
|
||||
fun NavGraph(
|
||||
navController: NavHostController,
|
||||
stepViewModel: StepViewModel,
|
||||
waterViewModel: WaterViewModel
|
||||
waterViewModel: WaterViewModel,
|
||||
profileViewModel: ProfileViewModel
|
||||
) {
|
||||
NavHost(
|
||||
navController = navController,
|
||||
@ -24,7 +27,8 @@ fun NavGraph(
|
||||
HomeScreen(
|
||||
navController = navController,
|
||||
stepViewModel = stepViewModel,
|
||||
waterViewModel = waterViewModel
|
||||
waterViewModel = waterViewModel,
|
||||
profileViewModel = profileViewModel
|
||||
)
|
||||
}
|
||||
|
||||
@ -41,5 +45,11 @@ fun NavGraph(
|
||||
viewModel = waterViewModel
|
||||
)
|
||||
}
|
||||
composable(Screen.Profile.route) {
|
||||
ProfileScreen(
|
||||
navController = navController,
|
||||
viewModel = profileViewModel )
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -4,4 +4,5 @@ sealed class Screen(val route: String) {
|
||||
object Home : Screen("home")
|
||||
object Steps : Screen("steps")
|
||||
object Water : Screen("water")
|
||||
object Profile : Screen("profile")
|
||||
}
|
||||
@ -3,6 +3,7 @@ package com.example.stepdrink.ui.screen.home
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.DirectionsWalk
|
||||
import androidx.compose.material.icons.filled.Person
|
||||
import androidx.compose.material.icons.filled.WaterDrop
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
@ -14,18 +15,22 @@ import com.example.stepdrink.ui.components.StatCard
|
||||
import com.example.stepdrink.ui.navigation.Screen
|
||||
import com.example.stepdrink.viewmodel.StepViewModel
|
||||
import com.example.stepdrink.viewmodel.WaterViewModel
|
||||
import com.example.stepdrink.viewmodel.ProfileViewModel
|
||||
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun HomeScreen(
|
||||
navController: NavController,
|
||||
stepViewModel: StepViewModel,
|
||||
waterViewModel: WaterViewModel
|
||||
waterViewModel: WaterViewModel,
|
||||
profileViewModel: ProfileViewModel
|
||||
) {
|
||||
val todaySteps by stepViewModel.todaySteps.collectAsState()
|
||||
val stepGoal by stepViewModel.dailyGoal.collectAsState()
|
||||
val todayWater by waterViewModel.todayTotalWater.collectAsState()
|
||||
val waterGoal by waterViewModel.dailyGoal.collectAsState()
|
||||
val userName by profileViewModel.userName.collectAsState()
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
@ -36,6 +41,11 @@ fun HomeScreen(
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
},
|
||||
actions = {
|
||||
IconButton(onClick = { navController.navigate(Screen.Profile.route) }) {
|
||||
Icon(Icons.Default.Person, "Profil")
|
||||
}
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = MaterialTheme.colorScheme.primaryContainer,
|
||||
titleContentColor = MaterialTheme.colorScheme.onPrimaryContainer
|
||||
@ -50,6 +60,11 @@ fun HomeScreen(
|
||||
.padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "Halo, $userName! 👋",
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
Text(
|
||||
text = "Aktivitas Hari Ini",
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
|
||||
317
app/src/main/java/ui/screen/profilescreen/ProfileScreen.kt
Normal file
317
app/src/main/java/ui/screen/profilescreen/ProfileScreen.kt
Normal file
@ -0,0 +1,317 @@
|
||||
package com.example.stepdrink.ui.screen.profile
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.*
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavController
|
||||
import com.example.stepdrink.viewmodel.ProfileViewModel
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun ProfileScreen(
|
||||
navController: NavController,
|
||||
viewModel: ProfileViewModel
|
||||
) {
|
||||
val userName by viewModel.userName.collectAsState()
|
||||
val stepGoal by viewModel.stepGoal.collectAsState()
|
||||
val waterGoal by viewModel.waterGoal.collectAsState()
|
||||
|
||||
var showNameDialog by remember { mutableStateOf(false) }
|
||||
var showStepGoalDialog by remember { mutableStateOf(false) }
|
||||
var showWaterGoalDialog by remember { mutableStateOf(false) }
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text("Profil") },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = { navController.popBackStack() }) {
|
||||
Icon(Icons.Default.ArrowBack, "Kembali")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
) { paddingValues ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues)
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
// Profile Header
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(120.dp)
|
||||
.clip(CircleShape)
|
||||
.background(MaterialTheme.colorScheme.primaryContainer),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Person,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(60.dp),
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
|
||||
Text(
|
||||
text = userName,
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
// Settings Section
|
||||
Text(
|
||||
text = "Pengaturan",
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.Bold,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
// Name Setting
|
||||
SettingItem(
|
||||
icon = Icons.Default.Person,
|
||||
title = "Nama",
|
||||
value = userName,
|
||||
onClick = { showNameDialog = true }
|
||||
)
|
||||
|
||||
// Step Goal Setting
|
||||
SettingItem(
|
||||
icon = Icons.Default.DirectionsWalk,
|
||||
title = "Target Langkah Harian",
|
||||
value = "$stepGoal langkah",
|
||||
onClick = { showStepGoalDialog = true }
|
||||
)
|
||||
|
||||
// Water Goal Setting
|
||||
SettingItem(
|
||||
icon = Icons.Default.WaterDrop,
|
||||
title = "Target Air Minum Harian",
|
||||
value = "${waterGoal}ml",
|
||||
onClick = { showWaterGoalDialog = true }
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
// Info Card
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = MaterialTheme.colorScheme.secondaryContainer
|
||||
)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(16.dp)
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Info,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.secondary
|
||||
)
|
||||
Text(
|
||||
text = "Tentang Aplikasi",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
Text(
|
||||
text = "Step & Drink v1.0\nAplikasi untuk tracking langkah harian dan kebutuhan air minum.",
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dialogs
|
||||
if (showNameDialog) {
|
||||
EditTextDialog(
|
||||
title = "Edit Nama",
|
||||
label = "Nama",
|
||||
currentValue = userName,
|
||||
onDismiss = { showNameDialog = false },
|
||||
onConfirm = { newName ->
|
||||
viewModel.updateUserName(newName)
|
||||
showNameDialog = false
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (showStepGoalDialog) {
|
||||
EditNumberDialog(
|
||||
title = "Edit Target Langkah",
|
||||
label = "Target (langkah)",
|
||||
currentValue = stepGoal,
|
||||
onDismiss = { showStepGoalDialog = false },
|
||||
onConfirm = { newGoal ->
|
||||
viewModel.updateStepGoal(newGoal)
|
||||
showStepGoalDialog = false
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
if (showWaterGoalDialog) {
|
||||
EditNumberDialog(
|
||||
title = "Edit Target Air Minum",
|
||||
label = "Target (ml)",
|
||||
currentValue = waterGoal,
|
||||
onDismiss = { showWaterGoalDialog = false },
|
||||
onConfirm = { newGoal ->
|
||||
viewModel.updateWaterGoal(newGoal)
|
||||
showWaterGoalDialog = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SettingItem(
|
||||
icon: androidx.compose.ui.graphics.vector.ImageVector,
|
||||
title: String,
|
||||
value: String,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
Card(
|
||||
onClick = onClick,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
Column {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
Text(
|
||||
text = value,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
Icon(
|
||||
imageVector = Icons.Default.Edit,
|
||||
contentDescription = "Edit",
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EditTextDialog(
|
||||
title: String,
|
||||
label: String,
|
||||
currentValue: String,
|
||||
onDismiss: () -> Unit,
|
||||
onConfirm: (String) -> Unit
|
||||
) {
|
||||
var text by remember { mutableStateOf(currentValue) }
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text(title) },
|
||||
text = {
|
||||
OutlinedTextField(
|
||||
value = text,
|
||||
onValueChange = { text = it },
|
||||
label = { Text(label) },
|
||||
singleLine = true
|
||||
)
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
if (text.isNotBlank()) {
|
||||
onConfirm(text)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text("Simpan")
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = onDismiss) {
|
||||
Text("Batal")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun EditNumberDialog(
|
||||
title: String,
|
||||
label: String,
|
||||
currentValue: Int,
|
||||
onDismiss: () -> Unit,
|
||||
onConfirm: (Int) -> Unit
|
||||
) {
|
||||
var number by remember { mutableStateOf(currentValue.toString()) }
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
title = { Text(title) },
|
||||
text = {
|
||||
OutlinedTextField(
|
||||
value = number,
|
||||
onValueChange = { number = it.filter { char -> char.isDigit() } },
|
||||
label = { Text(label) },
|
||||
singleLine = true
|
||||
)
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(
|
||||
onClick = {
|
||||
val value = number.toIntOrNull()
|
||||
if (value != null && value > 0) {
|
||||
onConfirm(value)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text("Simpan")
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = onDismiss) {
|
||||
Text("Batal")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
42
app/src/main/java/viewmodel/ProfileViewModel.kt
Normal file
42
app/src/main/java/viewmodel/ProfileViewModel.kt
Normal file
@ -0,0 +1,42 @@
|
||||
package com.example.stepdrink.viewmodel
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.example.stepdrink.data.local.PreferencesManager
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class ProfileViewModel(application: Application) : AndroidViewModel(application) {
|
||||
|
||||
private val preferencesManager = PreferencesManager(application)
|
||||
|
||||
val userName: StateFlow<String> = preferencesManager.userName
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), "Pengguna")
|
||||
|
||||
val stepGoal: StateFlow<Int> = preferencesManager.stepGoal
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), 10000)
|
||||
|
||||
val waterGoal: StateFlow<Int> = preferencesManager.waterGoal
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), 2000)
|
||||
|
||||
fun updateUserName(name: String) {
|
||||
viewModelScope.launch {
|
||||
preferencesManager.saveUserName(name)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateStepGoal(goal: Int) {
|
||||
viewModelScope.launch {
|
||||
preferencesManager.saveStepGoal(goal)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateWaterGoal(goal: Int) {
|
||||
viewModelScope.launch {
|
||||
preferencesManager.saveWaterGoal(goal)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,6 +7,7 @@ import com.example.stepdrink.data.local.database.AppDatabase
|
||||
import com.example.stepdrink.data.local.entity.StepRecord
|
||||
import com.example.stepdrink.data.repository.StepRepository
|
||||
import com.example.stepdrink.sensor.StepCounterManager
|
||||
import com.example.stepdrink.data.local.PreferencesManager
|
||||
import com.example.stepdrink.util.DateUtils
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
@ -18,8 +19,10 @@ class StepViewModel(application: Application) : AndroidViewModel(application) {
|
||||
)
|
||||
val stepCounterManager: StepCounterManager = StepCounterManager(application)
|
||||
|
||||
private val _dailyGoal = MutableStateFlow(10000)
|
||||
val dailyGoal: StateFlow<Int> = _dailyGoal.asStateFlow()
|
||||
private val preferencesManager = PreferencesManager(application)
|
||||
|
||||
val dailyGoal: StateFlow<Int> = preferencesManager.stepGoal
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), 10000)
|
||||
|
||||
val todaySteps: StateFlow<StepRecord?> = repository.getStepsByDate(DateUtils.getCurrentDate())
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), null)
|
||||
@ -44,15 +47,6 @@ class StepViewModel(application: Application) : AndroidViewModel(application) {
|
||||
}
|
||||
}
|
||||
|
||||
fun setDailyGoal(goal: Int) {
|
||||
_dailyGoal.value = goal
|
||||
}
|
||||
|
||||
fun getProgressPercentage(): Float {
|
||||
val today = todaySteps.value?.steps ?: 0
|
||||
return (today.toFloat() / _dailyGoal.value.toFloat()).coerceIn(0f, 1f)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
stepCounterManager.stopTracking()
|
||||
|
||||
@ -4,6 +4,7 @@ import android.app.Application
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.example.stepdrink.data.local.database.AppDatabase
|
||||
import com.example.stepdrink.data.local.PreferencesManager
|
||||
import com.example.stepdrink.data.local.entity.WaterRecord
|
||||
import com.example.stepdrink.data.repository.WaterRepository
|
||||
import com.example.stepdrink.util.DateUtils
|
||||
@ -16,8 +17,10 @@ class WaterViewModel(application: Application) : AndroidViewModel(application) {
|
||||
AppDatabase.getDatabase(application).waterDao()
|
||||
)
|
||||
|
||||
private val _dailyGoal = MutableStateFlow(2000) // 2000ml = 2 liter
|
||||
val dailyGoal: StateFlow<Int> = _dailyGoal.asStateFlow()
|
||||
private val preferencesManager = PreferencesManager(application)
|
||||
|
||||
val dailyGoal: StateFlow<Int> = preferencesManager.waterGoal
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), 2000)
|
||||
|
||||
val todayWaterRecords: StateFlow<List<WaterRecord>> =
|
||||
repository.getWaterRecordsByDate(DateUtils.getCurrentDate())
|
||||
@ -43,12 +46,4 @@ class WaterViewModel(application: Application) : AndroidViewModel(application) {
|
||||
repository.deleteWaterRecord(record)
|
||||
}
|
||||
}
|
||||
|
||||
fun setDailyGoal(goal: Int) {
|
||||
_dailyGoal.value = goal
|
||||
}
|
||||
|
||||
fun getProgressPercentage(): Float {
|
||||
return (todayTotalWater.value.toFloat() / _dailyGoal.value.toFloat()).coerceIn(0f, 1f)
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user