Save favorites state

This commit is contained in:
Sad Ellie 2023-04-03 11:53:50 +03:00
parent bb8e909b23
commit 754ba665fd
3 changed files with 47 additions and 14 deletions

View File

@ -55,6 +55,7 @@ import javax.inject.Inject
* @property enableVibrations When true will use haptic feedback in app. * @property enableVibrations When true will use haptic feedback in app.
* @property enableToolsExperiment When true will enable experimental Tools screen. * @property enableToolsExperiment When true will enable experimental Tools screen.
* @property radianMode AngleMode in mxParser. When true - Radian, when False - Degree. * @property radianMode AngleMode in mxParser. When true - Radian, when False - Degree.
* @property unitConverterFavoritesOnly If true will show only units that are marked as favorite.
*/ */
data class UserPreferences( data class UserPreferences(
val themingMode: ThemingMode? = null, val themingMode: ThemingMode? = null,
@ -69,7 +70,8 @@ data class UserPreferences(
val enableVibrations: Boolean = true, val enableVibrations: Boolean = true,
val enableToolsExperiment: Boolean = false, val enableToolsExperiment: Boolean = false,
val startingScreen: String = TopLevelDestinations.Converter.route, val startingScreen: String = TopLevelDestinations.Converter.route,
val radianMode: Boolean = true val radianMode: Boolean = true,
val unitConverterFavoritesOnly: Boolean = false
) )
/** /**
@ -93,6 +95,7 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS
val ENABLE_TOOLS_EXPERIMENT = booleanPreferencesKey("ENABLE_TOOLS_EXPERIMENT_PREF_KEY") val ENABLE_TOOLS_EXPERIMENT = booleanPreferencesKey("ENABLE_TOOLS_EXPERIMENT_PREF_KEY")
val STARTING_SCREEN = stringPreferencesKey("STARTING_SCREEN_PREF_KEY") val STARTING_SCREEN = stringPreferencesKey("STARTING_SCREEN_PREF_KEY")
val RADIAN_MODE = booleanPreferencesKey("RADIAN_MODE_PREF_KEY") val RADIAN_MODE = booleanPreferencesKey("RADIAN_MODE_PREF_KEY")
val UNIT_CONVERTER_FAVORITES_ONLY = booleanPreferencesKey("UNIT_CONVERTER_FAVORITES_ONLY_PREF_KEY")
} }
val userPreferencesFlow: Flow<UserPreferences> = dataStore.data val userPreferencesFlow: Flow<UserPreferences> = dataStore.data
@ -138,6 +141,7 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS
val enableToolsExperiment: Boolean = preferences[PrefsKeys.ENABLE_TOOLS_EXPERIMENT] ?: false val enableToolsExperiment: Boolean = preferences[PrefsKeys.ENABLE_TOOLS_EXPERIMENT] ?: false
val startingScreen: String = preferences[PrefsKeys.STARTING_SCREEN] ?: TopLevelDestinations.Converter.route val startingScreen: String = preferences[PrefsKeys.STARTING_SCREEN] ?: TopLevelDestinations.Converter.route
val radianMode: Boolean = preferences[PrefsKeys.RADIAN_MODE] ?: true val radianMode: Boolean = preferences[PrefsKeys.RADIAN_MODE] ?: true
val unitConverterFavoritesOnly: Boolean = preferences[PrefsKeys.UNIT_CONVERTER_FAVORITES_ONLY] ?: false
UserPreferences( UserPreferences(
themingMode = themingMode, themingMode = themingMode,
@ -152,7 +156,8 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS
enableVibrations = enableVibrations, enableVibrations = enableVibrations,
enableToolsExperiment = enableToolsExperiment, enableToolsExperiment = enableToolsExperiment,
startingScreen = startingScreen, startingScreen = startingScreen,
radianMode = radianMode radianMode = radianMode,
unitConverterFavoritesOnly = unitConverterFavoritesOnly
) )
} }
@ -285,4 +290,15 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS
preferences[PrefsKeys.RADIAN_MODE] = radianMode preferences[PrefsKeys.RADIAN_MODE] = radianMode
} }
} }
/**
* Update units list favorite filter state.
*
* @param enabled When true will show only favorite units.
*/
suspend fun updateUnitConverterFavoritesOnly(enabled: Boolean) {
dataStore.edit { preferences ->
preferences[PrefsKeys.UNIT_CONVERTER_FAVORITES_ONLY] = enabled
}
}
} }

View File

