Implement a system to load timer prefs on viewmodel instantiation

And also add a function to manually reload timer preferences on timer reset
This commit is contained in:
Nishant Mishra
2025-07-04 09:08:52 +05:30
parent 32e3a05df8
commit 8f3ee5359e
5 changed files with 38 additions and 13 deletions

View File

@@ -4,18 +4,23 @@ import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import org.nsh07.pomodoro.ui.AppScreen import org.nsh07.pomodoro.ui.AppScreen
import org.nsh07.pomodoro.ui.NavItem import org.nsh07.pomodoro.ui.NavItem
import org.nsh07.pomodoro.ui.Screen import org.nsh07.pomodoro.ui.Screen
import org.nsh07.pomodoro.ui.theme.TomatoTheme import org.nsh07.pomodoro.ui.theme.TomatoTheme
import org.nsh07.pomodoro.ui.viewModel.UiViewModel
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
private val viewModel: UiViewModel by viewModels(factoryProducer = { UiViewModel.Factory })
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
setContent { setContent {
TomatoTheme { TomatoTheme {
AppScreen() AppScreen(viewModel = viewModel)
} }
} }
} }

View File

@@ -4,7 +4,6 @@ import androidx.room.Dao
import androidx.room.Insert import androidx.room.Insert
import androidx.room.OnConflictStrategy import androidx.room.OnConflictStrategy
import androidx.room.Query import androidx.room.Query
import kotlinx.coroutines.flow.Flow
@Dao @Dao
interface PreferenceDao { interface PreferenceDao {
@@ -15,5 +14,5 @@ interface PreferenceDao {
suspend fun resetIntPreferences() suspend fun resetIntPreferences()
@Query("SELECT value FROM int_preference WHERE `key` = :key") @Query("SELECT value FROM int_preference WHERE `key` = :key")
fun getIntPreference(key: String): Flow<Int?> suspend fun getIntPreference(key: String): Int?
} }

View File

@@ -2,13 +2,12 @@ package org.nsh07.pomodoro.data
import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
interface PreferencesRepository { interface PreferencesRepository {
suspend fun saveIntPreference(key: String, value: Int) suspend fun saveIntPreference(key: String, value: Int): Int
fun getIntPreference(key: String): Flow<Int?> suspend fun getIntPreference(key: String): Int?
suspend fun resetSettings() suspend fun resetSettings()
} }
@@ -16,14 +15,16 @@ interface PreferencesRepository {
class AppPreferenceRepository( class AppPreferenceRepository(
private val preferenceDao: PreferenceDao, private val preferenceDao: PreferenceDao,
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
): PreferencesRepository { ) : PreferencesRepository {
override suspend fun saveIntPreference(key: String, value: Int) = override suspend fun saveIntPreference(key: String, value: Int): Int =
withContext(ioDispatcher) { withContext(ioDispatcher) {
preferenceDao.insertIntPreference(IntPreference(key, value)) preferenceDao.insertIntPreference(IntPreference(key, value))
value
} }
override fun getIntPreference(key: String): Flow<Int?> = override suspend fun getIntPreference(key: String): Int? = withContext(ioDispatcher) {
preferenceDao.getIntPreference(key) preferenceDao.getIntPreference(key)
}
override suspend fun resetSettings() = withContext(ioDispatcher) { override suspend fun resetSettings() = withContext(ioDispatcher) {
preferenceDao.resetIntPreferences() preferenceDao.resetIntPreferences()

View File

@@ -95,7 +95,7 @@ fun AppScreen(
uiState = uiState, uiState = uiState,
showBrandTitle = showBrandTitle, showBrandTitle = showBrandTitle,
progress = { progress }, progress = { progress },
resetTimer = viewModel::resetTimer, resetTimer = viewModel::updateTimerConstants,
skipTimer = viewModel::skipTimer, skipTimer = viewModel::skipTimer,
toggleTimer = viewModel::toggleTimer, toggleTimer = viewModel::toggleTimer,
modifier = modifier.padding( modifier = modifier.padding(

View File

@@ -7,6 +7,7 @@ import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.AP
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.initializer import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory import androidx.lifecycle.viewmodel.viewModelFactory
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@@ -22,9 +23,13 @@ import kotlin.math.ceil
class UiViewModel( class UiViewModel(
private val preferenceRepository: AppPreferenceRepository private val preferenceRepository: AppPreferenceRepository
) : ViewModel() { ) : ViewModel() {
val focusTime = 25 * 60 * 1000 var focusTime = 25 * 60 * 1000
val shortBreakTime = 5 * 60 * 1000 var shortBreakTime = 5 * 60 * 1000
val longBreakTime = 15 * 60 * 1000 var longBreakTime = 15 * 60 * 1000
init {
updateTimerConstants()
}
private val _uiState = MutableStateFlow( private val _uiState = MutableStateFlow(
UiState( UiState(
@@ -119,8 +124,10 @@ class UiViewModel(
when (uiState.value.timerMode) { when (uiState.value.timerMode) {
TimerMode.FOCUS -> TimerMode.FOCUS ->
focusTime - (SystemClock.elapsedRealtime() - startTime - pauseDuration).toInt() focusTime - (SystemClock.elapsedRealtime() - startTime - pauseDuration).toInt()
TimerMode.SHORT_BREAK -> TimerMode.SHORT_BREAK ->
shortBreakTime - (SystemClock.elapsedRealtime() - startTime - pauseDuration).toInt() shortBreakTime - (SystemClock.elapsedRealtime() - startTime - pauseDuration).toInt()
else -> else ->
longBreakTime - (SystemClock.elapsedRealtime() - startTime - pauseDuration).toInt() longBreakTime - (SystemClock.elapsedRealtime() - startTime - pauseDuration).toInt()
} }
@@ -177,6 +184,19 @@ class UiViewModel(
} }
} }
fun updateTimerConstants() {
viewModelScope.launch(Dispatchers.IO) {
focusTime = preferenceRepository.getIntPreference("focus_time")
?: preferenceRepository.saveIntPreference("focus_time", focusTime)
shortBreakTime = preferenceRepository.getIntPreference("short_break_time")
?: preferenceRepository.saveIntPreference("short_break_time", shortBreakTime)
longBreakTime = preferenceRepository.getIntPreference("long_break_time")
?: preferenceRepository.saveIntPreference("long_break_time", longBreakTime)
resetTimer()
}
}
private fun millisecondsToStr(t: Int): String { private fun millisecondsToStr(t: Int): String {
val min = (ceil(t / 1000.0).toInt() / 60) val min = (ceil(t / 1000.0).toInt() / 60)
val sec = (ceil(t / 1000.0).toInt() % 60) val sec = (ceil(t / 1000.0).toInt() % 60)