diff --git a/app/src/main/java/com/sadellie/unitto/MainActivity.kt b/app/src/main/java/com/sadellie/unitto/MainActivity.kt index ba6bce39..874858bb 100644 --- a/app/src/main/java/com/sadellie/unitto/MainActivity.kt +++ b/app/src/main/java/com/sadellie/unitto/MainActivity.kt @@ -26,6 +26,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.SideEffect import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost @@ -41,8 +42,8 @@ import com.sadellie.unitto.data.NavRoutes.SETTINGS_GRAPH import com.sadellie.unitto.data.NavRoutes.SETTINGS_SCREEN import com.sadellie.unitto.data.NavRoutes.THEMES_SCREEN import com.sadellie.unitto.data.NavRoutes.UNIT_GROUPS_SCREEN -import com.sadellie.unitto.screens.main.MainViewModel import com.sadellie.unitto.screens.main.MainScreen +import com.sadellie.unitto.screens.main.MainViewModel import com.sadellie.unitto.screens.second.LeftSideScreen import com.sadellie.unitto.screens.second.RightSideScreen import com.sadellie.unitto.screens.second.SecondViewModel @@ -67,15 +68,15 @@ class MainActivity : ComponentActivity() { setContent { val settingsViewModel: SettingsViewModel = hiltViewModel() - val userPrefs = settingsViewModel.userPrefs + val userPrefs = settingsViewModel.userPrefs.collectAsStateWithLifecycle() val themmoController = rememberThemmoController( lightColorScheme = LightThemeColors, darkColorScheme = DarkThemeColors, // Anything below will not called if theming mode is still loading from DataStore - themingMode = userPrefs.themingMode ?: return@setContent, - dynamicThemeEnabled = userPrefs.enableDynamicTheme, - amoledThemeEnabled = userPrefs.enableAmoledTheme + themingMode = userPrefs.value.themingMode ?: return@setContent, + dynamicThemeEnabled = userPrefs.value.enableDynamicTheme, + amoledThemeEnabled = userPrefs.value.enableAmoledTheme ) val navController = rememberNavController() val sysUiController = rememberSystemUiController() diff --git a/app/src/main/java/com/sadellie/unitto/screens/Utils.kt b/app/src/main/java/com/sadellie/unitto/screens/Utils.kt index 6038f7b0..07fc2cbd 100644 --- a/app/src/main/java/com/sadellie/unitto/screens/Utils.kt +++ b/app/src/main/java/com/sadellie/unitto/screens/Utils.kt @@ -28,6 +28,8 @@ import com.sadellie.unitto.data.KEY_DOT import com.sadellie.unitto.data.KEY_E import com.sadellie.unitto.data.preferences.Separator import com.sadellie.unitto.data.units.AbstractUnit +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine import java.math.BigDecimal import java.math.RoundingMode import java.text.NumberFormat @@ -222,3 +224,27 @@ fun Sequence.sortByLev(stringA: String): Sequence { .map { it.first } .asSequence() } + +@Suppress("UNCHECKED_CAST") +fun combine( + flow: Flow, + flow2: Flow, + flow3: Flow, + flow4: Flow, + flow5: Flow, + flow6: Flow, + flow7: Flow, + flow8: Flow, + transform: suspend (T1, T2, T3, T4, T5, T6, T7, T8) -> R +): Flow = combine(flow, flow2, flow3, flow4, flow5, flow6, flow7, flow8) { args: Array<*> -> + transform( + args[0] as T1, + args[1] as T2, + args[2] as T3, + args[3] as T4, + args[4] as T5, + args[5] as T6, + args[6] as T7, + args[7] as T8 + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/sadellie/unitto/screens/main/MainViewModel.kt b/app/src/main/java/com/sadellie/unitto/screens/main/MainViewModel.kt index 665733a4..38f6b5f0 100644 --- a/app/src/main/java/com/sadellie/unitto/screens/main/MainViewModel.kt +++ b/app/src/main/java/com/sadellie/unitto/screens/main/MainViewModel.kt @@ -19,7 +19,6 @@ package com.sadellie.unitto.screens.main import android.app.Application -import android.util.Log import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue @@ -40,12 +39,13 @@ import com.sadellie.unitto.data.units.database.MyBasedUnit import com.sadellie.unitto.data.units.database.MyBasedUnitsRepository import com.sadellie.unitto.data.units.remote.CurrencyApi import com.sadellie.unitto.data.units.remote.CurrencyUnitResponse +import com.sadellie.unitto.screens.combine import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import java.math.BigDecimal import java.math.RoundingMode @@ -58,12 +58,39 @@ class MainViewModel @Inject constructor( private val application: Application, private val allUnitsRepository: AllUnitsRepository ) : ViewModel() { - private var userPrefs = UserPreferences() - /** - * UI state - */ - private val _mainUIState = MutableStateFlow(MainScreenUIState()) + private val _inputValue: MutableStateFlow = MutableStateFlow(KEY_0) + private val _deleteButtonEnabled: MutableStateFlow = MutableStateFlow(false) + private val _dotButtonEnabled: MutableStateFlow = MutableStateFlow(true) + private val _negateButtonEnabled: MutableStateFlow = MutableStateFlow(false) + private val _isLoadingDatabase: MutableStateFlow = MutableStateFlow(true) + private val _isLoadingNetwork: MutableStateFlow = MutableStateFlow(false) + private val _showError: MutableStateFlow = MutableStateFlow(false) + private val _userPrefs = userPrefsRepository.userPreferencesFlow + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), UserPreferences()) + + val mainFlow = combine( + _inputValue, + _deleteButtonEnabled, + _dotButtonEnabled, + _negateButtonEnabled, + _isLoadingDatabase, + _isLoadingNetwork, + _showError, + _userPrefs + ) { inputValue, deleteButtonEnabled, dotButtonEnabled, negateButtonEnabled, isLoadingDatabase, isLoadingNetwork, showError, _ -> + return@combine MainScreenUIState( + inputValue = inputValue, + resultValue = convertValue(), + deleteButtonEnabled = deleteButtonEnabled, + dotButtonEnabled = dotButtonEnabled, + negateButtonEnabled = negateButtonEnabled, + isLoadingDatabase = isLoadingDatabase, + isLoadingNetwork = isLoadingNetwork, + showError = showError + ) + } + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), MainScreenUIState()) /** * Unit we converting from (left side) @@ -77,27 +104,16 @@ class MainViewModel @Inject constructor( var unitTo: AbstractUnit by mutableStateOf(allUnitsRepository.getById(MyUnitIDS.mile)) private set - val mainFlow = combine(_mainUIState, userPrefsRepository.userPreferencesFlow) { UIState, prefs -> - userPrefs = prefs - convertValue() - return@combine UIState - } - .stateIn( - scope = viewModelScope, - started = SharingStarted.WhileSubscribed(5000), - initialValue = MainScreenUIState() - ) - /** * This function takes local variables, converts values and then causes the UI to update */ - private fun convertValue() { + private fun convertValue(): String { // Converting value using a specified precision val convertedValue: BigDecimal = unitFrom.convert( unitTo, - _mainUIState.value.inputValue.toBigDecimal(), - userPrefs.digitsPrecision + _inputValue.value.toBigDecimal(), + _userPrefs.value.digitsPrecision ) /** @@ -107,20 +123,20 @@ class MainViewModel @Inject constructor( */ val resultValue = if (convertedValue == BigDecimal.ZERO.setScale( - userPrefs.digitsPrecision, + _userPrefs.value.digitsPrecision, RoundingMode.HALF_EVEN ) ) { KEY_0 } else { // Setting result value using a specified OutputFormat - when (userPrefs.outputFormat) { + when (_userPrefs.value.outputFormat) { OutputFormat.ALLOW_ENGINEERING -> convertedValue.toString() OutputFormat.FORCE_ENGINEERING -> convertedValue.toEngineeringString() else -> convertedValue.toPlainString() } } - _mainUIState.value = _mainUIState.value.copy(resultValue = resultValue) + return resultValue } /** @@ -133,16 +149,10 @@ class MainViewModel @Inject constructor( unitFrom = clickedUnit // Now we check for negate button - _mainUIState.value = - _mainUIState.value.copy(negateButtonEnabled = clickedUnit.group.canNegate) + _negateButtonEnabled.update { clickedUnit.group.canNegate } // Now we change to positive if the group we switched to supports negate if (!clickedUnit.group.canNegate) { - _mainUIState.value = - _mainUIState.value.copy( - inputValue = _mainUIState.value.inputValue.removePrefix( - KEY_MINUS - ) - ) + _inputValue.update { _inputValue.value.removePrefix(KEY_MINUS) } } // Now setting up right unit (pair for the left one) @@ -157,8 +167,6 @@ class MainViewModel @Inject constructor( incrementCounter(clickedUnit) // Currencies require us to get data from the internet updateCurrenciesBasicUnits() - // We can't call outside of this block. It will set precision to 0 in that case - convertValue() // Saving latest pair saveLatestPairOfUnits() } @@ -190,9 +198,6 @@ class MainViewModel @Inject constructor( // Saving latest pair saveLatestPairOfUnits() } - - // Changed units, now we can convert - convertValue() } private suspend fun incrementCounter(unit: AbstractUnit) { @@ -213,12 +218,13 @@ class MainViewModel @Inject constructor( */ private suspend fun updateCurrenciesBasicUnits() { // Resetting error and network loading states in case we are not gonna do anything below - _mainUIState.value = _mainUIState.value.copy(isLoadingNetwork = false, showError = false) + _isLoadingNetwork.update { false } + _showError.update { false } // We update currencies only when needed if (unitFrom.group != UnitGroup.CURRENCY) return // Starting to load stuff - _mainUIState.value = _mainUIState.value.copy(isLoadingNetwork = true) + _isLoadingNetwork.update { true } try { val pairs: CurrencyUnitResponse = @@ -233,10 +239,10 @@ class MainViewModel @Inject constructor( FirebaseHelper().recordException(e) } } - _mainUIState.value = _mainUIState.value.copy(showError = true) + _showError.update { true } } finally { // Loaded - _mainUIState.value = _mainUIState.value.copy(isLoadingNetwork = false) + _isLoadingNetwork.update { false } } } @@ -251,8 +257,6 @@ class MainViewModel @Inject constructor( updateCurrenciesBasicUnits() saveLatestPairOfUnits() } - // Swapped, can convert now - convertValue() } /** @@ -266,17 +270,14 @@ class MainViewModel @Inject constructor( // Here we add a dot to input // Disabling dot button to avoid multiple dots in input value // Enabling delete button to so that we can delete this dot from input - _mainUIState.value = _mainUIState.value.copy( - inputValue = _mainUIState.value.inputValue + digitToAdd, - dotButtonEnabled = false, - deleteButtonEnabled = true - ) + _inputValue.update { _inputValue.value + digitToAdd } + _dotButtonEnabled.update { false } + _deleteButtonEnabled.update { true } } KEY_0 -> { // We shouldn't add zero to another zero in input, i.e. 00 - if (_mainUIState.value.inputValue != KEY_0) { - _mainUIState.value = - _mainUIState.value.copy(inputValue = _mainUIState.value.inputValue + digitToAdd) + if (_inputValue.value != KEY_0) { + _inputValue.update { _inputValue.value + digitToAdd } } } else -> { @@ -285,13 +286,12 @@ class MainViewModel @Inject constructor( When there is just a zero, we should replace it with the digit we want to add, avoids input to be like 03 (with this check it will be just 3) */ - _mainUIState.value = _mainUIState.value.copy( - inputValue = if (_mainUIState.value.inputValue == KEY_0) digitToAdd else _mainUIState.value.inputValue + digitToAdd, - deleteButtonEnabled = true - ) + _inputValue.update { + if (_inputValue.value == KEY_0) digitToAdd else _inputValue.value + digitToAdd + } + _deleteButtonEnabled.update { true } } } - convertValue() } /** @@ -300,13 +300,12 @@ class MainViewModel @Inject constructor( fun deleteDigit() { // Last symbol is a dot // We enable DOT button - if (_mainUIState.value.inputValue.endsWith(KEY_DOT)) { - _mainUIState.value = _mainUIState.value.copy(dotButtonEnabled = true) + if (_inputValue.value.endsWith(KEY_DOT)) { + _dotButtonEnabled.update { true } } // Deleting last symbol - _mainUIState.value = - _mainUIState.value.copy(inputValue = _mainUIState.value.inputValue.dropLast(1)) + var inputToSet = _inputValue.value.dropLast(1) /* Now we check what we have left @@ -316,42 +315,37 @@ class MainViewModel @Inject constructor( Skipping this block means that we are left we acceptable value, i.e. 123.03 */ if ( - _mainUIState.value.inputValue in listOf(String(), KEY_MINUS, KEY_0) + inputToSet in listOf(String(), KEY_MINUS, KEY_0) ) { - _mainUIState.value = - _mainUIState.value.copy(deleteButtonEnabled = false, inputValue = KEY_0) + _deleteButtonEnabled.update { false } + inputToSet = KEY_0 } - // We are sure that input has acceptable value, so we convert it - convertValue() + _inputValue.update { inputToSet } } /** * Clears input value and sets it to default (ZERO) */ fun clearInput() { - _mainUIState.value = _mainUIState.value.copy( - inputValue = KEY_0, - deleteButtonEnabled = false, - dotButtonEnabled = true - ) - convertValue() + _inputValue.update { KEY_0 } + _deleteButtonEnabled.update { false } + _dotButtonEnabled.update { true } } /** * Changes input from positive to negative and vice versa */ fun negateInput() { - _mainUIState.value = _mainUIState.value.copy( - inputValue = if (_mainUIState.value.inputValue.getOrNull(0) != KEY_MINUS.single()) { + _inputValue.update { + if (_inputValue.value.getOrNull(0) != KEY_MINUS.single()) { // If input doesn't have minus at the beginning, we give it to it - KEY_MINUS + _mainUIState.value.inputValue + KEY_MINUS + _inputValue.value } else { // Input has minus, meaning we need to remove it - _mainUIState.value.inputValue.removePrefix(KEY_MINUS) + _inputValue.value.removePrefix(KEY_MINUS) } - ) - convertValue() + } } /** @@ -363,34 +357,29 @@ class MainViewModel @Inject constructor( init { viewModelScope.launch { - userPrefs = userPrefsRepository.userPreferencesFlow.first() + val initialUserPrefs = userPrefsRepository.userPreferencesFlow.first() // First we load latest pair of units unitFrom = try { - allUnitsRepository.getById(userPrefs.latestLeftSideUnit) + allUnitsRepository.getById(initialUserPrefs.latestLeftSideUnit) } catch (e: java.util.NoSuchElementException) { - Log.w("MainViewModel", "No unit with the given unitId") allUnitsRepository.getById(MyUnitIDS.kilometer) } unitTo = try { - allUnitsRepository.getById(userPrefs.latestRightSideUnit) + allUnitsRepository.getById(initialUserPrefs.latestRightSideUnit) } catch (e: java.util.NoSuchElementException) { - Log.w("MainViewModel", "No unit with the given unitId") allUnitsRepository.getById(MyUnitIDS.mile) } - _mainUIState.value = - _mainUIState.value.copy(negateButtonEnabled = unitFrom.group.canNegate) - // Now we load units data from database val allBasedUnits = basedUnitRepository.getAll() allUnitsRepository.loadFromDatabase(application, allBasedUnits) // User is free to convert values and units on units screen can be sorted properly - _mainUIState.value = _mainUIState.value.copy(isLoadingDatabase = false) + _negateButtonEnabled.update { unitFrom.group.canNegate } + _isLoadingDatabase.update { false } updateCurrenciesBasicUnits() - convertValue() } } } diff --git a/app/src/main/java/com/sadellie/unitto/screens/second/SecondViewModel.kt b/app/src/main/java/com/sadellie/unitto/screens/second/SecondViewModel.kt index 9ed808a6..b3189718 100644 --- a/app/src/main/java/com/sadellie/unitto/screens/second/SecondViewModel.kt +++ b/app/src/main/java/com/sadellie/unitto/screens/second/SecondViewModel.kt @@ -32,6 +32,7 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import javax.inject.Inject @@ -43,25 +44,35 @@ class SecondViewModel @Inject constructor( unitGroupsRepository: UnitGroupsRepository ) : ViewModel() { - private val _uiStateFlow = MutableStateFlow(SecondScreenUIState()) + private val _favoritesOnly = MutableStateFlow(false) + private val _unitsToShow = MutableStateFlow(emptyMap>()) + private val _searchQuery = MutableStateFlow("") + private val _chosenUnitGroup: MutableStateFlow = MutableStateFlow(null) + private val _shownUnitGroups = unitGroupsRepository.shownUnitGroups - val mainFlow = combine(_uiStateFlow, unitGroupsRepository.shownUnitGroups) { uiState, shown -> - val newState = uiState.copy(shownUnitGroups = shown) - _uiStateFlow.value = newState - return@combine newState - } - .stateIn( - scope = viewModelScope, - started = SharingStarted.WhileSubscribed(5000), - initialValue = SecondScreenUIState() + val mainFlow = combine( + _favoritesOnly, + _unitsToShow, + _searchQuery, + _chosenUnitGroup, + _shownUnitGroups + ) { favoritesOnly, unitsToShow, searchQuery, chosenUnitGroup, shownUnitGroups -> + return@combine SecondScreenUIState( + favoritesOnly = favoritesOnly, + unitsToShow = unitsToShow, + searchQuery = searchQuery, + chosenUnitGroup = chosenUnitGroup, + shownUnitGroups = shownUnitGroups ) + } + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), SecondScreenUIState()) fun toggleFavoritesOnly() { - _uiStateFlow.value = _uiStateFlow.value.copy(favoritesOnly = !_uiStateFlow.value.favoritesOnly) + _favoritesOnly.update { !_favoritesOnly.value } } fun onSearchQueryChange(newValue: String) { - _uiStateFlow.value = _uiStateFlow.value.copy(searchQuery = newValue) + _searchQuery.update { newValue } } /** @@ -70,7 +81,7 @@ class SecondViewModel @Inject constructor( * @param unitGroup Chip to change to. */ fun setSelectedChip(unitGroup: UnitGroup) { - _uiStateFlow.value = _uiStateFlow.value.copy(chosenUnitGroup = unitGroup) + _chosenUnitGroup.update { unitGroup } } /** @@ -82,8 +93,8 @@ class SecondViewModel @Inject constructor( * @param unitGroup [UnitGroup], currently selected chip. */ fun toggleSelectedChip(unitGroup: UnitGroup) { - val newUnitGroup = if (_uiStateFlow.value.chosenUnitGroup == unitGroup) null else unitGroup - _uiStateFlow.value = _uiStateFlow.value.copy(chosenUnitGroup = newUnitGroup) + val newUnitGroup = if (_chosenUnitGroup.value == unitGroup) null else unitGroup + _chosenUnitGroup.update { newUnitGroup } } /** @@ -101,13 +112,13 @@ class SecondViewModel @Inject constructor( withContext(Dispatchers.Default) { val unitsToShow = allUnitsRepository.filterUnits( hideBrokenCurrencies = hideBrokenCurrencies, - chosenUnitGroup = _uiStateFlow.value.chosenUnitGroup, - favoritesOnly = _uiStateFlow.value.favoritesOnly, - searchQuery = _uiStateFlow.value.searchQuery, - allUnitsGroups = _uiStateFlow.value.shownUnitGroups + chosenUnitGroup = _chosenUnitGroup.value, + favoritesOnly = _favoritesOnly.value, + searchQuery = _searchQuery.value, + allUnitsGroups = _shownUnitGroups.value ) - _uiStateFlow.value = _uiStateFlow.value.copy(unitsToShow = unitsToShow) + _unitsToShow.update { unitsToShow } } } } diff --git a/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsScreen.kt b/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsScreen.kt index aae0813e..aa438ddc 100644 --- a/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsScreen.kt +++ b/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsScreen.kt @@ -30,6 +30,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.sadellie.unitto.BuildConfig import com.sadellie.unitto.R import com.sadellie.unitto.data.NavRoutes.ABOUT_SCREEN @@ -51,6 +52,7 @@ fun SettingsScreen( navControllerAction: (String) -> Unit ) { val mContext = LocalContext.current + val userPrefs = viewModel.userPrefs.collectAsStateWithLifecycle() var dialogState: DialogState by rememberSaveable { mutableStateOf(DialogState.NONE) } @@ -151,7 +153,7 @@ fun SettingsScreen( UnittoListItem( label = stringResource(R.string.send_usage_statistics), supportText = stringResource(R.string.send_usage_statistics_support), - switchState = viewModel.userPrefs.enableAnalytics + switchState = userPrefs.value.enableAnalytics ) { viewModel.updateEnableAnalytics(it) } } } @@ -198,7 +200,7 @@ fun SettingsScreen( AlertDialogWithList( title = stringResource(R.string.precision_setting), listItems = PRECISIONS, - selectedItemIndex = viewModel.userPrefs.digitsPrecision, + selectedItemIndex = userPrefs.value.digitsPrecision, selectAction = { viewModel.updatePrecision(it) }, dismissAction = { resetDialog() }, supportText = stringResource(R.string.precision_setting_info) @@ -208,7 +210,7 @@ fun SettingsScreen( AlertDialogWithList( title = stringResource(R.string.separator_setting), listItems = SEPARATORS, - selectedItemIndex = viewModel.userPrefs.separator, + selectedItemIndex = userPrefs.value.separator, selectAction = { viewModel.updateSeparator(it) }, dismissAction = { resetDialog() } ) @@ -217,7 +219,7 @@ fun SettingsScreen( AlertDialogWithList( title = stringResource(R.string.output_format_setting), listItems = OUTPUT_FORMAT, - selectedItemIndex = viewModel.userPrefs.outputFormat, + selectedItemIndex = userPrefs.value.outputFormat, selectAction = { viewModel.updateOutputFormat(it) }, dismissAction = { resetDialog() }, supportText = stringResource(R.string.output_format_setting_info) diff --git a/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsViewModel.kt b/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsViewModel.kt index 6192d663..9de4da3d 100644 --- a/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsViewModel.kt +++ b/app/src/main/java/com/sadellie/unitto/screens/setttings/SettingsViewModel.kt @@ -19,9 +19,6 @@ package com.sadellie.unitto.screens.setttings import android.app.Application -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.sadellie.unitto.FirebaseHelper @@ -32,7 +29,10 @@ import com.sadellie.unitto.data.units.UnitGroupsRepository import com.sadellie.unitto.screens.Formatter import dagger.hilt.android.lifecycle.HiltViewModel import io.github.sadellie.themmo.ThemingMode +import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import org.burnoutcrew.reorderable.ItemPosition import javax.inject.Inject @@ -43,7 +43,9 @@ class SettingsViewModel @Inject constructor( private val unitGroupsRepository: UnitGroupsRepository, private val application: Application, ) : ViewModel() { - var userPrefs: UserPreferences by mutableStateOf(UserPreferences()) + var userPrefs = userPrefsRepository.userPreferencesFlow + .onEach { Formatter.setSeparator(it.separator) } + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), UserPreferences()) val shownUnitGroups = unitGroupsRepository.shownUnitGroups val hiddenUnitGroups = unitGroupsRepository.hiddenUnitGroups @@ -164,11 +166,6 @@ class SettingsViewModel @Inject constructor( unitGroupsRepository.updateShownGroups( userPrefsRepository.userPreferencesFlow.first().shownUnitGroups ) - - userPrefsRepository.userPreferencesFlow.collect { - userPrefs = it - Formatter.setSeparator(it.separator) - } } } }