Improve testability

- Use interfaces to mock objects
- Use only primitives in preferences
This commit is contained in:
Sad Ellie 2023-10-31 00:25:08 +03:00
parent e42fd625a5
commit 1475e5a948
39 changed files with 736 additions and 171 deletions

View File

@ -35,7 +35,7 @@ import com.sadellie.unitto.core.ui.LocalLocale
import com.sadellie.unitto.core.ui.theme.LocalNumberTypography
import com.sadellie.unitto.core.ui.theme.NumberTypographySystem
import com.sadellie.unitto.core.ui.theme.NumberTypographyUnitto
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
import dagger.hilt.android.AndroidEntryPoint
import java.util.Locale
import javax.inject.Inject

View File

@ -49,7 +49,9 @@ import com.sadellie.unitto.core.ui.pushDynamicShortcut
import com.sadellie.unitto.core.ui.theme.DarkThemeColors
import com.sadellie.unitto.core.ui.theme.LightThemeColors
import com.sadellie.unitto.core.ui.theme.TypographySystem
import com.sadellie.unitto.data.userprefs.AppPreferences
import com.sadellie.unitto.data.model.userprefs.AppPreferences
import io.github.sadellie.themmo.MonetMode
import io.github.sadellie.themmo.ThemingMode
import io.github.sadellie.themmo.Themmo
import io.github.sadellie.themmo.ThemmoController
import kotlinx.coroutines.launch
@ -80,11 +82,11 @@ internal fun UnittoApp(prefs: AppPreferences?) {
ThemmoController(
lightColorScheme = LightThemeColors,
darkColorScheme = DarkThemeColors,
themingMode = prefs.themingMode,
themingMode = prefs.themingMode.toThemingMode(),
dynamicThemeEnabled = prefs.enableDynamicTheme,
amoledThemeEnabled = prefs.enableAmoledTheme,
customColor = prefs.customColor,
monetMode = prefs.monetMode
customColor = prefs.customColor.toColor(),
monetMode = prefs.monetMode.toMonetMode()
)
}
@ -150,3 +152,21 @@ internal fun UnittoApp(prefs: AppPreferences?) {
drawerScope.launch { drawerState.close() }
}
}
private fun String.toThemingMode(): ThemingMode = try {
ThemingMode.valueOf(this)
} catch (e: Exception) {
ThemingMode.AUTO
}
private fun String.toMonetMode(): MonetMode = try {
MonetMode.valueOf(this)
} catch (e: Exception) {
MonetMode.TonalSpot
}
private fun Long.toColor(): Color = try {
Color(this.toULong())
} catch (e: Exception) {
Color.Unspecified
}

View File

