mirror of
https://github.com/Myzel394/NumberHub.git
synced 2025-06-19 00:35:26 +02:00
Separate User Preferences
This commit is contained in:
parent
1b61b4bd85
commit
86dce329ac
@ -120,8 +120,7 @@ dependencies {
|
|||||||
implementation(project(mapOf("path" to ":feature:calculator")))
|
implementation(project(mapOf("path" to ":feature:calculator")))
|
||||||
implementation(project(mapOf("path" to ":feature:settings")))
|
implementation(project(mapOf("path" to ":feature:settings")))
|
||||||
implementation(project(mapOf("path" to ":feature:unitslist")))
|
implementation(project(mapOf("path" to ":feature:unitslist")))
|
||||||
implementation(project(mapOf("path" to ":feature:datedifference")))
|
implementation(project(mapOf("path" to ":feature:datedifference")))
|
||||||
implementation(project(mapOf("path" to ":data:units")))
|
|
||||||
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:userprefs")))
|
||||||
implementation(project(mapOf("path" to ":core:ui")))
|
implementation(project(mapOf("path" to ":core:ui")))
|
||||||
|
@ -40,13 +40,11 @@ internal class MainActivity : ComponentActivity() {
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
val userPrefsFlow = userPrefsRepository.userPreferencesFlow
|
|
||||||
|
|
||||||
setContent {
|
setContent {
|
||||||
val userPrefs = userPrefsFlow
|
val uiPrefs = userPrefsRepository.uiPreferencesFlow
|
||||||
.collectAsStateWithLifecycle(null).value
|
.collectAsStateWithLifecycle(null).value
|
||||||
|
|
||||||
if (userPrefs != null) UnittoApp(userPrefs)
|
if (uiPrefs != null) UnittoApp(uiPrefs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,23 +44,23 @@ import com.sadellie.unitto.core.ui.model.DrawerItems
|
|||||||
import com.sadellie.unitto.core.ui.theme.AppTypography
|
import com.sadellie.unitto.core.ui.theme.AppTypography
|
||||||
import com.sadellie.unitto.core.ui.theme.DarkThemeColors
|
import com.sadellie.unitto.core.ui.theme.DarkThemeColors
|
||||||
import com.sadellie.unitto.core.ui.theme.LightThemeColors
|
import com.sadellie.unitto.core.ui.theme.LightThemeColors
|
||||||
import com.sadellie.unitto.data.userprefs.UserPreferences
|
import com.sadellie.unitto.data.userprefs.UIPreferences
|
||||||
import io.github.sadellie.themmo.Themmo
|
import io.github.sadellie.themmo.Themmo
|
||||||
import io.github.sadellie.themmo.rememberThemmoController
|
import io.github.sadellie.themmo.rememberThemmoController
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun UnittoApp(userPrefs: UserPreferences) {
|
internal fun UnittoApp(uiPrefs: UIPreferences) {
|
||||||
|
|
||||||
val themmoController = rememberThemmoController(
|
val themmoController = rememberThemmoController(
|
||||||
lightColorScheme = LightThemeColors,
|
lightColorScheme = LightThemeColors,
|
||||||
darkColorScheme = DarkThemeColors,
|
darkColorScheme = DarkThemeColors,
|
||||||
// Anything below will not be called if theming mode is still loading from DataStore
|
// Anything below will not be called if theming mode is still loading from DataStore
|
||||||
themingMode = userPrefs.themingMode,
|
themingMode = uiPrefs.themingMode,
|
||||||
dynamicThemeEnabled = userPrefs.enableDynamicTheme,
|
dynamicThemeEnabled = uiPrefs.enableDynamicTheme,
|
||||||
amoledThemeEnabled = userPrefs.enableAmoledTheme,
|
amoledThemeEnabled = uiPrefs.enableAmoledTheme,
|
||||||
customColor = userPrefs.customColor,
|
customColor = uiPrefs.customColor,
|
||||||
monetMode = userPrefs.monetMode
|
monetMode = uiPrefs.monetMode
|
||||||
)
|
)
|
||||||
val navController = rememberNavController()
|
val navController = rememberNavController()
|
||||||
val sysUiController = rememberSystemUiController()
|
val sysUiController = rememberSystemUiController()
|
||||||
@ -131,7 +131,7 @@ internal fun UnittoApp(userPrefs: UserPreferences) {
|
|||||||
UnittoNavigation(
|
UnittoNavigation(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
themmoController = it,
|
themmoController = it,
|
||||||
startDestination = userPrefs.startingScreen,
|
startDestination = uiPrefs.startingScreen,
|
||||||
openDrawer = { drawerScope.launch { drawerState.open() } }
|
openDrawer = { drawerScope.launch { drawerState.open() } }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ import com.sadellie.unitto.feature.calculator.navigation.calculatorScreen
|
|||||||
import com.sadellie.unitto.feature.converter.ConverterViewModel
|
import com.sadellie.unitto.feature.converter.ConverterViewModel
|
||||||
import com.sadellie.unitto.feature.converter.navigation.converterScreen
|
import com.sadellie.unitto.feature.converter.navigation.converterScreen
|
||||||
import com.sadellie.unitto.feature.datedifference.navigation.dateDifferenceScreen
|
import com.sadellie.unitto.feature.datedifference.navigation.dateDifferenceScreen
|
||||||
import com.sadellie.unitto.feature.settings.SettingsViewModel
|
|
||||||
import com.sadellie.unitto.feature.settings.navigation.navigateToSettings
|
import com.sadellie.unitto.feature.settings.navigation.navigateToSettings
|
||||||
import com.sadellie.unitto.feature.settings.navigation.navigateToUnitGroups
|
import com.sadellie.unitto.feature.settings.navigation.navigateToUnitGroups
|
||||||
import com.sadellie.unitto.feature.settings.navigation.settingGraph
|
import com.sadellie.unitto.feature.settings.navigation.settingGraph
|
||||||
@ -50,7 +49,6 @@ internal fun UnittoNavigation(
|
|||||||
) {
|
) {
|
||||||
val converterViewModel: ConverterViewModel = hiltViewModel()
|
val converterViewModel: ConverterViewModel = hiltViewModel()
|
||||||
val unitsListViewModel: UnitsListViewModel = hiltViewModel()
|
val unitsListViewModel: UnitsListViewModel = hiltViewModel()
|
||||||
val settingsViewModel: SettingsViewModel = hiltViewModel()
|
|
||||||
|
|
||||||
NavHost(
|
NavHost(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
@ -90,7 +88,6 @@ internal fun UnittoNavigation(
|
|||||||
)
|
)
|
||||||
|
|
||||||
settingGraph(
|
settingGraph(
|
||||||
settingsViewModel = settingsViewModel,
|
|
||||||
themmoController = themmoController,
|
themmoController = themmoController,
|
||||||
navController = navController,
|
navController = navController,
|
||||||
menuButtonClick = openDrawer
|
menuButtonClick = openDrawer
|
||||||
|
@ -1,115 +0,0 @@
|
|||||||
/*
|
|
||||||
* Unitto is a unit converter for Android
|
|
||||||
* Copyright (c) 2022-2023 Elshan Agaev
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.sadellie.unitto.data.unitgroups
|
|
||||||
|
|
||||||
import com.sadellie.unitto.data.model.ALL_UNIT_GROUPS
|
|
||||||
import com.sadellie.unitto.data.model.UnitGroup
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
|
||||||
import kotlinx.coroutines.sync.withLock
|
|
||||||
import org.burnoutcrew.reorderable.ItemPosition
|
|
||||||
import javax.inject.Inject
|
|
||||||
import javax.inject.Singleton
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Repository that holds information about shown and hidden [UnitGroup]s and provides methods to
|
|
||||||
* show/hide [UnitGroup]s.
|
|
||||||
*/
|
|
||||||
@Singleton
|
|
||||||
class UnitGroupsRepository @Inject constructor() {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mutex is need needed because we work with flow (sync stuff).
|
|
||||||
*/
|
|
||||||
private val mutex = Mutex()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Currently shown [UnitGroup]s.
|
|
||||||
*/
|
|
||||||
var shownUnitGroups = MutableStateFlow(listOf<UnitGroup>())
|
|
||||||
private set
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Currently hidden [UnitGroup]s.
|
|
||||||
*/
|
|
||||||
var hiddenUnitGroups = MutableStateFlow(listOf<UnitGroup>())
|
|
||||||
private set
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets [shownUnitGroups] and updates [hiddenUnitGroups] as a side effect. [hiddenUnitGroups] is
|
|
||||||
* everything from [ALL_UNIT_GROUPS] that was not in [shownUnitGroups].
|
|
||||||
*
|
|
||||||
* @param list List of [UnitGroup]s that need to be shown.
|
|
||||||
*/
|
|
||||||
suspend fun updateShownGroups(list: List<UnitGroup>) {
|
|
||||||
mutex.withLock {
|
|
||||||
shownUnitGroups.value = list
|
|
||||||
hiddenUnitGroups.value = ALL_UNIT_GROUPS - list.toSet()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Moves [UnitGroup] from [shownUnitGroups] to [hiddenUnitGroups]
|
|
||||||
*
|
|
||||||
* @param unitGroup [UnitGroup] to hide.
|
|
||||||
*/
|
|
||||||
suspend fun markUnitGroupAsHidden(unitGroup: UnitGroup) {
|
|
||||||
mutex.withLock {
|
|
||||||
shownUnitGroups.value = shownUnitGroups.value - unitGroup
|
|
||||||
// Newly hidden unit will appear at the top of the list
|
|
||||||
hiddenUnitGroups.value = listOf(unitGroup) + hiddenUnitGroups.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Moves [UnitGroup] from [hiddenUnitGroups] to [shownUnitGroups]
|
|
||||||
*
|
|
||||||
* @param unitGroup [UnitGroup] to show.
|
|
||||||
*/
|
|
||||||
suspend fun markUnitGroupAsShown(unitGroup: UnitGroup) {
|
|
||||||
mutex.withLock {
|
|
||||||
hiddenUnitGroups.value = hiddenUnitGroups.value - unitGroup
|
|
||||||
shownUnitGroups.value = shownUnitGroups.value + unitGroup
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Moves [UnitGroup] in [shownUnitGroups] from one index to another (reorder).
|
|
||||||
*
|
|
||||||
* @param from Position from which we need to move from
|
|
||||||
* @param to Position where to put [UnitGroup]
|
|
||||||
*/
|
|
||||||
suspend fun moveShownUnitGroups(from: ItemPosition, to: ItemPosition) {
|
|
||||||
mutex.withLock {
|
|
||||||
shownUnitGroups.value = shownUnitGroups.value.toMutableList().apply {
|
|
||||||
val initialIndex = shownUnitGroups.value.indexOfFirst { it == from.key }
|
|
||||||
/**
|
|
||||||
* No such item. Happens when dragging item and clicking "remove" while item is
|
|
||||||
* still being dragged.
|
|
||||||
*/
|
|
||||||
if (initialIndex == -1) return
|
|
||||||
|
|
||||||
add(
|
|
||||||
shownUnitGroups.value.indexOfFirst { it == to.key },
|
|
||||||
removeAt(initialIndex)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -39,6 +39,7 @@ import io.github.sadellie.themmo.MonetMode
|
|||||||
import io.github.sadellie.themmo.ThemingMode
|
import io.github.sadellie.themmo.ThemingMode
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.catch
|
import kotlinx.coroutines.flow.catch
|
||||||
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -84,6 +85,29 @@ data class UserPreferences(
|
|||||||
val unitConverterSorting: UnitsListSorting = UnitsListSorting.USAGE,
|
val unitConverterSorting: UnitsListSorting = UnitsListSorting.USAGE,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data class UIPreferences(
|
||||||
|
val themingMode: ThemingMode = ThemingMode.AUTO,
|
||||||
|
val enableDynamicTheme: Boolean = false,
|
||||||
|
val enableAmoledTheme: Boolean = false,
|
||||||
|
val customColor: Color = Color.Unspecified,
|
||||||
|
val monetMode: MonetMode = MonetMode.TONAL_SPOT,
|
||||||
|
val startingScreen: String = TopLevelDestinations.Converter.route,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class MainPreferences(
|
||||||
|
val digitsPrecision: Int = 3,
|
||||||
|
val separator: Int = Separator.SPACES,
|
||||||
|
val outputFormat: Int = OutputFormat.PLAIN,
|
||||||
|
val latestLeftSideUnit: String = MyUnitIDS.kilometer,
|
||||||
|
val latestRightSideUnit: String = MyUnitIDS.mile,
|
||||||
|
val shownUnitGroups: List<UnitGroup> = ALL_UNIT_GROUPS,
|
||||||
|
val enableVibrations: Boolean = true,
|
||||||
|
val radianMode: Boolean = true,
|
||||||
|
val unitConverterFavoritesOnly: Boolean = false,
|
||||||
|
val unitConverterFormatTime: Boolean = false,
|
||||||
|
val unitConverterSorting: UnitsListSorting = UnitsListSorting.USAGE,
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repository that works with DataStore
|
* Repository that works with DataStore
|
||||||
*/
|
*/
|
||||||
@ -112,7 +136,7 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS
|
|||||||
val UNIT_CONVERTER_SORTING = stringPreferencesKey("UNIT_CONVERTER_SORTING_PREF_KEY")
|
val UNIT_CONVERTER_SORTING = stringPreferencesKey("UNIT_CONVERTER_SORTING_PREF_KEY")
|
||||||
}
|
}
|
||||||
|
|
||||||
val userPreferencesFlow: Flow<UserPreferences> = dataStore.data
|
val uiPreferencesFlow: Flow<UIPreferences> = dataStore.data
|
||||||
.catch { exception ->
|
.catch { exception ->
|
||||||
if (exception is IOException) {
|
if (exception is IOException) {
|
||||||
emit(emptyPreferences())
|
emit(emptyPreferences())
|
||||||
@ -128,6 +152,27 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS
|
|||||||
val customColor: Color = preferences[PrefsKeys.CUSTOM_COLOR]?.let { Color(it.toULong()) } ?: Color.Unspecified
|
val customColor: Color = preferences[PrefsKeys.CUSTOM_COLOR]?.let { Color(it.toULong()) } ?: Color.Unspecified
|
||||||
val monetMode: MonetMode = preferences[PrefsKeys.MONET_MODE]?.let { MonetMode.valueOf(it) }
|
val monetMode: MonetMode = preferences[PrefsKeys.MONET_MODE]?.let { MonetMode.valueOf(it) }
|
||||||
?: MonetMode.TONAL_SPOT
|
?: MonetMode.TONAL_SPOT
|
||||||
|
val startingScreen: String = preferences[PrefsKeys.STARTING_SCREEN] ?: TopLevelDestinations.Converter.route
|
||||||
|
|
||||||
|
UIPreferences(
|
||||||
|
themingMode = themingMode,
|
||||||
|
enableDynamicTheme = enableDynamicTheme,
|
||||||
|
enableAmoledTheme = enableAmoledTheme,
|
||||||
|
customColor = customColor,
|
||||||
|
monetMode = monetMode,
|
||||||
|
startingScreen = startingScreen
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val mainPreferencesFlow: Flow<MainPreferences> = dataStore.data
|
||||||
|
.catch { exception ->
|
||||||
|
if (exception is IOException) {
|
||||||
|
emit(emptyPreferences())
|
||||||
|
} else {
|
||||||
|
throw exception
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.map { preferences ->
|
||||||
val digitsPrecision: Int = preferences[PrefsKeys.DIGITS_PRECISION] ?: 3
|
val digitsPrecision: Int = preferences[PrefsKeys.DIGITS_PRECISION] ?: 3
|
||||||
val separator: Int = preferences[PrefsKeys.SEPARATOR] ?: Separator.SPACES
|
val separator: Int = preferences[PrefsKeys.SEPARATOR] ?: Separator.SPACES
|
||||||
val outputFormat: Int = preferences[PrefsKeys.OUTPUT_FORMAT] ?: OutputFormat.PLAIN
|
val outputFormat: Int = preferences[PrefsKeys.OUTPUT_FORMAT] ?: OutputFormat.PLAIN
|
||||||
@ -147,19 +192,12 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS
|
|||||||
|
|
||||||
} ?: ALL_UNIT_GROUPS
|
} ?: ALL_UNIT_GROUPS
|
||||||
val enableVibrations: Boolean = preferences[PrefsKeys.ENABLE_VIBRATIONS] ?: true
|
val enableVibrations: Boolean = preferences[PrefsKeys.ENABLE_VIBRATIONS] ?: true
|
||||||
val enableToolsExperiment: Boolean = preferences[PrefsKeys.ENABLE_TOOLS_EXPERIMENT] ?: false
|
|
||||||
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
|
val unitConverterFavoritesOnly: Boolean = preferences[PrefsKeys.UNIT_CONVERTER_FAVORITES_ONLY] ?: false
|
||||||
val unitConverterFormatTime: Boolean = preferences[PrefsKeys.UNIT_CONVERTER_FORMAT_TIME] ?: false
|
val unitConverterFormatTime: Boolean = preferences[PrefsKeys.UNIT_CONVERTER_FORMAT_TIME] ?: false
|
||||||
val unitConverterSorting: UnitsListSorting = preferences[PrefsKeys.UNIT_CONVERTER_SORTING]?.let { UnitsListSorting.valueOf(it) } ?: UnitsListSorting.USAGE
|
val unitConverterSorting: UnitsListSorting = preferences[PrefsKeys.UNIT_CONVERTER_SORTING]?.let { UnitsListSorting.valueOf(it) } ?: UnitsListSorting.USAGE
|
||||||
|
|
||||||
UserPreferences(
|
MainPreferences(
|
||||||
themingMode = themingMode,
|
|
||||||
enableDynamicTheme = enableDynamicTheme,
|
|
||||||
enableAmoledTheme = enableAmoledTheme,
|
|
||||||
customColor = customColor,
|
|
||||||
monetMode = monetMode,
|
|
||||||
digitsPrecision = digitsPrecision,
|
digitsPrecision = digitsPrecision,
|
||||||
separator = separator,
|
separator = separator,
|
||||||
outputFormat = outputFormat,
|
outputFormat = outputFormat,
|
||||||
@ -167,8 +205,6 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS
|
|||||||
latestRightSideUnit = latestRightSideUnit,
|
latestRightSideUnit = latestRightSideUnit,
|
||||||
shownUnitGroups = shownUnitGroups,
|
shownUnitGroups = shownUnitGroups,
|
||||||
enableVibrations = enableVibrations,
|
enableVibrations = enableVibrations,
|
||||||
enableToolsExperiment = enableToolsExperiment,
|
|
||||||
startingScreen = startingScreen,
|
|
||||||
radianMode = radianMode,
|
radianMode = radianMode,
|
||||||
unitConverterFavoritesOnly = unitConverterFavoritesOnly,
|
unitConverterFavoritesOnly = unitConverterFavoritesOnly,
|
||||||
unitConverterFormatTime = unitConverterFormatTime,
|
unitConverterFormatTime = unitConverterFormatTime,
|
||||||
@ -176,6 +212,31 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val allPreferencesFlow = combine(
|
||||||
|
mainPreferencesFlow, uiPreferencesFlow
|
||||||
|
) { main, ui ->
|
||||||
|
return@combine UserPreferences(
|
||||||
|
themingMode = ui.themingMode,
|
||||||
|
enableDynamicTheme = ui.enableDynamicTheme,
|
||||||
|
enableAmoledTheme = ui.enableAmoledTheme,
|
||||||
|
customColor = ui.customColor,
|
||||||
|
monetMode = ui.monetMode,
|
||||||
|
digitsPrecision = main.digitsPrecision,
|
||||||
|
separator = main.separator,
|
||||||
|
outputFormat = main.outputFormat,
|
||||||
|
latestLeftSideUnit = main.latestLeftSideUnit,
|
||||||
|
latestRightSideUnit = main.latestRightSideUnit,
|
||||||
|
shownUnitGroups = main.shownUnitGroups,
|
||||||
|
enableVibrations = main.enableVibrations,
|
||||||
|
enableToolsExperiment = false,
|
||||||
|
startingScreen = ui.startingScreen,
|
||||||
|
radianMode = main.radianMode,
|
||||||
|
unitConverterFavoritesOnly = main.unitConverterFavoritesOnly,
|
||||||
|
unitConverterFormatTime = main.unitConverterFormatTime,
|
||||||
|
unitConverterSorting = main.unitConverterSorting,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update precision preference in DataStore
|
* Update precision preference in DataStore
|
||||||
*
|
*
|
||||||
|
@ -29,7 +29,6 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testImplementation(libs.junit)
|
testImplementation(libs.junit)
|
||||||
implementation(libs.com.github.sadellie.themmo)
|
|
||||||
|
|
||||||
implementation(project(mapOf("path" to ":data:common")))
|
implementation(project(mapOf("path" to ":data:common")))
|
||||||
implementation(project(mapOf("path" to ":data:userprefs")))
|
implementation(project(mapOf("path" to ":data:userprefs")))
|
||||||
|
@ -31,7 +31,7 @@ import com.sadellie.unitto.data.common.isExpression
|
|||||||
import com.sadellie.unitto.data.common.setMinimumRequiredScale
|
import com.sadellie.unitto.data.common.setMinimumRequiredScale
|
||||||
import com.sadellie.unitto.data.common.toStringWith
|
import com.sadellie.unitto.data.common.toStringWith
|
||||||
import com.sadellie.unitto.data.common.trimZeros
|
import com.sadellie.unitto.data.common.trimZeros
|
||||||
import com.sadellie.unitto.data.userprefs.UserPreferences
|
import com.sadellie.unitto.data.userprefs.MainPreferences
|
||||||
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
|
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import io.github.sadellie.evaluatto.Expression
|
import io.github.sadellie.evaluatto.Expression
|
||||||
@ -54,11 +54,11 @@ internal class CalculatorViewModel @Inject constructor(
|
|||||||
private val userPrefsRepository: UserPreferencesRepository,
|
private val userPrefsRepository: UserPreferencesRepository,
|
||||||
private val calculatorHistoryRepository: CalculatorHistoryRepository,
|
private val calculatorHistoryRepository: CalculatorHistoryRepository,
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
private val _userPrefs: StateFlow<UserPreferences> =
|
private val _userPrefs: StateFlow<MainPreferences> =
|
||||||
userPrefsRepository.userPreferencesFlow.stateIn(
|
userPrefsRepository.mainPreferencesFlow.stateIn(
|
||||||
viewModelScope,
|
viewModelScope,
|
||||||
SharingStarted.WhileSubscribed(5000L),
|
SharingStarted.WhileSubscribed(5000L),
|
||||||
UserPreferences()
|
MainPreferences()
|
||||||
)
|
)
|
||||||
|
|
||||||
private val _input: MutableStateFlow<TextFieldValue> = MutableStateFlow(TextFieldValue())
|
private val _input: MutableStateFlow<TextFieldValue> = MutableStateFlow(TextFieldValue())
|
||||||
|
@ -36,7 +36,6 @@ dependencies {
|
|||||||
kapt(libs.androidx.room.compiler)
|
kapt(libs.androidx.room.compiler)
|
||||||
testImplementation(libs.androidx.datastore)
|
testImplementation(libs.androidx.datastore)
|
||||||
|
|
||||||
implementation(libs.com.github.sadellie.themmo)
|
|
||||||
implementation(libs.com.squareup.moshi)
|
implementation(libs.com.squareup.moshi)
|
||||||
implementation(libs.com.squareup.retrofit2)
|
implementation(libs.com.squareup.retrofit2)
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ import com.sadellie.unitto.data.units.MyUnitIDS
|
|||||||
import com.sadellie.unitto.data.units.combine
|
import com.sadellie.unitto.data.units.combine
|
||||||
import com.sadellie.unitto.data.units.remote.CurrencyApi
|
import com.sadellie.unitto.data.units.remote.CurrencyApi
|
||||||
import com.sadellie.unitto.data.units.remote.CurrencyUnitResponse
|
import com.sadellie.unitto.data.units.remote.CurrencyUnitResponse
|
||||||
import com.sadellie.unitto.data.userprefs.UserPreferences
|
import com.sadellie.unitto.data.userprefs.MainPreferences
|
||||||
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
|
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import io.github.sadellie.evaluatto.Expression
|
import io.github.sadellie.evaluatto.Expression
|
||||||
@ -65,10 +65,10 @@ class ConverterViewModel @Inject constructor(
|
|||||||
private val allUnitsRepository: AllUnitsRepository
|
private val allUnitsRepository: AllUnitsRepository
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
private val _userPrefs = userPrefsRepository.userPreferencesFlow.stateIn(
|
private val _userPrefs = userPrefsRepository.mainPreferencesFlow.stateIn(
|
||||||
viewModelScope,
|
viewModelScope,
|
||||||
SharingStarted.WhileSubscribed(5000),
|
SharingStarted.WhileSubscribed(5000),
|
||||||
UserPreferences()
|
MainPreferences()
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -334,7 +334,7 @@ class ConverterViewModel @Inject constructor(
|
|||||||
|
|
||||||
private fun loadInitialUnitPair() {
|
private fun loadInitialUnitPair() {
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
val initialUserPrefs = userPrefsRepository.userPreferencesFlow.first()
|
val initialUserPrefs = userPrefsRepository.mainPreferencesFlow.first()
|
||||||
|
|
||||||
// First we load latest pair of units
|
// First we load latest pair of units
|
||||||
_unitFrom.update {
|
_unitFrom.update {
|
||||||
|
@ -43,6 +43,7 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.sadellie.unitto.core.base.BuildConfig
|
import com.sadellie.unitto.core.base.BuildConfig
|
||||||
import com.sadellie.unitto.core.base.R
|
import com.sadellie.unitto.core.base.R
|
||||||
@ -54,7 +55,7 @@ import com.sadellie.unitto.core.ui.openLink
|
|||||||
internal fun AboutScreen(
|
internal fun AboutScreen(
|
||||||
navigateUpAction: () -> Unit,
|
navigateUpAction: () -> Unit,
|
||||||
navigateToThirdParty: () -> Unit,
|
navigateToThirdParty: () -> Unit,
|
||||||
viewModel: SettingsViewModel
|
viewModel: SettingsViewModel = hiltViewModel()
|
||||||
) {
|
) {
|
||||||
val mContext = LocalContext.current
|
val mContext = LocalContext.current
|
||||||
val userPrefs = viewModel.userPrefs.collectAsStateWithLifecycle()
|
val userPrefs = viewModel.userPrefs.collectAsStateWithLifecycle()
|
||||||
|
@ -43,6 +43,7 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.sadellie.unitto.core.base.BuildConfig
|
import com.sadellie.unitto.core.base.BuildConfig
|
||||||
import com.sadellie.unitto.core.base.OUTPUT_FORMAT
|
import com.sadellie.unitto.core.base.OUTPUT_FORMAT
|
||||||
@ -63,7 +64,7 @@ import com.sadellie.unitto.feature.settings.navigation.unitsGroupRoute
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun SettingsScreen(
|
internal fun SettingsScreen(
|
||||||
viewModel: SettingsViewModel,
|
viewModel: SettingsViewModel = hiltViewModel(),
|
||||||
menuButtonClick: () -> Unit,
|
menuButtonClick: () -> Unit,
|
||||||
navControllerAction: (String) -> Unit
|
navControllerAction: (String) -> Unit
|
||||||
) {
|
) {
|
||||||
|
@ -18,80 +18,27 @@
|
|||||||
|
|
||||||
package com.sadellie.unitto.feature.settings
|
package com.sadellie.unitto.feature.settings
|
||||||
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.sadellie.unitto.data.model.UnitGroup
|
|
||||||
import com.sadellie.unitto.data.model.UnitsListSorting
|
import com.sadellie.unitto.data.model.UnitsListSorting
|
||||||
import com.sadellie.unitto.data.unitgroups.UnitGroupsRepository
|
|
||||||
import com.sadellie.unitto.data.userprefs.UserPreferences
|
import com.sadellie.unitto.data.userprefs.UserPreferences
|
||||||
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
|
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import io.github.sadellie.themmo.MonetMode
|
|
||||||
import io.github.sadellie.themmo.ThemingMode
|
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.first
|
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.burnoutcrew.reorderable.ItemPosition
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class SettingsViewModel @Inject constructor(
|
class SettingsViewModel @Inject constructor(
|
||||||
private val userPrefsRepository: UserPreferencesRepository,
|
private val userPrefsRepository: UserPreferencesRepository,
|
||||||
private val unitGroupsRepository: UnitGroupsRepository,
|
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
val userPrefs = userPrefsRepository.userPreferencesFlow
|
val userPrefs = userPrefsRepository.allPreferencesFlow
|
||||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000),
|
.stateIn(
|
||||||
|
viewModelScope,
|
||||||
|
SharingStarted.WhileSubscribed(5000),
|
||||||
UserPreferences()
|
UserPreferences()
|
||||||
)
|
)
|
||||||
val shownUnitGroups = unitGroupsRepository.shownUnitGroups
|
|
||||||
val hiddenUnitGroups = unitGroupsRepository.hiddenUnitGroups
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see UserPreferencesRepository.updateThemingMode
|
|
||||||
*/
|
|
||||||
fun updateThemingMode(themingMode: ThemingMode) {
|
|
||||||
viewModelScope.launch {
|
|
||||||
userPrefsRepository.updateThemingMode(themingMode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see UserPreferencesRepository.updateDynamicTheme
|
|
||||||
*/
|
|
||||||
fun updateDynamicTheme(enabled: Boolean) {
|
|
||||||
viewModelScope.launch {
|
|
||||||
userPrefsRepository.updateDynamicTheme(enabled)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see UserPreferencesRepository.updateAmoledTheme
|
|
||||||
*/
|
|
||||||
fun updateAmoledTheme(enabled: Boolean) {
|
|
||||||
viewModelScope.launch {
|
|
||||||
userPrefsRepository.updateAmoledTheme(enabled)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see UserPreferencesRepository.updateCustomColor
|
|
||||||
*/
|
|
||||||
fun updateCustomColor(color: Color) {
|
|
||||||
viewModelScope.launch {
|
|
||||||
userPrefsRepository.updateCustomColor(color)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see UserPreferencesRepository.updateMonetMode
|
|
||||||
*/
|
|
||||||
fun updateMonetMode(monetMode: MonetMode) {
|
|
||||||
viewModelScope.launch {
|
|
||||||
userPrefsRepository.updateMonetMode(monetMode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see UserPreferencesRepository.updateDigitsPrecision
|
* @see UserPreferencesRepository.updateDigitsPrecision
|
||||||
@ -138,46 +85,6 @@ class SettingsViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see UnitGroupsRepository.markUnitGroupAsHidden
|
|
||||||
* @see UserPreferencesRepository.updateShownUnitGroups
|
|
||||||
*/
|
|
||||||
fun hideUnitGroup(unitGroup: UnitGroup) {
|
|
||||||
viewModelScope.launch {
|
|
||||||
unitGroupsRepository.markUnitGroupAsHidden(unitGroup)
|
|
||||||
userPrefsRepository.updateShownUnitGroups(unitGroupsRepository.shownUnitGroups.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see UnitGroupsRepository.markUnitGroupAsShown
|
|
||||||
* @see UserPreferencesRepository.updateShownUnitGroups
|
|
||||||
*/
|
|
||||||
fun returnUnitGroup(unitGroup: UnitGroup) {
|
|
||||||
viewModelScope.launch {
|
|
||||||
unitGroupsRepository.markUnitGroupAsShown(unitGroup)
|
|
||||||
userPrefsRepository.updateShownUnitGroups(unitGroupsRepository.shownUnitGroups.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see UnitGroupsRepository.moveShownUnitGroups
|
|
||||||
*/
|
|
||||||
fun onMove(from: ItemPosition, to: ItemPosition) {
|
|
||||||
viewModelScope.launch {
|
|
||||||
unitGroupsRepository.moveShownUnitGroups(from, to)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see UserPreferencesRepository.updateShownUnitGroups
|
|
||||||
*/
|
|
||||||
fun onDragEnd() {
|
|
||||||
viewModelScope.launch {
|
|
||||||
userPrefsRepository.updateShownUnitGroups(unitGroupsRepository.shownUnitGroups.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see UserPreferencesRepository.updateToolsExperiment
|
* @see UserPreferencesRepository.updateToolsExperiment
|
||||||
*/
|
*/
|
||||||
@ -204,20 +111,4 @@ class SettingsViewModel @Inject constructor(
|
|||||||
userPrefsRepository.updateUnitConverterSorting(sorting)
|
userPrefsRepository.updateUnitConverterSorting(sorting)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevent from dragging over non-draggable items (headers and hidden)
|
|
||||||
*
|
|
||||||
* @param pos Position we are dragging over.
|
|
||||||
* @return True if can drag over given item.
|
|
||||||
*/
|
|
||||||
fun canDragOver(pos: ItemPosition) = shownUnitGroups.value.any { it == pos.key }
|
|
||||||
|
|
||||||
init {
|
|
||||||
viewModelScope.launch {
|
|
||||||
unitGroupsRepository.updateShownGroups(
|
|
||||||
userPrefsRepository.userPreferencesFlow.first().shownUnitGroups
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -27,10 +27,9 @@ import androidx.navigation.compose.navigation
|
|||||||
import com.sadellie.unitto.core.base.TopLevelDestinations
|
import com.sadellie.unitto.core.base.TopLevelDestinations
|
||||||
import com.sadellie.unitto.feature.settings.AboutScreen
|
import com.sadellie.unitto.feature.settings.AboutScreen
|
||||||
import com.sadellie.unitto.feature.settings.SettingsScreen
|
import com.sadellie.unitto.feature.settings.SettingsScreen
|
||||||
import com.sadellie.unitto.feature.settings.SettingsViewModel
|
import com.sadellie.unitto.feature.settings.themes.ThemesRoute
|
||||||
import com.sadellie.unitto.feature.settings.ThemesRoute
|
|
||||||
import com.sadellie.unitto.feature.settings.ThirdPartyLicensesScreen
|
import com.sadellie.unitto.feature.settings.ThirdPartyLicensesScreen
|
||||||
import com.sadellie.unitto.feature.settings.UnitGroupsScreen
|
import com.sadellie.unitto.feature.settings.unitgroups.UnitGroupsScreen
|
||||||
import io.github.sadellie.themmo.ThemmoController
|
import io.github.sadellie.themmo.ThemmoController
|
||||||
|
|
||||||
private val settingsGraph: String by lazy { TopLevelDestinations.Settings.route }
|
private val settingsGraph: String by lazy { TopLevelDestinations.Settings.route }
|
||||||
@ -49,7 +48,6 @@ fun NavController.navigateToUnitGroups() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun NavGraphBuilder.settingGraph(
|
fun NavGraphBuilder.settingGraph(
|
||||||
settingsViewModel: SettingsViewModel,
|
|
||||||
themmoController: ThemmoController,
|
themmoController: ThemmoController,
|
||||||
navController: NavHostController,
|
navController: NavHostController,
|
||||||
menuButtonClick: () -> Unit
|
menuButtonClick: () -> Unit
|
||||||
@ -57,37 +55,34 @@ fun NavGraphBuilder.settingGraph(
|
|||||||
navigation(settingsRoute, settingsGraph) {
|
navigation(settingsRoute, settingsGraph) {
|
||||||
composable(settingsRoute) {
|
composable(settingsRoute) {
|
||||||
SettingsScreen(
|
SettingsScreen(
|
||||||
viewModel = settingsViewModel,
|
menuButtonClick = menuButtonClick,
|
||||||
menuButtonClick = menuButtonClick
|
navControllerAction = navController::navigate
|
||||||
) { route -> navController.navigate(route) }
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
composable(themesRoute) {
|
composable(themesRoute) {
|
||||||
ThemesRoute(
|
ThemesRoute(
|
||||||
navigateUpAction = { navController.navigateUp() },
|
navigateUpAction = navController::navigateUp,
|
||||||
themmoController = themmoController,
|
themmoController = themmoController,
|
||||||
viewModel = settingsViewModel
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
composable(thirdPartyRoute) {
|
composable(thirdPartyRoute) {
|
||||||
ThirdPartyLicensesScreen(
|
ThirdPartyLicensesScreen(
|
||||||
navigateUpAction = { navController.navigateUp() }
|
navigateUpAction = navController::navigateUp,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
composable(aboutRoute) {
|
composable(aboutRoute) {
|
||||||
AboutScreen(
|
AboutScreen(
|
||||||
navigateUpAction = { navController.navigateUp() },
|
navigateUpAction = navController::navigateUp,
|
||||||
navigateToThirdParty = { navController.navigate(thirdPartyRoute) },
|
navigateToThirdParty = { navController.navigate(thirdPartyRoute) },
|
||||||
viewModel = settingsViewModel
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
composable(unitsGroupRoute) {
|
composable(unitsGroupRoute) {
|
||||||
UnitGroupsScreen(
|
UnitGroupsScreen(
|
||||||
viewModel = settingsViewModel,
|
navigateUpAction = navController::navigateUp,
|
||||||
navigateUpAction = { navController.navigateUp() }
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.sadellie.unitto.feature.settings
|
package com.sadellie.unitto.feature.settings.themes
|
||||||
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
@ -49,6 +49,7 @@ import androidx.compose.ui.graphics.Color
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import com.sadellie.unitto.core.base.R
|
import com.sadellie.unitto.core.base.R
|
||||||
import com.sadellie.unitto.core.ui.common.Header
|
import com.sadellie.unitto.core.ui.common.Header
|
||||||
import com.sadellie.unitto.core.ui.common.NavigateUpButton
|
import com.sadellie.unitto.core.ui.common.NavigateUpButton
|
||||||
@ -82,7 +83,7 @@ private val colorSchemes: List<Color> by lazy {
|
|||||||
internal fun ThemesRoute(
|
internal fun ThemesRoute(
|
||||||
navigateUpAction: () -> Unit = {},
|
navigateUpAction: () -> Unit = {},
|
||||||
themmoController: ThemmoController,
|
themmoController: ThemmoController,
|
||||||
viewModel: SettingsViewModel
|
viewModel: ThemesViewModel = hiltViewModel()
|
||||||
) {
|
) {
|
||||||
ThemesScreen(
|
ThemesScreen(
|
||||||
navigateUpAction = navigateUpAction,
|
navigateUpAction = navigateUpAction,
|
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Unitto is a unit converter for Android
|
||||||
|
* Copyright (c) 2023 Elshan Agaev
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sadellie.unitto.feature.settings.themes
|
||||||
|
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import io.github.sadellie.themmo.MonetMode
|
||||||
|
import io.github.sadellie.themmo.ThemingMode
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
class ThemesViewModel @Inject constructor(
|
||||||
|
private val userPrefsRepository: UserPreferencesRepository
|
||||||
|
) : ViewModel() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see UserPreferencesRepository.updateThemingMode
|
||||||
|
*/
|
||||||
|
fun updateThemingMode(themingMode: ThemingMode) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
userPrefsRepository.updateThemingMode(themingMode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see UserPreferencesRepository.updateDynamicTheme
|
||||||
|
*/
|
||||||
|
fun updateDynamicTheme(enabled: Boolean) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
userPrefsRepository.updateDynamicTheme(enabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see UserPreferencesRepository.updateAmoledTheme
|
||||||
|
*/
|
||||||
|
fun updateAmoledTheme(enabled: Boolean) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
userPrefsRepository.updateAmoledTheme(enabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see UserPreferencesRepository.updateCustomColor
|
||||||
|
*/
|
||||||
|
fun updateCustomColor(color: Color) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
userPrefsRepository.updateCustomColor(color)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see UserPreferencesRepository.updateMonetMode
|
||||||
|
*/
|
||||||
|
fun updateMonetMode(monetMode: MonetMode) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
userPrefsRepository.updateMonetMode(monetMode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,7 +16,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.sadellie.unitto.feature.settings
|
package com.sadellie.unitto.feature.settings.unitgroups
|
||||||
|
|
||||||
import androidx.compose.animation.animateColor
|
import androidx.compose.animation.animateColor
|
||||||
import androidx.compose.animation.core.animateDp
|
import androidx.compose.animation.core.animateDp
|
||||||
@ -40,13 +40,14 @@ import androidx.compose.material3.ListItemDefaults
|
|||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.sadellie.unitto.core.base.R
|
import com.sadellie.unitto.core.base.R
|
||||||
import com.sadellie.unitto.core.ui.common.Header
|
import com.sadellie.unitto.core.ui.common.Header
|
||||||
import com.sadellie.unitto.core.ui.common.NavigateUpButton
|
import com.sadellie.unitto.core.ui.common.NavigateUpButton
|
||||||
@ -59,21 +60,20 @@ import org.burnoutcrew.reorderable.reorderable
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun UnitGroupsScreen(
|
internal fun UnitGroupsScreen(
|
||||||
viewModel: SettingsViewModel,
|
viewModel: UnitGroupsViewModel = hiltViewModel(),
|
||||||
navigateUpAction: () -> Unit
|
navigateUpAction: () -> Unit
|
||||||
) {
|
) {
|
||||||
|
val uiState = viewModel.uiState.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
UnittoScreenWithLargeTopBar(
|
UnittoScreenWithLargeTopBar(
|
||||||
title = stringResource(R.string.unit_groups_setting),
|
title = stringResource(R.string.unit_groups_setting),
|
||||||
navigationIcon = { NavigateUpButton(navigateUpAction) }
|
navigationIcon = { NavigateUpButton(navigateUpAction) }
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
|
|
||||||
val shownUnits = viewModel.shownUnitGroups.collectAsState()
|
|
||||||
val hiddenUnits = viewModel.hiddenUnitGroups.collectAsState()
|
|
||||||
|
|
||||||
val state = rememberReorderableLazyListState(
|
val state = rememberReorderableLazyListState(
|
||||||
onMove = viewModel::onMove,
|
onMove = viewModel::moveShownUnitGroups,
|
||||||
canDragOver = { from, _ -> viewModel.canDragOver(from) },
|
canDragOver = { from, _ -> viewModel.canDragOver(from) },
|
||||||
onDragEnd = { _, _ -> viewModel.onDragEnd() }
|
onDragEnd = { _, _ -> viewModel.saveShownUnitGroups() }
|
||||||
)
|
)
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
@ -89,7 +89,7 @@ internal fun UnitGroupsScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
items(shownUnits.value, { it }) { item ->
|
items(uiState.value.shownGroups, { it }) { item ->
|
||||||
ReorderableItem(state, key = item) { isDragging ->
|
ReorderableItem(state, key = item) { isDragging ->
|
||||||
val transition = updateTransition(isDragging, label = "draggedTransition")
|
val transition = updateTransition(isDragging, label = "draggedTransition")
|
||||||
val background by transition.animateColor(label = "background") {
|
val background by transition.animateColor(label = "background") {
|
||||||
@ -104,7 +104,7 @@ internal fun UnitGroupsScreen(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(horizontal = itemPadding)
|
.padding(horizontal = itemPadding)
|
||||||
.clip(CircleShape)
|
.clip(CircleShape)
|
||||||
.clickable { viewModel.hideUnitGroup(item) }
|
.clickable { viewModel.markUnitGroupAsHidden(item) }
|
||||||
.detectReorderAfterLongPress(state),
|
.detectReorderAfterLongPress(state),
|
||||||
colors = ListItemDefaults.colors(
|
colors = ListItemDefaults.colors(
|
||||||
containerColor = background
|
containerColor = background
|
||||||
@ -117,7 +117,7 @@ internal fun UnitGroupsScreen(
|
|||||||
modifier = Modifier.clickable(
|
modifier = Modifier.clickable(
|
||||||
interactionSource = remember { MutableInteractionSource() },
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
indication = rememberRipple(false),
|
indication = rememberRipple(false),
|
||||||
onClick = { viewModel.hideUnitGroup(item) }
|
onClick = { viewModel.markUnitGroupAsHidden(item) }
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -147,11 +147,11 @@ internal fun UnitGroupsScreen(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
items(hiddenUnits.value, { it }) {
|
items(uiState.value.hiddenGroups, { it }) {
|
||||||
ListItem(
|
ListItem(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.background(MaterialTheme.colorScheme.surface)
|
.background(MaterialTheme.colorScheme.surface)
|
||||||
.clickable { viewModel.returnUnitGroup(it) }
|
.clickable { viewModel.markUnitGroupAsShown(it) }
|
||||||
.animateItemPlacement(),
|
.animateItemPlacement(),
|
||||||
headlineContent = { Text(stringResource(it.res)) },
|
headlineContent = { Text(stringResource(it.res)) },
|
||||||
trailingContent = {
|
trailingContent = {
|
||||||
@ -162,7 +162,7 @@ internal fun UnitGroupsScreen(
|
|||||||
modifier = Modifier.clickable(
|
modifier = Modifier.clickable(
|
||||||
interactionSource = remember { MutableInteractionSource() },
|
interactionSource = remember { MutableInteractionSource() },
|
||||||
indication = rememberRipple(false),
|
indication = rememberRipple(false),
|
||||||
onClick = { viewModel.returnUnitGroup(it) }
|
onClick = { viewModel.markUnitGroupAsShown(it) }
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Unitto is a unit converter for Android
|
||||||
|
* Copyright (c) 2023 Elshan Agaev
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sadellie.unitto.feature.settings.unitgroups
|
||||||
|
|
||||||
|
import com.sadellie.unitto.data.model.UnitGroup
|
||||||
|
|
||||||
|
data class UnitGroupsUIState(
|
||||||
|
val shownGroups: List<UnitGroup>,
|
||||||
|
val hiddenGroups: List<UnitGroup>
|
||||||
|
)
|
@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
* Unitto is a unit converter for Android
|
||||||
|
* Copyright (c) 2023 Elshan Agaev
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sadellie.unitto.feature.settings.unitgroups
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.sadellie.unitto.data.model.ALL_UNIT_GROUPS
|
||||||
|
import com.sadellie.unitto.data.model.UnitGroup
|
||||||
|
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
|
||||||
|
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 kotlinx.coroutines.sync.Mutex
|
||||||
|
import kotlinx.coroutines.sync.withLock
|
||||||
|
import org.burnoutcrew.reorderable.ItemPosition
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
class UnitGroupsViewModel @Inject constructor(
|
||||||
|
private val userPreferencesRepository: UserPreferencesRepository,
|
||||||
|
) : ViewModel() {
|
||||||
|
|
||||||
|
private var mutex: Mutex = Mutex()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Currently shown [UnitGroup]s.
|
||||||
|
*/
|
||||||
|
private val _shownUnitGroups = MutableStateFlow(listOf<UnitGroup>())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Currently hidden [UnitGroup]s.
|
||||||
|
*/
|
||||||
|
private val _hiddenUnitGroups = MutableStateFlow(listOf<UnitGroup>())
|
||||||
|
|
||||||
|
init {
|
||||||
|
viewModelScope.launch {
|
||||||
|
val shown = userPreferencesRepository.mainPreferencesFlow.first().shownUnitGroups
|
||||||
|
mutex.withLock {
|
||||||
|
_shownUnitGroups.update { shown }
|
||||||
|
_hiddenUnitGroups.update { ALL_UNIT_GROUPS - shown.toSet() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val uiState = combine(_shownUnitGroups, _hiddenUnitGroups) { shown, hidden ->
|
||||||
|
return@combine UnitGroupsUIState(
|
||||||
|
shownGroups = shown,
|
||||||
|
hiddenGroups = hidden
|
||||||
|
)
|
||||||
|
}.stateIn(
|
||||||
|
viewModelScope,
|
||||||
|
SharingStarted.WhileSubscribed(5000L),
|
||||||
|
UnitGroupsUIState(emptyList(), emptyList())
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves [UnitGroup] from [_shownUnitGroups] to [_hiddenUnitGroups]
|
||||||
|
*
|
||||||
|
* @param unitGroup [UnitGroup] to hide.
|
||||||
|
*/
|
||||||
|
fun markUnitGroupAsHidden(unitGroup: UnitGroup) = viewModelScope.launch {
|
||||||
|
mutex.withLock {
|
||||||
|
_shownUnitGroups.update { it - unitGroup }
|
||||||
|
// Newly hidden unit will appear at the top of the list
|
||||||
|
_hiddenUnitGroups.update { listOf(unitGroup) + it }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves [UnitGroup] from [_hiddenUnitGroups] to [_shownUnitGroups]
|
||||||
|
*
|
||||||
|
* @param unitGroup [UnitGroup] to show.
|
||||||
|
*/
|
||||||
|
fun markUnitGroupAsShown(unitGroup: UnitGroup) = viewModelScope.launch {
|
||||||
|
mutex.withLock {
|
||||||
|
_hiddenUnitGroups.update { it - unitGroup }
|
||||||
|
_shownUnitGroups.update { it + unitGroup }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves [UnitGroup] in [_shownUnitGroups] from one index to another (reorder).
|
||||||
|
*
|
||||||
|
* @param from Position from which we need to move from
|
||||||
|
* @param to Position where to put [UnitGroup]
|
||||||
|
*/
|
||||||
|
fun moveShownUnitGroups(from: ItemPosition, to: ItemPosition) = viewModelScope.launch {
|
||||||
|
mutex.withLock {
|
||||||
|
_shownUnitGroups.update { shown ->
|
||||||
|
shown.toMutableList().apply {
|
||||||
|
val initialIndex = shown.indexOfFirst { it == from.key }
|
||||||
|
/**
|
||||||
|
* No such item. Happens when dragging item and clicking "remove" while item is
|
||||||
|
* still being dragged.
|
||||||
|
*/
|
||||||
|
if (initialIndex == -1) return@launch
|
||||||
|
|
||||||
|
add(
|
||||||
|
shown.indexOfFirst { it == to.key },
|
||||||
|
removeAt(initialIndex)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun canDragOver(pos: ItemPosition) = uiState.value.shownGroups.any { it == pos.key }
|
||||||
|
|
||||||
|
fun saveShownUnitGroups() = viewModelScope.launch {
|
||||||
|
userPreferencesRepository.updateShownUnitGroups(
|
||||||
|
uiState.value.shownGroups
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -26,9 +26,8 @@ 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.MainPreferences
|
||||||
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
|
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
|
||||||
@ -48,33 +47,30 @@ class UnitsListViewModel @Inject constructor(
|
|||||||
private val allUnitsRepository: AllUnitsRepository,
|
private val allUnitsRepository: AllUnitsRepository,
|
||||||
private val mContext: Application,
|
private val mContext: Application,
|
||||||
private val userPrefsRepository: UserPreferencesRepository,
|
private val userPrefsRepository: UserPreferencesRepository,
|
||||||
unitGroupsRepository: UnitGroupsRepository,
|
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
private val _userPrefs: StateFlow<UserPreferences> =
|
private val _userPrefs: StateFlow<MainPreferences> =
|
||||||
userPrefsRepository.userPreferencesFlow.stateIn(
|
userPrefsRepository.mainPreferencesFlow.stateIn(
|
||||||
viewModelScope,
|
viewModelScope,
|
||||||
SharingStarted.WhileSubscribed(5000L),
|
SharingStarted.WhileSubscribed(5000L),
|
||||||
UserPreferences()
|
MainPreferences()
|
||||||
)
|
)
|
||||||
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
|
|
||||||
|
|
||||||
val mainFlow = combine(
|
val mainFlow = combine(
|
||||||
_userPrefs,
|
_userPrefs,
|
||||||
_unitsToShow,
|
_unitsToShow,
|
||||||
_searchQuery,
|
_searchQuery,
|
||||||
_chosenUnitGroup,
|
_chosenUnitGroup,
|
||||||
_shownUnitGroups,
|
) { userPrefs, unitsToShow, searchQuery, chosenUnitGroup ->
|
||||||
) { userPrefs, unitsToShow, searchQuery, chosenUnitGroup, shownUnitGroups ->
|
|
||||||
return@combine SecondScreenUIState(
|
return@combine SecondScreenUIState(
|
||||||
favoritesOnly = userPrefs.unitConverterFavoritesOnly,
|
favoritesOnly = userPrefs.unitConverterFavoritesOnly,
|
||||||
unitsToShow = unitsToShow,
|
unitsToShow = unitsToShow,
|
||||||
searchQuery = searchQuery,
|
searchQuery = searchQuery,
|
||||||
chosenUnitGroup = chosenUnitGroup,
|
chosenUnitGroup = chosenUnitGroup,
|
||||||
shownUnitGroups = shownUnitGroups,
|
shownUnitGroups = userPrefs.shownUnitGroups,
|
||||||
formatterSymbols = AllFormatterSymbols.getById(userPrefs.separator)
|
formatterSymbols = AllFormatterSymbols.getById(userPrefs.separator)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -136,7 +132,7 @@ class UnitsListViewModel @Inject constructor(
|
|||||||
chosenUnitGroup = _chosenUnitGroup.value,
|
chosenUnitGroup = _chosenUnitGroup.value,
|
||||||
favoritesOnly = _userPrefs.value.unitConverterFavoritesOnly,
|
favoritesOnly = _userPrefs.value.unitConverterFavoritesOnly,
|
||||||
searchQuery = _searchQuery.value,
|
searchQuery = _searchQuery.value,
|
||||||
allUnitsGroups = _shownUnitGroups.value,
|
allUnitsGroups = _userPrefs.value.shownUnitGroups,
|
||||||
sorting = _userPrefs.value.unitConverterSorting
|
sorting = _userPrefs.value.unitConverterSorting
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user