@@ -25,7 +25,6 @@ import kotlinx.coroutines.flow.asStateFlow
|
|||||||
*/
|
*/
|
||||||
class FossBillingManager : BillingManager {
|
class FossBillingManager : BillingManager {
|
||||||
override val isPlus = MutableStateFlow(true).asStateFlow()
|
override val isPlus = MutableStateFlow(true).asStateFlow()
|
||||||
override val isLoaded = MutableStateFlow(true).asStateFlow()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object BillingManagerProvider {
|
object BillingManagerProvider {
|
||||||
|
|||||||
@@ -61,18 +61,6 @@ class MainActivity : ComponentActivity() {
|
|||||||
val seed = settingsState.colorScheme.toColor()
|
val seed = settingsState.colorScheme.toColor()
|
||||||
|
|
||||||
val isPlus by settingsViewModel.isPlus.collectAsStateWithLifecycle()
|
val isPlus by settingsViewModel.isPlus.collectAsStateWithLifecycle()
|
||||||
val isPurchaseStateLoaded by settingsViewModel.isPurchaseStateLoaded.collectAsStateWithLifecycle()
|
|
||||||
val isSettingsLoaded by settingsViewModel.isSettingsLoaded.collectAsStateWithLifecycle()
|
|
||||||
|
|
||||||
LaunchedEffect(isPurchaseStateLoaded, isPlus, isSettingsLoaded) {
|
|
||||||
if (isPurchaseStateLoaded && isSettingsLoaded) {
|
|
||||||
if (!isPlus) {
|
|
||||||
settingsViewModel.resetPaywalledSettings()
|
|
||||||
} else {
|
|
||||||
settingsViewModel.reloadSettings()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TomatoTheme(
|
TomatoTheme(
|
||||||
darkTheme = darkTheme,
|
darkTheme = darkTheme,
|
||||||
|
|||||||
@@ -21,5 +21,4 @@ import kotlinx.coroutines.flow.StateFlow
|
|||||||
|
|
||||||
interface BillingManager {
|
interface BillingManager {
|
||||||
val isPlus: StateFlow<Boolean>
|
val isPlus: StateFlow<Boolean>
|
||||||
val isLoaded: StateFlow<Boolean>
|
|
||||||
}
|
}
|
||||||
@@ -101,10 +101,6 @@ fun SettingsScreenRoot(
|
|||||||
val longBreakTimeInputFieldState = viewModel.longBreakTimeTextFieldState
|
val longBreakTimeInputFieldState = viewModel.longBreakTimeTextFieldState
|
||||||
|
|
||||||
val isPlus by viewModel.isPlus.collectAsStateWithLifecycle()
|
val isPlus by viewModel.isPlus.collectAsStateWithLifecycle()
|
||||||
val alarmEnabled by viewModel.alarmEnabled.collectAsStateWithLifecycle(true)
|
|
||||||
val vibrateEnabled by viewModel.vibrateEnabled.collectAsStateWithLifecycle(true)
|
|
||||||
val dndEnabled by viewModel.dndEnabled.collectAsStateWithLifecycle(false)
|
|
||||||
val alarmSound by viewModel.alarmSound.collectAsStateWithLifecycle(viewModel.currentAlarmSound)
|
|
||||||
|
|
||||||
val settingsState by viewModel.settingsState.collectAsStateWithLifecycle()
|
val settingsState by viewModel.settingsState.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
@@ -125,10 +121,6 @@ fun SettingsScreenRoot(
|
|||||||
shortBreakTimeInputFieldState = shortBreakTimeInputFieldState,
|
shortBreakTimeInputFieldState = shortBreakTimeInputFieldState,
|
||||||
longBreakTimeInputFieldState = longBreakTimeInputFieldState,
|
longBreakTimeInputFieldState = longBreakTimeInputFieldState,
|
||||||
sessionsSliderState = sessionsSliderState,
|
sessionsSliderState = sessionsSliderState,
|
||||||
alarmEnabled = alarmEnabled,
|
|
||||||
vibrateEnabled = vibrateEnabled,
|
|
||||||
dndEnabled = dndEnabled,
|
|
||||||
alarmSound = alarmSound,
|
|
||||||
onAction = viewModel::onAction,
|
onAction = viewModel::onAction,
|
||||||
setShowPaywall = setShowPaywall,
|
setShowPaywall = setShowPaywall,
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
@@ -146,10 +138,6 @@ private fun SettingsScreen(
|
|||||||
shortBreakTimeInputFieldState: TextFieldState,
|
shortBreakTimeInputFieldState: TextFieldState,
|
||||||
longBreakTimeInputFieldState: TextFieldState,
|
longBreakTimeInputFieldState: TextFieldState,
|
||||||
sessionsSliderState: SliderState,
|
sessionsSliderState: SliderState,
|
||||||
alarmEnabled: Boolean,
|
|
||||||
vibrateEnabled: Boolean,
|
|
||||||
dndEnabled: Boolean,
|
|
||||||
alarmSound: String,
|
|
||||||
onAction: (SettingsAction) -> Unit,
|
onAction: (SettingsAction) -> Unit,
|
||||||
setShowPaywall: (Boolean) -> Unit,
|
setShowPaywall: (Boolean) -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
@@ -288,9 +276,6 @@ private fun SettingsScreen(
|
|||||||
entry<Screen.Settings.Alarm> {
|
entry<Screen.Settings.Alarm> {
|
||||||
AlarmSettings(
|
AlarmSettings(
|
||||||
settingsState = settingsState,
|
settingsState = settingsState,
|
||||||
alarmEnabled = alarmEnabled,
|
|
||||||
vibrateEnabled = vibrateEnabled,
|
|
||||||
alarmSound = alarmSound,
|
|
||||||
onAction = onAction,
|
onAction = onAction,
|
||||||
onBack = backStack::removeLastOrNull
|
onBack = backStack::removeLastOrNull
|
||||||
)
|
)
|
||||||
@@ -307,8 +292,7 @@ private fun SettingsScreen(
|
|||||||
entry<Screen.Settings.Timer> {
|
entry<Screen.Settings.Timer> {
|
||||||
TimerSettings(
|
TimerSettings(
|
||||||
isPlus = isPlus,
|
isPlus = isPlus,
|
||||||
aodEnabled = settingsState.aodEnabled,
|
settingsState = settingsState,
|
||||||
dndEnabled = dndEnabled,
|
|
||||||
focusTimeInputFieldState = focusTimeInputFieldState,
|
focusTimeInputFieldState = focusTimeInputFieldState,
|
||||||
shortBreakTimeInputFieldState = shortBreakTimeInputFieldState,
|
shortBreakTimeInputFieldState = shortBreakTimeInputFieldState,
|
||||||
longBreakTimeInputFieldState = longBreakTimeInputFieldState,
|
longBreakTimeInputFieldState = longBreakTimeInputFieldState,
|
||||||
|
|||||||
@@ -79,9 +79,6 @@ import org.nsh07.pomodoro.ui.theme.TomatoShapeDefaults.topListItemShape
|
|||||||
@Composable
|
@Composable
|
||||||
fun AlarmSettings(
|
fun AlarmSettings(
|
||||||
settingsState: SettingsState,
|
settingsState: SettingsState,
|
||||||
alarmEnabled: Boolean,
|
|
||||||
vibrateEnabled: Boolean,
|
|
||||||
alarmSound: String,
|
|
||||||
onAction: (SettingsAction) -> Unit,
|
onAction: (SettingsAction) -> Unit,
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
@@ -91,10 +88,11 @@ fun AlarmSettings(
|
|||||||
|
|
||||||
var alarmName by remember { mutableStateOf("...") }
|
var alarmName by remember { mutableStateOf("...") }
|
||||||
|
|
||||||
LaunchedEffect(alarmSound) {
|
LaunchedEffect(settingsState.alarmSound) {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
alarmName =
|
alarmName =
|
||||||
RingtoneManager.getRingtone(context, alarmSound.toUri())?.getTitle(context) ?: ""
|
RingtoneManager.getRingtone(context, settingsState.alarmSound.toUri())
|
||||||
|
?.getTitle(context) ?: ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,30 +115,30 @@ fun AlarmSettings(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("LocalContextGetResourceValueCall")
|
@SuppressLint("LocalContextGetResourceValueCall")
|
||||||
val ringtonePickerIntent = remember(alarmSound) {
|
val ringtonePickerIntent = remember(settingsState.alarmSound) {
|
||||||
Intent(RingtoneManager.ACTION_RINGTONE_PICKER).apply {
|
Intent(RingtoneManager.ACTION_RINGTONE_PICKER).apply {
|
||||||
putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_ALARM)
|
putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_ALARM)
|
||||||
putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, context.getString(R.string.alarm_sound))
|
putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, context.getString(R.string.alarm_sound))
|
||||||
putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, alarmSound.toUri())
|
putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, settingsState.alarmSound.toUri())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val switchItems = remember(
|
val switchItems = remember(
|
||||||
settingsState.blackTheme,
|
settingsState.blackTheme,
|
||||||
settingsState.aodEnabled,
|
settingsState.aodEnabled,
|
||||||
alarmEnabled,
|
settingsState.alarmEnabled,
|
||||||
vibrateEnabled
|
settingsState.vibrateEnabled
|
||||||
) {
|
) {
|
||||||
listOf(
|
listOf(
|
||||||
SettingsSwitchItem(
|
SettingsSwitchItem(
|
||||||
checked = alarmEnabled,
|
checked = settingsState.alarmEnabled,
|
||||||
icon = R.drawable.alarm_on,
|
icon = R.drawable.alarm_on,
|
||||||
label = R.string.sound,
|
label = R.string.sound,
|
||||||
description = R.string.alarm_desc,
|
description = R.string.alarm_desc,
|
||||||
onClick = { onAction(SettingsAction.SaveAlarmEnabled(it)) }
|
onClick = { onAction(SettingsAction.SaveAlarmEnabled(it)) }
|
||||||
),
|
),
|
||||||
SettingsSwitchItem(
|
SettingsSwitchItem(
|
||||||
checked = vibrateEnabled,
|
checked = settingsState.vibrateEnabled,
|
||||||
icon = R.drawable.mobile_vibrate,
|
icon = R.drawable.mobile_vibrate,
|
||||||
label = R.string.vibrate,
|
label = R.string.vibrate,
|
||||||
description = R.string.vibrate_desc,
|
description = R.string.vibrate_desc,
|
||||||
@@ -245,9 +243,7 @@ fun AlarmSettingsPreview() {
|
|||||||
val settingsState = SettingsState()
|
val settingsState = SettingsState()
|
||||||
AlarmSettings(
|
AlarmSettings(
|
||||||
settingsState = settingsState,
|
settingsState = settingsState,
|
||||||
alarmEnabled = true,
|
|
||||||
vibrateEnabled = false,
|
|
||||||
alarmSound = "",
|
|
||||||
onAction = {},
|
onAction = {},
|
||||||
onBack = {})
|
onBack = {}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import androidx.compose.foundation.lazy.itemsIndexed
|
|||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.input.TextFieldState
|
import androidx.compose.foundation.text.input.TextFieldState
|
||||||
|
import androidx.compose.foundation.text.input.rememberTextFieldState
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||||
import androidx.compose.material3.FilledTonalIconToggleButton
|
import androidx.compose.material3.FilledTonalIconToggleButton
|
||||||
@@ -57,6 +58,7 @@ import androidx.compose.material3.Switch
|
|||||||
import androidx.compose.material3.SwitchDefaults
|
import androidx.compose.material3.SwitchDefaults
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBarDefaults
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
|
import androidx.compose.material3.rememberSliderState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
@@ -78,6 +80,7 @@ import org.nsh07.pomodoro.ui.settingsScreen.SettingsSwitchItem
|
|||||||
import org.nsh07.pomodoro.ui.settingsScreen.components.MinuteInputField
|
import org.nsh07.pomodoro.ui.settingsScreen.components.MinuteInputField
|
||||||
import org.nsh07.pomodoro.ui.settingsScreen.components.PlusDivider
|
import org.nsh07.pomodoro.ui.settingsScreen.components.PlusDivider
|
||||||
import org.nsh07.pomodoro.ui.settingsScreen.viewModel.SettingsAction
|
import org.nsh07.pomodoro.ui.settingsScreen.viewModel.SettingsAction
|
||||||
|
import org.nsh07.pomodoro.ui.settingsScreen.viewModel.SettingsState
|
||||||
import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar
|
import org.nsh07.pomodoro.ui.theme.AppFonts.robotoFlexTopBar
|
||||||
import org.nsh07.pomodoro.ui.theme.CustomColors.listItemColors
|
import org.nsh07.pomodoro.ui.theme.CustomColors.listItemColors
|
||||||
import org.nsh07.pomodoro.ui.theme.CustomColors.switchColors
|
import org.nsh07.pomodoro.ui.theme.CustomColors.switchColors
|
||||||
@@ -92,14 +95,13 @@ import org.nsh07.pomodoro.ui.theme.TomatoShapeDefaults.topListItemShape
|
|||||||
@Composable
|
@Composable
|
||||||
fun TimerSettings(
|
fun TimerSettings(
|
||||||
isPlus: Boolean,
|
isPlus: Boolean,
|
||||||
aodEnabled: Boolean,
|
settingsState: SettingsState,
|
||||||
dndEnabled: Boolean,
|
|
||||||
focusTimeInputFieldState: TextFieldState,
|
focusTimeInputFieldState: TextFieldState,
|
||||||
shortBreakTimeInputFieldState: TextFieldState,
|
shortBreakTimeInputFieldState: TextFieldState,
|
||||||
longBreakTimeInputFieldState: TextFieldState,
|
longBreakTimeInputFieldState: TextFieldState,
|
||||||
sessionsSliderState: SliderState,
|
sessionsSliderState: SliderState,
|
||||||
setShowPaywall: (Boolean) -> Unit,
|
|
||||||
onAction: (SettingsAction) -> Unit,
|
onAction: (SettingsAction) -> Unit,
|
||||||
|
setShowPaywall: (Boolean) -> Unit,
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
@@ -116,7 +118,7 @@ fun TimerSettings(
|
|||||||
|
|
||||||
val switchItems = listOf(
|
val switchItems = listOf(
|
||||||
SettingsSwitchItem(
|
SettingsSwitchItem(
|
||||||
checked = dndEnabled,
|
checked = settingsState.dndEnabled,
|
||||||
icon = R.drawable.dnd,
|
icon = R.drawable.dnd,
|
||||||
label = R.string.dnd,
|
label = R.string.dnd,
|
||||||
description = R.string.dnd_desc,
|
description = R.string.dnd_desc,
|
||||||
@@ -133,7 +135,7 @@ fun TimerSettings(
|
|||||||
}
|
}
|
||||||
),
|
),
|
||||||
SettingsSwitchItem(
|
SettingsSwitchItem(
|
||||||
checked = aodEnabled,
|
checked = settingsState.aodEnabled,
|
||||||
icon = R.drawable.aod,
|
icon = R.drawable.aod,
|
||||||
label = R.string.always_on_display,
|
label = R.string.always_on_display,
|
||||||
description = R.string.always_on_display_desc,
|
description = R.string.always_on_display_desc,
|
||||||
@@ -393,18 +395,17 @@ fun TimerSettings(
|
|||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
private fun TimerSettingsPreview() {
|
private fun TimerSettingsPreview() {
|
||||||
val focusTimeInputFieldState = TextFieldState("25")
|
val focusTimeInputFieldState = rememberTextFieldState("25")
|
||||||
val shortBreakTimeInputFieldState = TextFieldState("5")
|
val shortBreakTimeInputFieldState = rememberTextFieldState("5")
|
||||||
val longBreakTimeInputFieldState = TextFieldState("15")
|
val longBreakTimeInputFieldState = rememberTextFieldState("15")
|
||||||
val sessionsSliderState = SliderState(
|
val sessionsSliderState = rememberSliderState(
|
||||||
value = 4f,
|
value = 4f,
|
||||||
valueRange = 1f..8f,
|
valueRange = 1f..8f,
|
||||||
steps = 6
|
steps = 6
|
||||||
)
|
)
|
||||||
TimerSettings(
|
TimerSettings(
|
||||||
isPlus = false,
|
isPlus = false,
|
||||||
aodEnabled = true,
|
settingsState = remember { SettingsState() },
|
||||||
dndEnabled = false,
|
|
||||||
focusTimeInputFieldState = focusTimeInputFieldState,
|
focusTimeInputFieldState = focusTimeInputFieldState,
|
||||||
shortBreakTimeInputFieldState = shortBreakTimeInputFieldState,
|
shortBreakTimeInputFieldState = shortBreakTimeInputFieldState,
|
||||||
longBreakTimeInputFieldState = longBreakTimeInputFieldState,
|
longBreakTimeInputFieldState = longBreakTimeInputFieldState,
|
||||||
|
|||||||
@@ -23,7 +23,11 @@ import androidx.compose.ui.graphics.Color
|
|||||||
@Immutable
|
@Immutable
|
||||||
data class SettingsState(
|
data class SettingsState(
|
||||||
val theme: String = "auto",
|
val theme: String = "auto",
|
||||||
|
val alarmSound: String = "",
|
||||||
val colorScheme: String = Color.White.toString(),
|
val colorScheme: String = Color.White.toString(),
|
||||||
val blackTheme: Boolean = false,
|
val blackTheme: Boolean = false,
|
||||||
val aodEnabled: Boolean = false
|
val aodEnabled: Boolean = false,
|
||||||
|
val alarmEnabled: Boolean = true,
|
||||||
|
val vibrateEnabled: Boolean = true,
|
||||||
|
val dndEnabled: Boolean = false
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
package org.nsh07.pomodoro.ui.settingsScreen.viewModel
|
package org.nsh07.pomodoro.ui.settingsScreen.viewModel
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import android.provider.Settings
|
||||||
import androidx.compose.foundation.text.input.TextFieldState
|
import androidx.compose.foundation.text.input.TextFieldState
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.SliderState
|
import androidx.compose.material3.SliderState
|
||||||
@@ -36,7 +37,6 @@ import kotlinx.coroutines.Job
|
|||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.debounce
|
import kotlinx.coroutines.flow.debounce
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.nsh07.pomodoro.TomatoApplication
|
import org.nsh07.pomodoro.TomatoApplication
|
||||||
@@ -54,10 +54,6 @@ class SettingsViewModel(
|
|||||||
val backStack = mutableStateListOf<Screen.Settings>(Screen.Settings.Main)
|
val backStack = mutableStateListOf<Screen.Settings>(Screen.Settings.Main)
|
||||||
|
|
||||||
val isPlus = billingManager.isPlus
|
val isPlus = billingManager.isPlus
|
||||||
val isPurchaseStateLoaded = billingManager.isLoaded
|
|
||||||
|
|
||||||
private val _isSettingsLoaded = MutableStateFlow(false)
|
|
||||||
val isSettingsLoaded = _isSettingsLoaded.asStateFlow()
|
|
||||||
|
|
||||||
private val _settingsState = MutableStateFlow(SettingsState())
|
private val _settingsState = MutableStateFlow(SettingsState())
|
||||||
val settingsState = _settingsState.asStateFlow()
|
val settingsState = _settingsState.asStateFlow()
|
||||||
@@ -81,25 +77,13 @@ class SettingsViewModel(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val currentAlarmSound = timerRepository.alarmSoundUri.toString()
|
|
||||||
|
|
||||||
private var focusFlowCollectionJob: Job? = null
|
private var focusFlowCollectionJob: Job? = null
|
||||||
private var shortBreakFlowCollectionJob: Job? = null
|
private var shortBreakFlowCollectionJob: Job? = null
|
||||||
private var longBreakFlowCollectionJob: Job? = null
|
private var longBreakFlowCollectionJob: Job? = null
|
||||||
|
|
||||||
val alarmSound =
|
|
||||||
preferenceRepository.getStringPreferenceFlow("alarm_sound").distinctUntilChanged()
|
|
||||||
val alarmEnabled =
|
|
||||||
preferenceRepository.getBooleanPreferenceFlow("alarm_enabled").distinctUntilChanged()
|
|
||||||
val vibrateEnabled =
|
|
||||||
preferenceRepository.getBooleanPreferenceFlow("vibrate_enabled").distinctUntilChanged()
|
|
||||||
val dndEnabled =
|
|
||||||
preferenceRepository.getBooleanPreferenceFlow("dnd_enabled").distinctUntilChanged()
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
reloadSettings()
|
reloadSettings()
|
||||||
_isSettingsLoaded.value = true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,6 +160,9 @@ class SettingsViewModel(
|
|||||||
private fun saveAlarmEnabled(enabled: Boolean) {
|
private fun saveAlarmEnabled(enabled: Boolean) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
timerRepository.alarmEnabled = enabled
|
timerRepository.alarmEnabled = enabled
|
||||||
|
_settingsState.update { currentState ->
|
||||||
|
currentState.copy(alarmEnabled = enabled)
|
||||||
|
}
|
||||||
preferenceRepository.saveBooleanPreference("alarm_enabled", enabled)
|
preferenceRepository.saveBooleanPreference("alarm_enabled", enabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,6 +170,9 @@ class SettingsViewModel(
|
|||||||
private fun saveVibrateEnabled(enabled: Boolean) {
|
private fun saveVibrateEnabled(enabled: Boolean) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
timerRepository.vibrateEnabled = enabled
|
timerRepository.vibrateEnabled = enabled
|
||||||
|
_settingsState.update { currentState ->
|
||||||
|
currentState.copy(vibrateEnabled = enabled)
|
||||||
|
}
|
||||||
preferenceRepository.saveBooleanPreference("vibrate_enabled", enabled)
|
preferenceRepository.saveBooleanPreference("vibrate_enabled", enabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,6 +180,9 @@ class SettingsViewModel(
|
|||||||
private fun saveDndEnabled(enabled: Boolean) {
|
private fun saveDndEnabled(enabled: Boolean) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
timerRepository.dndEnabled = enabled
|
timerRepository.dndEnabled = enabled
|
||||||
|
_settingsState.update { currentState ->
|
||||||
|
currentState.copy(dndEnabled = enabled)
|
||||||
|
}
|
||||||
preferenceRepository.saveBooleanPreference("dnd_enabled", enabled)
|
preferenceRepository.saveBooleanPreference("dnd_enabled", enabled)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,6 +190,9 @@ class SettingsViewModel(
|
|||||||
private fun saveAlarmSound(uri: Uri?) {
|
private fun saveAlarmSound(uri: Uri?) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
timerRepository.alarmSoundUri = uri
|
timerRepository.alarmSoundUri = uri
|
||||||
|
_settingsState.update { currentState ->
|
||||||
|
currentState.copy(alarmSound = uri.toString())
|
||||||
|
}
|
||||||
preferenceRepository.saveStringPreference("alarm_sound", uri.toString())
|
preferenceRepository.saveStringPreference("alarm_sound", uri.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,16 +233,6 @@ class SettingsViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resetPaywalledSettings() {
|
|
||||||
_settingsState.update { currentState ->
|
|
||||||
currentState.copy(
|
|
||||||
aodEnabled = false,
|
|
||||||
blackTheme = false,
|
|
||||||
colorScheme = Color.White.toString()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun reloadSettings() {
|
suspend fun reloadSettings() {
|
||||||
val theme = preferenceRepository.getStringPreference("theme")
|
val theme = preferenceRepository.getStringPreference("theme")
|
||||||
?: preferenceRepository.saveStringPreference("theme", "auto")
|
?: preferenceRepository.saveStringPreference("theme", "auto")
|
||||||
@@ -256,13 +242,29 @@ class SettingsViewModel(
|
|||||||
?: preferenceRepository.saveBooleanPreference("black_theme", false)
|
?: preferenceRepository.saveBooleanPreference("black_theme", false)
|
||||||
val aodEnabled = preferenceRepository.getBooleanPreference("aod_enabled")
|
val aodEnabled = preferenceRepository.getBooleanPreference("aod_enabled")
|
||||||
?: preferenceRepository.saveBooleanPreference("aod_enabled", false)
|
?: preferenceRepository.saveBooleanPreference("aod_enabled", false)
|
||||||
|
val alarmSound = preferenceRepository.getStringPreference("alarm_sound")
|
||||||
|
?: preferenceRepository.saveStringPreference(
|
||||||
|
"alarm_sound",
|
||||||
|
(Settings.System.DEFAULT_ALARM_ALERT_URI
|
||||||
|
?: Settings.System.DEFAULT_RINGTONE_URI).toString()
|
||||||
|
)
|
||||||
|
val alarmEnabled = preferenceRepository.getBooleanPreference("alarm_enabled")
|
||||||
|
?: preferenceRepository.saveBooleanPreference("alarm_enabled", true)
|
||||||
|
val vibrateEnabled = preferenceRepository.getBooleanPreference("vibrate_enabled")
|
||||||
|
?: preferenceRepository.saveBooleanPreference("vibrate_enabled", true)
|
||||||
|
val dndEnabled = preferenceRepository.getBooleanPreference("dnd_enabled")
|
||||||
|
?: preferenceRepository.saveBooleanPreference("dnd_enabled", false)
|
||||||
|
|
||||||
_settingsState.update { currentState ->
|
_settingsState.update { currentState ->
|
||||||
currentState.copy(
|
currentState.copy(
|
||||||
theme = theme,
|
theme = theme,
|
||||||
colorScheme = colorScheme,
|
colorScheme = colorScheme,
|
||||||
|
alarmSound = alarmSound,
|
||||||
blackTheme = blackTheme,
|
blackTheme = blackTheme,
|
||||||
aodEnabled = aodEnabled
|
aodEnabled = aodEnabled,
|
||||||
|
alarmEnabled = alarmEnabled,
|
||||||
|
vibrateEnabled = vibrateEnabled,
|
||||||
|
dndEnabled = dndEnabled
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,9 +33,6 @@ class PlayBillingManager : BillingManager {
|
|||||||
private val _isPlus = MutableStateFlow(false)
|
private val _isPlus = MutableStateFlow(false)
|
||||||
override val isPlus = _isPlus.asStateFlow()
|
override val isPlus = _isPlus.asStateFlow()
|
||||||
|
|
||||||
private val _isLoaded = MutableStateFlow(false)
|
|
||||||
override val isLoaded = _isLoaded.asStateFlow()
|
|
||||||
|
|
||||||
private val purchases by lazy { Purchases.sharedInstance }
|
private val purchases by lazy { Purchases.sharedInstance }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -48,11 +45,9 @@ class PlayBillingManager : BillingManager {
|
|||||||
purchases.getCustomerInfoWith(
|
purchases.getCustomerInfoWith(
|
||||||
onSuccess = { customerInfo ->
|
onSuccess = { customerInfo ->
|
||||||
_isPlus.value = customerInfo.entitlements[ENTITLEMENT_ID]?.isActive == true
|
_isPlus.value = customerInfo.entitlements[ENTITLEMENT_ID]?.isActive == true
|
||||||
_isLoaded.value = true
|
|
||||||
},
|
},
|
||||||
onError = { error ->
|
onError = { error ->
|
||||||
Log.e("GooglePlayPaywallManager", "Error fetching customer info: $error")
|
Log.e("GooglePlayPaywallManager", "Error fetching customer info: $error")
|
||||||
_isLoaded.value = true
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user