fix: Fix some major bugs with the URI to string (and vice versa) conversion

This commit is contained in:
Nishant Mishra
2025-09-16 00:39:15 +05:30
parent 37c74dc844
commit 55de7589ee
4 changed files with 42 additions and 27 deletions

View File

@@ -11,6 +11,7 @@ import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy.Companion.REPLACE
import androidx.room.Query
import kotlinx.coroutines.flow.Flow
@Dao
interface PreferenceDao {
@@ -38,6 +39,12 @@ interface PreferenceDao {
@Query("SELECT value FROM boolean_preference WHERE `key` = :key")
suspend fun getBooleanPreference(key: String): Boolean?
@Query("SELECT value FROM boolean_preference WHERE `key` = :key")
fun getBooleanPreferenceFlow(key: String): Flow<Boolean>
@Query("SELECT value FROM string_preference WHERE `key` = :key")
suspend fun getStringPreference(key: String): String?
@Query("SELECT value FROM string_preference WHERE `key` = :key")
fun getStringPreferenceFlow(key: String): Flow<String>
}

View File

@@ -9,6 +9,7 @@ package org.nsh07.pomodoro.data
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.withContext
/**
@@ -42,11 +43,21 @@ interface PreferenceRepository {
*/
suspend fun getBooleanPreference(key: String): Boolean?
/**
* Retrieves a boolean preference key-value pair as a flow from the database.
*/
fun getBooleanPreferenceFlow(key: String): Flow<Boolean>
/**
* Retrieves a string preference key-value pair from the database.
*/
suspend fun getStringPreference(key: String): String?
/**
* Retrieves a string preference key-value pair as a flow from the database.
*/
fun getStringPreferenceFlow(key: String): Flow<String>
/**
* Erases all integer preference key-value pairs in the database. Do note that the default values
* will need to be rewritten manually
@@ -87,10 +98,16 @@ class AppPreferenceRepository(
preferenceDao.getBooleanPreference(key)
}
override fun getBooleanPreferenceFlow(key: String): Flow<Boolean> =
preferenceDao.getBooleanPreferenceFlow(key)
override suspend fun getStringPreference(key: String): String? = withContext(ioDispatcher) {
preferenceDao.getStringPreference(key)
}
override fun getStringPreferenceFlow(key: String): Flow<String> =
preferenceDao.getStringPreferenceFlow(key)
override suspend fun resetSettings() = withContext(ioDispatcher) {
preferenceDao.resetIntPreferences()
preferenceDao.resetBooleanPreferences()

View File

@@ -71,6 +71,7 @@ import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.net.toUri
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import org.nsh07.pomodoro.R
@@ -101,9 +102,9 @@ fun SettingsScreenRoot(
viewModel.longBreakTimeTextFieldState
}
val alarmEnabled by viewModel.alarmEnabled.collectAsStateWithLifecycle()
val vibrateEnabled by viewModel.vibrateEnabled.collectAsStateWithLifecycle()
val alarmSound by viewModel.alarmSound.collectAsStateWithLifecycle()
val alarmEnabled by viewModel.alarmEnabled.collectAsStateWithLifecycle(true)
val vibrateEnabled by viewModel.vibrateEnabled.collectAsStateWithLifecycle(true)
val alarmSound by viewModel.alarmSound.collectAsStateWithLifecycle("")
val sessionsSliderState = rememberSaveable(
saver = SliderState.Saver(
@@ -144,7 +145,7 @@ private fun SettingsScreen(
sessionsSliderState: SliderState,
alarmEnabled: Boolean,
vibrateEnabled: Boolean,
alarmSound: Uri?,
alarmSound: String,
onAlarmEnabledChange: (Boolean) -> Unit,
onVibrateEnabledChange: (Boolean) -> Unit,
onAlarmSoundChanged: (Uri?) -> Unit,
@@ -155,7 +156,7 @@ private fun SettingsScreen(
checkedIconColor = colorScheme.primary,
)
var selectedSoundUri by remember { mutableStateOf(alarmSound) }
var selectedSoundUri by remember(alarmSound) { mutableStateOf(alarmSound.toUri()) }
var selectedSoundName by remember { mutableStateOf("...") }
val context = LocalContext.current
@@ -173,7 +174,6 @@ private fun SettingsScreen(
@Suppress("DEPRECATION")
result.data?.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI)
}
selectedSoundUri = uri
onAlarmSoundChanged(uri)
}
}
@@ -436,7 +436,7 @@ fun SettingsScreenPreview() {
sessionsSliderState = rememberSliderState(value = 3f, steps = 3, valueRange = 1f..5f),
alarmEnabled = true,
vibrateEnabled = true,
alarmSound = Settings.System.DEFAULT_ALARM_ALERT_URI,
alarmSound = Settings.System.DEFAULT_ALARM_ALERT_URI.toString(),
onAlarmEnabledChange = {},
onVibrateEnabledChange = {},
onAlarmSoundChanged = {},

View File

@@ -20,10 +20,8 @@ import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.launch
import org.nsh07.pomodoro.TomatoApplication
import org.nsh07.pomodoro.data.AppPreferenceRepository
@@ -48,16 +46,12 @@ class SettingsViewModel(
onValueChangeFinished = ::updateSessionLength
)
private val _alarmSound = MutableStateFlow(timerRepository.alarmSoundUri)
val alarmSound: StateFlow<Uri?> = _alarmSound.asStateFlow()
private val _alarmEnabled: MutableStateFlow<Boolean> =
MutableStateFlow(timerRepository.alarmEnabled)
val alarmEnabled: StateFlow<Boolean> = _alarmEnabled.asStateFlow()
private val _vibrateEnabled: MutableStateFlow<Boolean> =
MutableStateFlow(timerRepository.alarmEnabled)
val vibrateEnabled: StateFlow<Boolean> = _vibrateEnabled.asStateFlow()
val alarmSound =
preferenceRepository.getStringPreferenceFlow("alarm_sound").distinctUntilChanged()
val alarmEnabled =
preferenceRepository.getBooleanPreferenceFlow("alarm_enabled").distinctUntilChanged()
val vibrateEnabled =
preferenceRepository.getBooleanPreferenceFlow("vibrate_enabled").distinctUntilChanged()
init {
viewModelScope.launch(Dispatchers.IO) {
@@ -109,17 +103,15 @@ class SettingsViewModel(
fun saveAlarmEnabled(enabled: Boolean) {
viewModelScope.launch {
timerRepository.alarmEnabled = preferenceRepository
.saveBooleanPreference("alarm_enabled", enabled)
_alarmEnabled.value = enabled
preferenceRepository.saveBooleanPreference("alarm_enabled", enabled)
timerRepository.alarmEnabled = enabled
}
}
fun saveVibrateEnabled(enabled: Boolean) {
viewModelScope.launch {
timerRepository.vibrateEnabled = preferenceRepository
.saveBooleanPreference("vibrate_enabled", enabled)
_vibrateEnabled.value = enabled
preferenceRepository.saveBooleanPreference("vibrate_enabled", enabled)
timerRepository.vibrateEnabled = enabled
}
}
@@ -127,7 +119,6 @@ class SettingsViewModel(
viewModelScope.launch {
preferenceRepository.saveStringPreference("alarm_sound", uri.toString())
timerRepository.alarmSoundUri = uri
_alarmSound.value = uri
}
}