@ -28,7 +28,10 @@ android {
} }
dependencies { dependencies {
implementation(libs.com.github.sadellie.themmo)
implementation(project(mapOf("path" to ":data:model"))) implementation(project(mapOf("path" to ":data:model")))
implementation(project(mapOf("path" to ":data:userprefs")))
implementation(project(mapOf("path" to ":data:units"))) implementation(project(mapOf("path" to ":data:units")))
implementation(project(mapOf("path" to ":data:database"))) implementation(project(mapOf("path" to ":data:database")))
implementation(project(mapOf("path" to ":data:unitgroups"))) implementation(project(mapOf("path" to ":data:unitgroups")))

View File

@ -25,11 +25,15 @@ import com.sadellie.unitto.data.database.UnitsEntity
import com.sadellie.unitto.data.database.UnitsRepository import com.sadellie.unitto.data.database.UnitsRepository
import com.sadellie.unitto.data.model.AbstractUnit import com.sadellie.unitto.data.model.AbstractUnit
import com.sadellie.unitto.data.model.UnitGroup import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.unitgroups.UnitGroupsRepository
import com.sadellie.unitto.data.units.AllUnitsRepository import com.sadellie.unitto.data.units.AllUnitsRepository
import com.sadellie.unitto.data.userprefs.UserPreferences
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
@ -42,36 +46,46 @@ class UnitsListViewModel @Inject constructor(
private val unitRepository: UnitsRepository, private val unitRepository: UnitsRepository,
private val allUnitsRepository: AllUnitsRepository, private val allUnitsRepository: AllUnitsRepository,
private val mContext: Application, private val mContext: Application,
unitGroupsRepository: com.sadellie.unitto.data.unitgroups.UnitGroupsRepository, private val userPrefsRepository: UserPreferencesRepository,
unitGroupsRepository: UnitGroupsRepository,
) : ViewModel() { ) : ViewModel() {
private val _favoritesOnly = MutableStateFlow(false) private val _userPrefs: StateFlow<UserPreferences> =
userPrefsRepository.userPreferencesFlow.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5000L),
UserPreferences()
)
private val _unitsToShow = MutableStateFlow(emptyMap<UnitGroup, List<AbstractUnit>>()) private val _unitsToShow = MutableStateFlow(emptyMap<UnitGroup, List<AbstractUnit>>())
private val _searchQuery = MutableStateFlow("") private val _searchQuery = MutableStateFlow("")
private val _chosenUnitGroup: MutableStateFlow<UnitGroup?> = MutableStateFlow(null) private val _chosenUnitGroup: MutableStateFlow<UnitGroup?> = MutableStateFlow(null)
private val _shownUnitGroups = unitGroupsRepository.shownUnitGroups private val _shownUnitGroups = unitGroupsRepository.shownUnitGroups
val mainFlow = combine( val mainFlow = combine(
_favoritesOnly, _userPrefs,
_unitsToShow, _unitsToShow,
_searchQuery, _searchQuery,
_chosenUnitGroup, _chosenUnitGroup,
_shownUnitGroups _shownUnitGroups,
) { favoritesOnly, unitsToShow, searchQuery, chosenUnitGroup, shownUnitGroups -> ) { userPrefs, unitsToShow, searchQuery, chosenUnitGroup, shownUnitGroups ->
return@combine SecondScreenUIState( return@combine SecondScreenUIState(
favoritesOnly = favoritesOnly, favoritesOnly = userPrefs.unitConverterFavoritesOnly,
unitsToShow = unitsToShow, unitsToShow = unitsToShow,
searchQuery = searchQuery, searchQuery = searchQuery,
chosenUnitGroup = chosenUnitGroup, chosenUnitGroup = chosenUnitGroup,
shownUnitGroups = shownUnitGroups shownUnitGroups = shownUnitGroups,
) )
} }
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), SecondScreenUIState()) .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), SecondScreenUIState())
fun toggleFavoritesOnly(hideBrokenCurrencies: Boolean = true) { fun toggleFavoritesOnly(hideBrokenCurrencies: Boolean = true) {
_favoritesOnly.update { !_favoritesOnly.value } viewModelScope.launch {
userPrefsRepository.updateUnitConverterFavoritesOnly(
!_userPrefs.value.unitConverterFavoritesOnly
)
loadUnitsToShow(hideBrokenCurrencies) loadUnitsToShow(hideBrokenCurrencies)
} }
}
fun onSearchQueryChange(newValue: String, hideBrokenCurrencies: Boolean = true) { fun onSearchQueryChange(newValue: String, hideBrokenCurrencies: Boolean = true) {
_searchQuery.update { newValue } _searchQuery.update { newValue }
@ -118,7 +132,7 @@ class UnitsListViewModel @Inject constructor(
val unitsToShow = allUnitsRepository.filterUnits( val unitsToShow = allUnitsRepository.filterUnits(
hideBrokenCurrencies = hideBrokenCurrencies, hideBrokenCurrencies = hideBrokenCurrencies,
chosenUnitGroup = _chosenUnitGroup.value, chosenUnitGroup = _chosenUnitGroup.value,
favoritesOnly = _favoritesOnly.value, favoritesOnly = _userPrefs.value.unitConverterFavoritesOnly,
searchQuery = _searchQuery.value, searchQuery = _searchQuery.value,
allUnitsGroups = _shownUnitGroups.value allUnitsGroups = _shownUnitGroups.value
) )
@ -147,7 +161,7 @@ class UnitsListViewModel @Inject constructor(
} }
} }
private fun loadUnits() { private fun loadUnitsFromDatabase() {
viewModelScope.launch(Dispatchers.IO) { viewModelScope.launch(Dispatchers.IO) {
// Now we load units data from database // Now we load units data from database
val allUnits = unitRepository.getAll() val allUnits = unitRepository.getAll()
@ -156,6 +170,6 @@ class UnitsListViewModel @Inject constructor(
} }
init { init {
loadUnits() loadUnitsFromDatabase()
} }
} }