@ -21,25 +21,26 @@ package com.sadellie.unitto.data.calculator
import com.sadellie.unitto.data.database.CalculatorHistoryDao
import com.sadellie.unitto.data.database.CalculatorHistoryEntity
import com.sadellie.unitto.data.model.HistoryItem
import com.sadellie.unitto.data.model.repository.CalculatorHistoryRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import java.util.*
import java.util.Date
import javax.inject.Inject
class CalculatorHistoryRepository @Inject constructor(
class CalculatorHistoryRepositoryImpl @Inject constructor(
private val calculatorHistoryDao: CalculatorHistoryDao
) {
) : CalculatorHistoryRepository {
/**
* Calculator history sorted by [CalculatorHistoryEntity.timestamp] from new to old (DESC).
*/
val historyFlow: Flow<List<HistoryItem>> = calculatorHistoryDao
override val historyFlow: Flow<List<HistoryItem>> = calculatorHistoryDao
.getAllDescending()
.map { it.toHistoryItemList() }
.flowOn(Dispatchers.IO)
suspend fun add(
override suspend fun add(
expression: String,
result: String
) {
@ -52,7 +53,7 @@ class CalculatorHistoryRepository @Inject constructor(
)
}
suspend fun clear() {
override suspend fun clear() {
calculatorHistoryDao.clear()
}

View File

@ -0,0 +1,35 @@
/*
* 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.data.calculator
import com.sadellie.unitto.data.database.CalculatorHistoryDao
import com.sadellie.unitto.data.model.repository.CalculatorHistoryRepository
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
@Module
@InstallIn(SingletonComponent::class)
class DataStoreModule {
@Provides
fun provideCalculatorHistoryRepository(calculatorHistoryDao: CalculatorHistoryDao): CalculatorHistoryRepository {
return CalculatorHistoryRepositoryImpl(calculatorHistoryDao)
}
}

View File

@ -0,0 +1,33 @@
/*
* 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.data.model.repository
import com.sadellie.unitto.data.model.HistoryItem
import kotlinx.coroutines.flow.Flow
interface CalculatorHistoryRepository {
val historyFlow: Flow<List<HistoryItem>>
suspend fun add(
expression: String,
result: String
)
suspend fun clear()
}

View File

@ -0,0 +1,50 @@
/*
* 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.data.model.repository
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.UnitsListSorting
import com.sadellie.unitto.data.model.unit.AbstractUnit
import kotlinx.coroutines.flow.Flow
import java.time.LocalDate
interface UnitsRepository {
val allUnits: Flow<List<AbstractUnit>>
suspend fun getById(id: String): AbstractUnit
suspend fun getCollection(group: UnitGroup): List<AbstractUnit>
suspend fun favorite(unit: AbstractUnit)
suspend fun incrementCounter(unit: AbstractUnit)
suspend fun setPair(unit: AbstractUnit, pair: AbstractUnit)
suspend fun updateRates(unit: AbstractUnit): LocalDate?
suspend fun filterUnits(
query: String,
unitGroup: UnitGroup?,
favoritesOnly: Boolean,
hideBrokenUnits: Boolean,
sorting: UnitsListSorting,
shownUnitGroups: List<UnitGroup> = emptyList(),
): Map<UnitGroup, List<AbstractUnit>>
}

View File

@ -0,0 +1,89 @@
/*
* 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.data.model.repository
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.UnitsListSorting
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.userprefs.AboutPreferences
import com.sadellie.unitto.data.model.userprefs.AddSubtractPreferences
import com.sadellie.unitto.data.model.userprefs.AppPreferences
import com.sadellie.unitto.data.model.userprefs.CalculatorPreferences
import com.sadellie.unitto.data.model.userprefs.ConverterPreferences
import com.sadellie.unitto.data.model.userprefs.DisplayPreferences
import com.sadellie.unitto.data.model.userprefs.FormattingPreferences
import com.sadellie.unitto.data.model.userprefs.GeneralPreferences
import com.sadellie.unitto.data.model.userprefs.StartingScreenPreferences
import com.sadellie.unitto.data.model.userprefs.UnitGroupsPreferences
import kotlinx.coroutines.flow.Flow
interface UserPreferencesRepository {
val appPrefs: Flow<AppPreferences>
val generalPrefs: Flow<GeneralPreferences>
val calculatorPrefs: Flow<CalculatorPreferences>
val converterPrefs: Flow<ConverterPreferences>
val displayPrefs: Flow<DisplayPreferences>
val formattingPrefs: Flow<FormattingPreferences>
val unitGroupsPrefs: Flow<UnitGroupsPreferences>
val addSubtractPrefs: Flow<AddSubtractPreferences>
val aboutPrefs: Flow<AboutPreferences>
val startingScreenPrefs: Flow<StartingScreenPreferences>
suspend fun updateDigitsPrecision(precision: Int)
suspend fun updateSeparator(separator: Int)
suspend fun updateOutputFormat(outputFormat: Int)
suspend fun updateLatestPairOfUnits(unitFrom: AbstractUnit, unitTo: AbstractUnit)
suspend fun updateThemingMode(themingMode: String)
suspend fun updateDynamicTheme(enabled: Boolean)
suspend fun updateAmoledTheme(enabled: Boolean)
suspend fun updateCustomColor(color: Long)
suspend fun updateMonetMode(monetMode: String)
suspend fun updateStartingScreen(startingScreen: String)
suspend fun updateShownUnitGroups(shownUnitGroups: List<UnitGroup>)
suspend fun updateVibrations(enabled: Boolean)
suspend fun updateMiddleZero(enabled: Boolean)
suspend fun updateToolsExperiment(enabled: Boolean)
suspend fun updateRadianMode(radianMode: Boolean)
suspend fun updateUnitConverterFavoritesOnly(enabled: Boolean)
suspend fun updateUnitConverterFormatTime(enabled: Boolean)
suspend fun updateUnitConverterSorting(sorting: UnitsListSorting)
suspend fun updateSystemFont(enabled: Boolean)
suspend fun updatePartialHistoryView(enabled: Boolean)
suspend fun updateAcButton(enabled: Boolean)
}

View File

@ -0,0 +1,23 @@
/*
* 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.data.model.userprefs
interface AboutPreferences{
val enableToolsExperiment: Boolean
}

View File

@ -0,0 +1,24 @@
/*
* 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.data.model.userprefs
interface AddSubtractPreferences{
val separator: Int
val enableVibrations: Boolean
}

View File

@ -0,0 +1,30 @@
/*
* 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.data.model.userprefs
interface AppPreferences {
val themingMode: String
val enableDynamicTheme: Boolean
val enableAmoledTheme: Boolean
val customColor: Long
val monetMode: String
val startingScreen: String
val enableToolsExperiment: Boolean
val systemFont: Boolean
}

View File

@ -0,0 +1,30 @@
/*
* 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.data.model.userprefs
interface CalculatorPreferences {
val radianMode: Boolean
val enableVibrations: Boolean
val separator: Int
val middleZero: Boolean
val acButton: Boolean
val partialHistoryView: Boolean
val precision: Int
val outputFormat: Int
}

View File

@ -0,0 +1,38 @@
/*
* 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.data.model.userprefs
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.UnitsListSorting
interface ConverterPreferences {
val enableVibrations: Boolean
val separator: Int
val middleZero: Boolean
val acButton: Boolean
val precision: Int
val outputFormat: Int
val unitConverterFormatTime: Boolean
val unitConverterSorting: UnitsListSorting
val shownUnitGroups: List<UnitGroup>
val unitConverterFavoritesOnly: Boolean
val enableToolsExperiment: Boolean
val latestLeftSideUnit: String
val latestRightSideUnit: String
}

View File

@ -0,0 +1,25 @@
/*
* 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.data.model.userprefs
interface DisplayPreferences {
val systemFont: Boolean
val middleZero: Boolean
val acButton: Boolean
}

View File

@ -0,0 +1,25 @@
/*
* 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.data.model.userprefs
interface FormattingPreferences{
val digitsPrecision: Int
val separator: Int
val outputFormat: Int
}

View File

@ -0,0 +1,23 @@
/*
* 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.data.model.userprefs
interface GeneralPreferences {
val enableVibrations: Boolean
}

View File

@ -0,0 +1,23 @@
/*
* 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.data.model.userprefs
interface StartingScreenPreferences{
val startingScreen: String
}

View File

@ -0,0 +1,25 @@
/*
* 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.data.model.userprefs
import com.sadellie.unitto.data.model.UnitGroup
interface UnitGroupsPreferences{
val shownUnitGroups: List<UnitGroup>
}

View File

@ -0,0 +1,46 @@
/*
* 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.data.units
import android.content.Context
import com.sadellie.unitto.data.database.CurrencyRatesDao
import com.sadellie.unitto.data.database.UnitsDao
import com.sadellie.unitto.data.model.repository.UnitsRepository
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
@Module
@InstallIn(SingletonComponent::class)
class DataStoreModule {
@Provides
fun provideUnitsRepository(
unitsDao: UnitsDao,
currencyRatesDao: CurrencyRatesDao,
@ApplicationContext appContext: Context
): UnitsRepository {
return UnitsRepositoryImpl(
unitsDao = unitsDao,
currencyRatesDao = currencyRatesDao,
mContext = appContext
)
}
}

View File

@ -26,6 +26,7 @@ import com.sadellie.unitto.data.database.UnitsDao
import com.sadellie.unitto.data.database.UnitsEntity
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.UnitsListSorting
import com.sadellie.unitto.data.model.repository.UnitsRepository
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.ReverseUnit
import com.sadellie.unitto.data.model.unit.filterByLev
@ -67,11 +68,11 @@ import java.math.BigDecimal
import java.time.LocalDate
import javax.inject.Inject
class UnitsRepository @Inject constructor(
class UnitsRepositoryImpl @Inject constructor(
private val unitsDao: UnitsDao,
private val currencyRatesDao: CurrencyRatesDao,
@ApplicationContext private val mContext: Context,
) {
) : UnitsRepository {
private val myUnits = MutableStateFlow(
lengthCollection +
currencyCollection +
@ -99,7 +100,7 @@ class UnitsRepository @Inject constructor(
fuelConsumptionCollection
)
val allUnits: Flow<List<AbstractUnit>> = combine(
override val allUnits: Flow<List<AbstractUnit>> = combine(
unitsDao.getAllFlow(),
myUnits
) { basedList, inMemoryList ->
@ -115,15 +116,15 @@ class UnitsRepository @Inject constructor(
}
.flowOn(Dispatchers.IO)
suspend fun getById(id: String): AbstractUnit {
override suspend fun getById(id: String): AbstractUnit {
return allUnits.first().first { it.id == id }
}
suspend fun getCollection(group: UnitGroup): List<AbstractUnit> {
override suspend fun getCollection(group: UnitGroup): List<AbstractUnit> {
return allUnits.first().filter { it.group == group }
}
suspend fun favorite(unit: AbstractUnit) = withContext(Dispatchers.IO) {
override suspend fun favorite(unit: AbstractUnit) = withContext(Dispatchers.IO) {
val basedUnit = unitsDao.getById(unit.id)
if (basedUnit == null) {
@ -145,7 +146,7 @@ class UnitsRepository @Inject constructor(
}
}
suspend fun incrementCounter(unit: AbstractUnit) = withContext(Dispatchers.IO) {
override suspend fun incrementCounter(unit: AbstractUnit) = withContext(Dispatchers.IO) {
val basedUnit = unitsDao.getById(unit.id)
if (basedUnit == null) {
@ -167,7 +168,7 @@ class UnitsRepository @Inject constructor(
}
}
suspend fun setPair(unit: AbstractUnit, pair: AbstractUnit) = withContext(Dispatchers.IO) {
override suspend fun setPair(unit: AbstractUnit, pair: AbstractUnit) = withContext(Dispatchers.IO) {
val basedUnit = unitsDao.getById(unit.id)
if (basedUnit == null) {
@ -189,7 +190,7 @@ class UnitsRepository @Inject constructor(
}
}
suspend fun updateRates(unit: AbstractUnit): LocalDate? = withContext(Dispatchers.IO) {
override suspend fun updateRates(unit: AbstractUnit): LocalDate? = withContext(Dispatchers.IO) {
var basedConversions = currencyRatesDao.getLatestRates(baseId = unit.id)
val epochDay = LocalDate.now().toEpochDay()
@ -235,13 +236,13 @@ class UnitsRepository @Inject constructor(
?.let { LocalDate.ofEpochDay(it) }
}
suspend fun filterUnits(
override suspend fun filterUnits(
query: String,
unitGroup: UnitGroup?,
favoritesOnly: Boolean,
hideBrokenUnits: Boolean,
sorting: UnitsListSorting,
shownUnitGroups: List<UnitGroup> = emptyList(),
shownUnitGroups: List<UnitGroup>,
): Map<UnitGroup, List<AbstractUnit>> {
// Leave only shown unit groups
var units: Sequence<AbstractUnit> = if (unitGroup == null) {

View File

@ -25,6 +25,7 @@ import androidx.datastore.preferences.core.PreferenceDataStoreFactory
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.emptyPreferences
import androidx.datastore.preferences.preferencesDataStoreFile
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@ -55,4 +56,9 @@ class DataStoreModule {
produceFile = { appContext.preferencesDataStoreFile(USER_PREFERENCES) }
)
}
@Provides
fun provideUserPreferencesRepository(dataStore: DataStore<Preferences>): UserPreferencesRepository {
return UserPreferencesRepositoryImpl(dataStore)
}
}

View File

@ -18,80 +18,88 @@
package com.sadellie.unitto.data.userprefs
import androidx.compose.ui.graphics.Color
import com.sadellie.unitto.data.model.ALL_UNIT_GROUPS
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.UnitsListSorting
import io.github.sadellie.themmo.MonetMode
import io.github.sadellie.themmo.ThemingMode
import com.sadellie.unitto.data.model.userprefs.AboutPreferences
import com.sadellie.unitto.data.model.userprefs.AddSubtractPreferences
import com.sadellie.unitto.data.model.userprefs.AppPreferences
import com.sadellie.unitto.data.model.userprefs.CalculatorPreferences
import com.sadellie.unitto.data.model.userprefs.ConverterPreferences
import com.sadellie.unitto.data.model.userprefs.DisplayPreferences
import com.sadellie.unitto.data.model.userprefs.FormattingPreferences
import com.sadellie.unitto.data.model.userprefs.GeneralPreferences
import com.sadellie.unitto.data.model.userprefs.StartingScreenPreferences
import com.sadellie.unitto.data.model.userprefs.UnitGroupsPreferences
data class AppPreferences(
val themingMode: ThemingMode,
val enableDynamicTheme: Boolean,
val enableAmoledTheme: Boolean,
val customColor: Color,
val monetMode: MonetMode,
val startingScreen: String,
val enableToolsExperiment: Boolean,
val systemFont: Boolean,
)
data class AppPreferencesImpl(
override val themingMode: String,
override val enableDynamicTheme: Boolean,
override val enableAmoledTheme: Boolean,
override val customColor: Long,
override val monetMode: String,
override val startingScreen: String,
override val enableToolsExperiment: Boolean,
override val systemFont: Boolean,
) : AppPreferences
data class GeneralPreferences(
val enableVibrations: Boolean,
)
data class CalculatorPreferences(
val radianMode: Boolean,
val enableVibrations: Boolean,
val separator: Int,
val middleZero: Boolean,
val acButton: Boolean,
val partialHistoryView: Boolean,
val precision: Int,
val outputFormat: Int,
)
data class GeneralPreferencesImpl(
override val enableVibrations: Boolean,
) : GeneralPreferences
data class ConverterPreferences(
val enableVibrations: Boolean,
val separator: Int,
val middleZero: Boolean,
val acButton: Boolean,
val precision: Int,
val outputFormat: Int,
val unitConverterFormatTime: Boolean,
val unitConverterSorting: UnitsListSorting,
val shownUnitGroups: List<UnitGroup>,
val unitConverterFavoritesOnly: Boolean,
val enableToolsExperiment: Boolean,
val latestLeftSideUnit: String,
val latestRightSideUnit: String,
)
data class CalculatorPreferencesImpl(
override val radianMode: Boolean,
override val enableVibrations: Boolean,
override val separator: Int,
override val middleZero: Boolean,
override val acButton: Boolean,
override val partialHistoryView: Boolean,
override val precision: Int,
override val outputFormat: Int,
) : CalculatorPreferences
data class DisplayPreferences(
val systemFont: Boolean,
val middleZero: Boolean,
val acButton: Boolean,
)
data class ConverterPreferencesImpl(
override val enableVibrations: Boolean,
override val separator: Int,
override val middleZero: Boolean,
override val acButton: Boolean,
override val precision: Int,
override val outputFormat: Int,
override val unitConverterFormatTime: Boolean,
override val unitConverterSorting: UnitsListSorting,
override val shownUnitGroups: List<UnitGroup>,
override val unitConverterFavoritesOnly: Boolean,
override val enableToolsExperiment: Boolean,
override val latestLeftSideUnit: String,
override val latestRightSideUnit: String,
) : ConverterPreferences
data class FormattingPreferences(
val digitsPrecision: Int,
val separator: Int,
val outputFormat: Int,
)
data class DisplayPreferencesImpl(
override val systemFont: Boolean,
override val middleZero: Boolean,
override val acButton: Boolean,
) : DisplayPreferences
data class UnitGroupsPreferences(
val shownUnitGroups: List<UnitGroup> = ALL_UNIT_GROUPS,
)
data class FormattingPreferencesImpl(
override val digitsPrecision: Int,
override val separator: Int,
override val outputFormat: Int,
) : FormattingPreferences
data class AddSubtractPreferences(
val separator: Int,
val enableVibrations: Boolean,
)
data class UnitGroupsPreferencesImpl(
override val shownUnitGroups: List<UnitGroup> = ALL_UNIT_GROUPS,
) : UnitGroupsPreferences
data class AboutPreferences(
val enableToolsExperiment: Boolean,
)
data class AddSubtractPreferencesImpl(
override val separator: Int,
override val enableVibrations: Boolean,
) : AddSubtractPreferences
data class StartingScreenPreferences(
val startingScreen: String,
)
data class AboutPreferencesImpl(
override val enableToolsExperiment: Boolean,
) : AboutPreferences
data class StartingScreenPreferencesImpl(
override val startingScreen: String,
) : StartingScreenPreferences

View File

@ -18,7 +18,6 @@
package com.sadellie.unitto.data.userprefs
import androidx.compose.ui.graphics.Color
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
@ -29,25 +28,34 @@ import com.sadellie.unitto.core.base.TopLevelDestinations
import com.sadellie.unitto.data.model.ALL_UNIT_GROUPS
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.UnitsListSorting
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.userprefs.AboutPreferences
import com.sadellie.unitto.data.model.userprefs.AddSubtractPreferences
import com.sadellie.unitto.data.model.userprefs.AppPreferences
import com.sadellie.unitto.data.model.userprefs.CalculatorPreferences
import com.sadellie.unitto.data.model.userprefs.ConverterPreferences
import com.sadellie.unitto.data.model.userprefs.DisplayPreferences
import com.sadellie.unitto.data.model.userprefs.FormattingPreferences
import com.sadellie.unitto.data.model.userprefs.GeneralPreferences
import com.sadellie.unitto.data.model.userprefs.StartingScreenPreferences
import com.sadellie.unitto.data.model.userprefs.UnitGroupsPreferences
import com.sadellie.unitto.data.units.MyUnitIDS
import io.github.sadellie.themmo.MonetMode
import io.github.sadellie.themmo.ThemingMode
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.map
import java.io.IOException
import javax.inject.Inject
class UserPreferencesRepository @Inject constructor(
class UserPreferencesRepositoryImpl @Inject constructor(
private val dataStore: DataStore<Preferences>,
) {
) : UserPreferencesRepository {
private val data = dataStore.data
.catch { if (it is IOException) emit(emptyPreferences()) else throw it }
val appPrefs: Flow<AppPreferences> = data
override val appPrefs: Flow<AppPreferences> = data
.map { preferences ->
AppPreferences(
AppPreferencesImpl(
themingMode = preferences.getThemingMode(),
enableDynamicTheme = preferences.getEnableDynamicTheme(),
enableAmoledTheme = preferences.getEnableAmoledTheme(),
@ -59,16 +67,16 @@ class UserPreferencesRepository @Inject constructor(
)
}
val generalPrefs: Flow<GeneralPreferences> = data
override val generalPrefs: Flow<GeneralPreferences> = data
.map { preferences ->
GeneralPreferences(
GeneralPreferencesImpl(
enableVibrations = preferences.getEnableVibrations(),
)
}
val calculatorPrefs: Flow<CalculatorPreferences> = data
override val calculatorPrefs: Flow<CalculatorPreferences> = data
.map { preferences ->
CalculatorPreferences(
CalculatorPreferencesImpl(
radianMode = preferences.getRadianMode(),
enableVibrations = preferences.getEnableVibrations(),
separator = preferences.getSeparator(),
@ -80,9 +88,9 @@ class UserPreferencesRepository @Inject constructor(
)
}
val converterPrefs: Flow<ConverterPreferences> = data
override val converterPrefs: Flow<ConverterPreferences> = data
.map { preferences ->
ConverterPreferences(
ConverterPreferencesImpl(
enableVibrations = preferences.getEnableVibrations(),
separator = preferences.getSeparator(),
middleZero = preferences.getMiddleZero(),
@ -99,175 +107,175 @@ class UserPreferencesRepository @Inject constructor(
)
}
val displayPrefs: Flow<DisplayPreferences> = data
override val displayPrefs: Flow<DisplayPreferences> = data
.map { preferences ->
DisplayPreferences(
DisplayPreferencesImpl(
systemFont = preferences.getSystemFont(),
middleZero = preferences.getMiddleZero(),
acButton = preferences.getAcButton(),
)
}
val formattingPrefs: Flow<FormattingPreferences> = data
override val formattingPrefs: Flow<FormattingPreferences> = data
.map { preferences ->
FormattingPreferences(
FormattingPreferencesImpl(
digitsPrecision = preferences.getDigitsPrecision(),
separator = preferences.getSeparator(),
outputFormat = preferences.getOutputFormat(),
)
}
val unitGroupsPrefs: Flow<UnitGroupsPreferences> = data
override val unitGroupsPrefs: Flow<UnitGroupsPreferences> = data
.map { preferences ->
UnitGroupsPreferences(
UnitGroupsPreferencesImpl(
shownUnitGroups = preferences.getShownUnitGroups(),
)
}
val addSubtractPrefs: Flow<AddSubtractPreferences> = data
override val addSubtractPrefs: Flow<AddSubtractPreferences> = data
.map { preferences ->
AddSubtractPreferences(
AddSubtractPreferencesImpl(
separator = preferences.getSeparator(),
enableVibrations = preferences.getEnableVibrations(),
)
}
val aboutPrefs: Flow<AboutPreferences> = data
override val aboutPrefs: Flow<AboutPreferences> = data
.map { preferences ->
AboutPreferences(
AboutPreferencesImpl(
enableToolsExperiment = preferences.getEnableToolsExperiment()
)
}
val startingScreenPrefs: Flow<StartingScreenPreferences> = data
override val startingScreenPrefs: Flow<StartingScreenPreferences> = data
.map { preferences ->
StartingScreenPreferences(
StartingScreenPreferencesImpl(
startingScreen = preferences.getStartingScreen(),
)
}
suspend fun updateDigitsPrecision(precision: Int) {
override suspend fun updateDigitsPrecision(precision: Int) {
dataStore.edit { preferences ->
preferences[PrefsKeys.DIGITS_PRECISION] = precision
}
}
suspend fun updateSeparator(separator: Int) {
override suspend fun updateSeparator(separator: Int) {
dataStore.edit { preferences ->
preferences[PrefsKeys.SEPARATOR] = separator
}
}
suspend fun updateOutputFormat(outputFormat: Int) {
override suspend fun updateOutputFormat(outputFormat: Int) {
dataStore.edit { preferences ->
preferences[PrefsKeys.OUTPUT_FORMAT] = outputFormat
}
}
suspend fun updateLatestPairOfUnits(unitFrom: AbstractUnit, unitTo: AbstractUnit) {
override suspend fun updateLatestPairOfUnits(unitFrom: AbstractUnit, unitTo: AbstractUnit) {
dataStore.edit { preferences ->
preferences[PrefsKeys.LATEST_LEFT_SIDE] = unitFrom.id
preferences[PrefsKeys.LATEST_RIGHT_SIDE] = unitTo.id
}
}
suspend fun updateThemingMode(themingMode: ThemingMode) {
override suspend fun updateThemingMode(themingMode: String) {
dataStore.edit { preferences ->
preferences[PrefsKeys.THEMING_MODE] = themingMode.name
preferences[PrefsKeys.THEMING_MODE] = themingMode
}
}
suspend fun updateDynamicTheme(enabled: Boolean) {
override suspend fun updateDynamicTheme(enabled: Boolean) {
dataStore.edit { preferences ->
preferences[PrefsKeys.ENABLE_DYNAMIC_THEME] = enabled
}
}
suspend fun updateAmoledTheme(enabled: Boolean) {
override suspend fun updateAmoledTheme(enabled: Boolean) {
dataStore.edit { preferences ->
preferences[PrefsKeys.ENABLE_AMOLED_THEME] = enabled
}
}
suspend fun updateCustomColor(color: Color) {
override suspend fun updateCustomColor(color: Long) {
dataStore.edit { preferences ->
preferences[PrefsKeys.CUSTOM_COLOR] = color.value.toLong()
preferences[PrefsKeys.CUSTOM_COLOR] = color
}
}
suspend fun updateMonetMode(monetMode: MonetMode) {
override suspend fun updateMonetMode(monetMode: String) {
dataStore.edit { preferences ->
preferences[PrefsKeys.MONET_MODE] = monetMode.name
preferences[PrefsKeys.MONET_MODE] = monetMode
}
}
suspend fun updateStartingScreen(startingScreen: String) {
override suspend fun updateStartingScreen(startingScreen: String) {
dataStore.edit { preferences ->
preferences[PrefsKeys.STARTING_SCREEN] = startingScreen
}
}
suspend fun updateShownUnitGroups(shownUnitGroups: List<UnitGroup>) {
override suspend fun updateShownUnitGroups(shownUnitGroups: List<UnitGroup>) {
dataStore.edit { preferences ->
preferences[PrefsKeys.SHOWN_UNIT_GROUPS] = shownUnitGroups.joinToString(",")
}
}
suspend fun updateVibrations(enabled: Boolean) {
override suspend fun updateVibrations(enabled: Boolean) {
dataStore.edit { preferences ->
preferences[PrefsKeys.ENABLE_VIBRATIONS] = enabled
}
}
suspend fun updateMiddleZero(enabled: Boolean) {
override suspend fun updateMiddleZero(enabled: Boolean) {
dataStore.edit { preferences ->
preferences[PrefsKeys.MIDDLE_ZERO] = enabled
}
}
suspend fun updateToolsExperiment(enabled: Boolean) {
override suspend fun updateToolsExperiment(enabled: Boolean) {
dataStore.edit { preferences ->
preferences[PrefsKeys.ENABLE_TOOLS_EXPERIMENT] = enabled
}
}
suspend fun updateRadianMode(radianMode: Boolean) {
override suspend fun updateRadianMode(radianMode: Boolean) {
dataStore.edit { preferences ->
preferences[PrefsKeys.RADIAN_MODE] = radianMode
}
}
suspend fun updateUnitConverterFavoritesOnly(enabled: Boolean) {
override suspend fun updateUnitConverterFavoritesOnly(enabled: Boolean) {
dataStore.edit { preferences ->
preferences[PrefsKeys.UNIT_CONVERTER_FAVORITES_ONLY] = enabled
}
}
suspend fun updateUnitConverterFormatTime(enabled: Boolean) {
override suspend fun updateUnitConverterFormatTime(enabled: Boolean) {
dataStore.edit { preferences ->
preferences[PrefsKeys.UNIT_CONVERTER_FORMAT_TIME] = enabled
}
}
suspend fun updateUnitConverterSorting(sorting: UnitsListSorting) {
override suspend fun updateUnitConverterSorting(sorting: UnitsListSorting) {
dataStore.edit { preferences ->
preferences[PrefsKeys.UNIT_CONVERTER_SORTING] = sorting.name
}
}
suspend fun updateSystemFont(enabled: Boolean) {
override suspend fun updateSystemFont(enabled: Boolean) {
dataStore.edit { preferences ->
preferences[PrefsKeys.SYSTEM_FONT] = enabled
}
}
suspend fun updatePartialHistoryView(enabled: Boolean) {
override suspend fun updatePartialHistoryView(enabled: Boolean) {
dataStore.edit { preferences ->
preferences[PrefsKeys.PARTIAL_HISTORY_VIEW] = enabled
}
}
suspend fun updateAcButton(enabled: Boolean) {
override suspend fun updateAcButton(enabled: Boolean) {
dataStore.edit { preferences ->
preferences[PrefsKeys.AC_BUTTON] = enabled
}
@ -278,24 +286,20 @@ private fun Preferences.getEnableDynamicTheme(): Boolean {
return this[PrefsKeys.ENABLE_DYNAMIC_THEME] ?: true
}
private fun Preferences.getThemingMode(): ThemingMode {
return this[PrefsKeys.THEMING_MODE]
?.letTryOrNull { ThemingMode.valueOf(it) }
?: ThemingMode.AUTO
private fun Preferences.getThemingMode(): String {
return this[PrefsKeys.THEMING_MODE] ?: ""
}
private fun Preferences.getEnableAmoledTheme(): Boolean {
return this[PrefsKeys.ENABLE_AMOLED_THEME] ?: false
}
private fun Preferences.getCustomColor(): Color {
return this[PrefsKeys.CUSTOM_COLOR]?.letTryOrNull { Color(it.toULong()) }
?: Color.Unspecified
private fun Preferences.getCustomColor(): Long {
return this[PrefsKeys.CUSTOM_COLOR] ?: Long.MIN_VALUE
}
private fun Preferences.getMonetMode(): MonetMode {
return this[PrefsKeys.MONET_MODE]?.letTryOrNull { MonetMode.valueOf(it) }
?: MonetMode.TonalSpot
private fun Preferences.getMonetMode(): String {
return this[PrefsKeys.MONET_MODE] ?: ""
}
private fun Preferences.getStartingScreen(): String {

View File

@ -32,13 +32,14 @@ android {
dependencies {
testImplementation(libs.junit.junit)
testImplementation(libs.org.robolectric.robolectric)
testImplementation(libs.org.jetbrains.kotlinx.kotlinx.coroutines.test)
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
debugImplementation(libs.androidx.compose.ui.test.manifest)
implementation(project(":data:common"))
implementation(project(":data:userprefs"))
implementation(project(":data:database"))
implementation(project(":data:calculator"))
implementation(project(":data:model"))
implementation(project(":data:userprefs"))
implementation(project(":data:calculator"))
implementation(project(":data:evaluatto"))
}

View File

@ -28,13 +28,13 @@ import com.sadellie.unitto.core.ui.common.textfield.AllFormatterSymbols
import com.sadellie.unitto.core.ui.common.textfield.addBracket
import com.sadellie.unitto.core.ui.common.textfield.addTokens
import com.sadellie.unitto.core.ui.common.textfield.deleteTokens
import com.sadellie.unitto.data.calculator.CalculatorHistoryRepository
import com.sadellie.unitto.data.common.isExpression
import com.sadellie.unitto.data.common.setMinimumRequiredScale
import com.sadellie.unitto.data.common.stateIn
import com.sadellie.unitto.data.common.toStringWith
import com.sadellie.unitto.data.common.trimZeros
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import com.sadellie.unitto.data.model.repository.CalculatorHistoryRepository
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import io.github.sadellie.evaluatto.Expression
import io.github.sadellie.evaluatto.ExpressionException

View File

@ -33,11 +33,11 @@ import com.sadellie.unitto.data.common.isExpression
import com.sadellie.unitto.data.common.stateIn
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.model.UnitsListSorting
import com.sadellie.unitto.data.model.repository.UnitsRepository
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
import com.sadellie.unitto.data.model.unit.AbstractUnit
import com.sadellie.unitto.data.model.unit.DefaultUnit
import com.sadellie.unitto.data.model.unit.NumberBaseUnit
import com.sadellie.unitto.data.units.UnitsRepository
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import io.github.sadellie.evaluatto.Expression
import io.github.sadellie.evaluatto.ExpressionException

View File

@ -31,5 +31,6 @@ android {
dependencies {
testImplementation(libs.junit.junit)
implementation(project(":data:model"))
implementation(project(":data:userprefs"))
}

View File

@ -23,7 +23,7 @@ import androidx.compose.ui.text.input.TextFieldValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sadellie.unitto.core.ui.common.textfield.AllFormatterSymbols
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow

View File

@ -59,7 +59,8 @@ import com.sadellie.unitto.core.ui.common.UnittoListItem
import com.sadellie.unitto.core.ui.common.UnittoScreenWithLargeTopBar
import com.sadellie.unitto.core.ui.openLink
import com.sadellie.unitto.core.ui.showToast
import com.sadellie.unitto.data.userprefs.GeneralPreferences
import com.sadellie.unitto.data.model.userprefs.GeneralPreferences
import com.sadellie.unitto.data.userprefs.GeneralPreferencesImpl
import com.sadellie.unitto.feature.settings.navigation.aboutRoute
import com.sadellie.unitto.feature.settings.navigation.calculatorSettingsRoute
import com.sadellie.unitto.feature.settings.navigation.converterSettingsRoute
@ -194,7 +195,7 @@ private fun PreviewSettingsScreen() {
var cacheSize by remember { mutableFloatStateOf(0.9f) }
SettingsScreen(
userPrefs = GeneralPreferences(
userPrefs = GeneralPreferencesImpl(
enableVibrations = true
),
navigateUp = {},

View File

@ -22,7 +22,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sadellie.unitto.data.common.stateIn
import com.sadellie.unitto.data.database.CurrencyRatesDao
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.map

View File

@ -52,7 +52,8 @@ import com.sadellie.unitto.core.ui.common.UnittoListItem
import com.sadellie.unitto.core.ui.common.UnittoScreenWithLargeTopBar
import com.sadellie.unitto.core.ui.openLink
import com.sadellie.unitto.core.ui.showToast
import com.sadellie.unitto.data.userprefs.AboutPreferences
import com.sadellie.unitto.data.model.userprefs.AboutPreferences
import com.sadellie.unitto.data.userprefs.AboutPreferencesImpl
@Composable
internal fun AboutRoute(
@ -194,7 +195,7 @@ private fun AboutScreen(
@Composable
fun PreviewAboutScreen() {
AboutScreen(
prefs = AboutPreferences(
prefs = AboutPreferencesImpl(
enableToolsExperiment = false
),
navigateUpAction = {},

View File

@ -21,7 +21,7 @@ package com.sadellie.unitto.feature.settings.about
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sadellie.unitto.data.common.stateIn
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject

View File

@ -33,7 +33,8 @@ import com.sadellie.unitto.core.ui.common.NavigateUpButton
import com.sadellie.unitto.core.ui.common.UnittoEmptyScreen
import com.sadellie.unitto.core.ui.common.UnittoListItem
import com.sadellie.unitto.core.ui.common.UnittoScreenWithLargeTopBar
import com.sadellie.unitto.data.userprefs.CalculatorPreferences
import com.sadellie.unitto.data.model.userprefs.CalculatorPreferences
import com.sadellie.unitto.data.userprefs.CalculatorPreferencesImpl
@Composable
internal fun CalculatorSettingsRoute(
@ -80,7 +81,7 @@ private fun CalculatorSettingsScreen(
@Composable
private fun PreviewCalculatorSettingsScreen() {
CalculatorSettingsScreen(
prefs = CalculatorPreferences(
prefs = CalculatorPreferencesImpl(
radianMode = false,
enableVibrations = false,
separator = Separator.SPACE,

View File

@ -21,7 +21,7 @@ package com.sadellie.unitto.feature.settings.calculator
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sadellie.unitto.data.common.stateIn
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject

View File

@ -43,7 +43,8 @@ import com.sadellie.unitto.core.ui.common.UnittoListItem
import com.sadellie.unitto.core.ui.common.UnittoScreenWithLargeTopBar
import com.sadellie.unitto.data.model.ALL_UNIT_GROUPS
import com.sadellie.unitto.data.model.UnitsListSorting
import com.sadellie.unitto.data.userprefs.ConverterPreferences
import com.sadellie.unitto.data.model.userprefs.ConverterPreferences
import com.sadellie.unitto.data.userprefs.ConverterPreferencesImpl
import com.sadellie.unitto.feature.settings.components.AlertDialogWithList
@Composable
@ -131,7 +132,7 @@ private fun ConverterSettingsScreen(
@Composable
private fun PreviewConverterSettingsScreen() {
ConverterSettingsScreen(
prefs = ConverterPreferences(
prefs = ConverterPreferencesImpl(
enableVibrations = true,
separator = Separator.SPACE,
middleZero = false,

View File

@ -22,7 +22,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sadellie.unitto.data.common.stateIn
import com.sadellie.unitto.data.model.UnitsListSorting
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject

View File

@ -22,7 +22,7 @@ import androidx.compose.ui.graphics.Color
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sadellie.unitto.data.common.stateIn
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import io.github.sadellie.themmo.MonetMode
import io.github.sadellie.themmo.ThemingMode
@ -39,7 +39,7 @@ class DisplayViewModel @Inject constructor(
fun updateThemingMode(themingMode: ThemingMode) {
viewModelScope.launch {
userPrefsRepository.updateThemingMode(themingMode)
userPrefsRepository.updateThemingMode(themingMode.name)
}
}
@ -57,13 +57,13 @@ class DisplayViewModel @Inject constructor(
fun updateCustomColor(color: Color) {
viewModelScope.launch {
userPrefsRepository.updateCustomColor(color)
userPrefsRepository.updateCustomColor(color.value.toLong())
}
}
fun updateMonetMode(monetMode: MonetMode) {
viewModelScope.launch {
userPrefsRepository.updateMonetMode(monetMode)
userPrefsRepository.updateMonetMode(monetMode.name)
}
}

View File

@ -28,7 +28,7 @@ import com.sadellie.unitto.data.common.setMinimumRequiredScale
import com.sadellie.unitto.data.common.stateIn
import com.sadellie.unitto.data.common.toStringWith
import com.sadellie.unitto.data.common.trimZeros
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine

View File

@ -21,7 +21,7 @@ package com.sadellie.unitto.feature.settings.startingscreen
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sadellie.unitto.data.common.stateIn
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject

View File

@ -21,7 +21,7 @@ package com.sadellie.unitto.feature.settings.unitgroups
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.sadellie.unitto.data.model.UnitGroup
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
import com.sadellie.unitto.data.model.repository.UserPreferencesRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch