mirror of
https://github.com/Myzel394/NumberHub.git
synced 2025-07-01 06:00:57 +02:00
Refactored repository for DataStore
Also renamed app theme from AppTheme to UnittoTheme so that it's less confusing
This commit is contained in:
parent
37826b7177
commit
941e260a15
@ -5,7 +5,7 @@ import android.content.Context
|
|||||||
import androidx.room.Room
|
import androidx.room.Room
|
||||||
import androidx.test.core.app.ApplicationProvider
|
import androidx.test.core.app.ApplicationProvider
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import com.sadellie.unitto.data.preferences.UserPreferences
|
import com.sadellie.unitto.data.preferences.UserPreferencesRepository
|
||||||
import com.sadellie.unitto.data.units.ALL_UNITS
|
import com.sadellie.unitto.data.units.ALL_UNITS
|
||||||
import com.sadellie.unitto.data.units.MyUnitIDS
|
import com.sadellie.unitto.data.units.MyUnitIDS
|
||||||
import com.sadellie.unitto.data.units.database.MyBasedUnitDatabase
|
import com.sadellie.unitto.data.units.database.MyBasedUnitDatabase
|
||||||
@ -26,7 +26,7 @@ class SwapUnitsTest {
|
|||||||
fun setUp() {
|
fun setUp() {
|
||||||
val context = ApplicationProvider.getApplicationContext<Context>()
|
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||||
viewModel = MainViewModel(
|
viewModel = MainViewModel(
|
||||||
UserPreferences(context),
|
UserPreferencesRepository(context),
|
||||||
MyBasedUnitsRepository(
|
MyBasedUnitsRepository(
|
||||||
Room.inMemoryDatabaseBuilder(
|
Room.inMemoryDatabaseBuilder(
|
||||||
context,
|
context,
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.sadellie.unitto
|
package com.sadellie.unitto
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
@ -8,8 +7,6 @@ import androidx.activity.viewModels
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.NavType
|
import androidx.navigation.NavType
|
||||||
@ -24,7 +21,7 @@ import com.sadellie.unitto.screens.about.AboutScreen
|
|||||||
import com.sadellie.unitto.screens.main.MainScreen
|
import com.sadellie.unitto.screens.main.MainScreen
|
||||||
import com.sadellie.unitto.screens.second.SecondScreen
|
import com.sadellie.unitto.screens.second.SecondScreen
|
||||||
import com.sadellie.unitto.screens.setttings.SettingsScreen
|
import com.sadellie.unitto.screens.setttings.SettingsScreen
|
||||||
import com.sadellie.unitto.ui.theme.AppTheme
|
import com.sadellie.unitto.ui.theme.UnittoTheme
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
|
||||||
|
|
||||||
@ -37,11 +34,11 @@ class MainActivity : ComponentActivity() {
|
|||||||
|
|
||||||
setContent {
|
setContent {
|
||||||
val navController = rememberNavController()
|
val navController = rememberNavController()
|
||||||
val currentAppTheme: Int by mainViewModel.currentAppTheme.collectAsState(AppTheme.NOT_SET)
|
val currentAppTheme: Int = mainViewModel.currentTheme
|
||||||
|
|
||||||
// We don't draw anything until we know what theme we need to use
|
// We don't draw anything until we know what theme we need to use
|
||||||
if (currentAppTheme != AppTheme.NOT_SET) {
|
if (currentAppTheme != AppTheme.NOT_SET) {
|
||||||
AppTheme(
|
UnittoTheme(
|
||||||
currentAppTheme = currentAppTheme
|
currentAppTheme = currentAppTheme
|
||||||
) {
|
) {
|
||||||
UnittoApp(
|
UnittoApp(
|
||||||
@ -54,7 +51,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
mainViewModel.saveMe()
|
mainViewModel.saveLatestPairOfUnits()
|
||||||
super.onPause()
|
super.onPause()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package com.sadellie.unitto.data.preferences
|
package com.sadellie.unitto.data.preferences
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import androidx.datastore.core.DataStore
|
||||||
import androidx.datastore.preferences.core.*
|
import androidx.datastore.preferences.core.*
|
||||||
import androidx.datastore.preferences.preferencesDataStore
|
import androidx.datastore.preferences.preferencesDataStore
|
||||||
|
import com.sadellie.unitto.data.units.AbstractUnit
|
||||||
|
import com.sadellie.unitto.data.units.MyUnitIDS
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
@ -14,81 +17,142 @@ import javax.inject.Inject
|
|||||||
private val Context.settingsDataStore by preferencesDataStore("settings")
|
private val Context.settingsDataStore by preferencesDataStore("settings")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keys for DataStore
|
* Represents user preferences that are user across the app
|
||||||
|
*
|
||||||
|
* @property currentAppTheme Current [AppTheme] to be used
|
||||||
|
* @property digitsPrecision Current [PRECISIONS]. Number of digits in fractional part
|
||||||
|
* @property separator Current [Separator] that used to separate thousands
|
||||||
|
* @property outputFormat Current [OutputFormat] that is applied to converted value (not input)
|
||||||
|
* @property latestLeftSideUnit Latest [AbstractUnit] that was on the left side
|
||||||
|
* @property latestRightSideUnit Latest [AbstractUnit] that was on the right side
|
||||||
|
* @property enableAnalytics Whether or not user wants to share application usage data
|
||||||
*/
|
*/
|
||||||
object UserPreferenceKeys {
|
data class UserPreferences(
|
||||||
val CURRENT_APP_THEME = intPreferencesKey("CURRENT_APP_THEME")
|
val currentAppTheme: Int,
|
||||||
val DIGITS_PRECISION = intPreferencesKey("DIGITS_PRECISION_PREF_KEY")
|
val digitsPrecision: Int,
|
||||||
val SEPARATOR = intPreferencesKey("SEPARATOR_PREF_KEY")
|
val separator: Int,
|
||||||
val OUTPUT_FORMAT = intPreferencesKey("OUTPUT_FORMAT_PREF_KEY")
|
val outputFormat: Int,
|
||||||
val LATEST_LEFT_SIDE = stringPreferencesKey("LATEST_LEFT_SIDE_PREF_KEY")
|
val latestLeftSideUnit: String,
|
||||||
val LATEST_RIGHT_SIDE = stringPreferencesKey("LATEST_RIGHT_SIDE_PREF_KEY")
|
val latestRightSideUnit: String,
|
||||||
val ENABLE_ANALYTICS = booleanPreferencesKey("ENABLE_ANALYTICS_PREF_KEY")
|
val enableAnalytics: Boolean
|
||||||
}
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repository that works with DataStore
|
* Repository that works with DataStore
|
||||||
*
|
*
|
||||||
* @property context
|
* @property context
|
||||||
*/
|
*/
|
||||||
class UserPreferences @Inject constructor(@ApplicationContext private val context: Context) {
|
class UserPreferencesRepository @Inject constructor(@ApplicationContext private val context: Context) {
|
||||||
|
|
||||||
|
private val dataStore: DataStore<Preferences> = context.settingsDataStore
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets string from datastore
|
* Keys for DataStore
|
||||||
|
*/
|
||||||
|
private object PrefsKeys {
|
||||||
|
val CURRENT_APP_THEME = intPreferencesKey("CURRENT_APP_THEME")
|
||||||
|
val DIGITS_PRECISION = intPreferencesKey("DIGITS_PRECISION_PREF_KEY")
|
||||||
|
val SEPARATOR = intPreferencesKey("SEPARATOR_PREF_KEY")
|
||||||
|
val OUTPUT_FORMAT = intPreferencesKey("OUTPUT_FORMAT_PREF_KEY")
|
||||||
|
val LATEST_LEFT_SIDE = stringPreferencesKey("LATEST_LEFT_SIDE_PREF_KEY")
|
||||||
|
val LATEST_RIGHT_SIDE = stringPreferencesKey("LATEST_RIGHT_SIDE_PREF_KEY")
|
||||||
|
val ENABLE_ANALYTICS = booleanPreferencesKey("ENABLE_ANALYTICS_PREF_KEY")
|
||||||
|
}
|
||||||
|
|
||||||
|
val userPreferencesFlow: Flow<UserPreferences> = dataStore.data
|
||||||
|
.map { preferences ->
|
||||||
|
val currentAppTheme: Int =
|
||||||
|
preferences[PrefsKeys.CURRENT_APP_THEME] ?: AppTheme.AUTO
|
||||||
|
val digitsPrecision: Int =
|
||||||
|
preferences[PrefsKeys.DIGITS_PRECISION] ?: 3
|
||||||
|
val separator: Int =
|
||||||
|
preferences[PrefsKeys.SEPARATOR] ?: Separator.SPACES
|
||||||
|
val outputFormat: Int =
|
||||||
|
preferences[PrefsKeys.OUTPUT_FORMAT] ?: OutputFormat.PLAIN
|
||||||
|
val latestLeftSideUnit: String =
|
||||||
|
preferences[PrefsKeys.LATEST_LEFT_SIDE] ?: MyUnitIDS.kilometer
|
||||||
|
val latestRightSideUnit: String =
|
||||||
|
preferences[PrefsKeys.LATEST_RIGHT_SIDE] ?: MyUnitIDS.mile
|
||||||
|
val enableAnalytics: Boolean =
|
||||||
|
preferences[PrefsKeys.ENABLE_ANALYTICS] ?: true
|
||||||
|
|
||||||
|
UserPreferences(
|
||||||
|
currentAppTheme = currentAppTheme,
|
||||||
|
digitsPrecision = digitsPrecision,
|
||||||
|
separator = separator,
|
||||||
|
outputFormat = outputFormat,
|
||||||
|
latestLeftSideUnit = latestLeftSideUnit,
|
||||||
|
latestRightSideUnit = latestRightSideUnit,
|
||||||
|
enableAnalytics = enableAnalytics
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update current theme preference in DataStore
|
||||||
*
|
*
|
||||||
* @param[default] Value to return if didn't find anything on fresh install
|
* @param appTheme [AppTheme] to change to
|
||||||
*/
|
*/
|
||||||
fun getItem(key: Preferences.Key<String>, default: String): Flow<String> {
|
suspend fun updateCurrentAppTheme(appTheme: Int) {
|
||||||
return context.settingsDataStore.data.map {
|
dataStore.edit { preferences ->
|
||||||
it[key] ?: default
|
preferences[PrefsKeys.CURRENT_APP_THEME] = appTheme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets int from datastore
|
* Update precision preference in DataStore
|
||||||
*
|
*
|
||||||
* @param[default] Value to return if didn't find anything. Used on fresh install
|
* @param precision One of the [PRECISIONS] to change to
|
||||||
*/
|
*/
|
||||||
fun getItem(key: Preferences.Key<Int>, default: Int): Flow<Int> {
|
suspend fun updateDigitsPrecision(precision: Int) {
|
||||||
return context.settingsDataStore.data.map {
|
dataStore.edit { preferences ->
|
||||||
it[key] ?: default
|
preferences[PrefsKeys.DIGITS_PRECISION] = precision
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets boolean from datastore
|
* Update separator preference in DataStore
|
||||||
*
|
*
|
||||||
* @param[default] Value to return if didn't find anything on fresh install
|
* @param separator One of the [Separator] to change to
|
||||||
*/
|
*/
|
||||||
fun getItem(key: Preferences.Key<Boolean>, default: Boolean): Flow<Boolean> {
|
suspend fun updateSeparator(separator: Int) {
|
||||||
return context.settingsDataStore.data.map {
|
dataStore.edit { preferences ->
|
||||||
it[key] ?: default
|
preferences[PrefsKeys.SEPARATOR] = separator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves string value by key
|
* Update outputFormat preference in DataStore
|
||||||
|
*
|
||||||
|
* @param outputFormat One of the [OutputFormat] to change to
|
||||||
*/
|
*/
|
||||||
suspend fun saveItem(key: Preferences.Key<String>, value: String) {
|
suspend fun updateOutputFormat(outputFormat: Int) {
|
||||||
context.settingsDataStore.edit {
|
dataStore.edit { preferences ->
|
||||||
it[key] = value
|
preferences[PrefsKeys.OUTPUT_FORMAT] = outputFormat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves int value by key
|
* Update analytics preference in DataStore
|
||||||
|
*
|
||||||
|
* @param enableAnalytics True if user wants to share data, False if not
|
||||||
*/
|
*/
|
||||||
suspend fun saveItem(key: Preferences.Key<Int>, value: Int) {
|
suspend fun updateEnableAnalytics(enableAnalytics: Boolean) {
|
||||||
context.settingsDataStore.edit {
|
dataStore.edit { preferences ->
|
||||||
it[key] = value
|
preferences[PrefsKeys.ENABLE_ANALYTICS] = enableAnalytics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves boolean value by key
|
* Update latest used pair of [AbstractUnit] in DataStore. Need it so when user restarts the app,
|
||||||
|
* this pair will be already set.
|
||||||
|
*
|
||||||
|
* @param leftSideUnit [AbstractUnit] on the left
|
||||||
|
* @param rightSideUnit [AbstractUnit] on the right
|
||||||
*/
|
*/
|
||||||
suspend fun saveItem(key: Preferences.Key<Boolean>, value: Boolean) {
|
suspend fun updateLatestPairOfUnits(leftSideUnit: AbstractUnit, rightSideUnit: AbstractUnit) {
|
||||||
context.settingsDataStore.edit {
|
dataStore.edit { preferences ->
|
||||||
it[key] = value
|
preferences[PrefsKeys.LATEST_LEFT_SIDE] = leftSideUnit.unitId
|
||||||
|
preferences[PrefsKeys.LATEST_RIGHT_SIDE] = rightSideUnit.unitId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,81 +33,67 @@ import javax.inject.Inject
|
|||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class MainViewModel @Inject constructor(
|
class MainViewModel @Inject constructor(
|
||||||
private val mySettingsPrefs: UserPreferences,
|
private val userPrefsRepository: UserPreferencesRepository,
|
||||||
private val basedUnitRepository: MyBasedUnitsRepository,
|
private val basedUnitRepository: MyBasedUnitsRepository,
|
||||||
private val application: Application
|
private val application: Application
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
/**
|
var currentTheme: Int by mutableStateOf(AppTheme.NOT_SET)
|
||||||
* APP THEME
|
|
||||||
*/
|
|
||||||
val currentAppTheme =
|
|
||||||
mySettingsPrefs.getItem(UserPreferenceKeys.CURRENT_APP_THEME, AppTheme.AUTO)
|
|
||||||
|
|
||||||
fun saveCurrentAppTheme(value: Int) {
|
|
||||||
viewModelScope.launch {
|
|
||||||
mySettingsPrefs.saveItem(key = UserPreferenceKeys.CURRENT_APP_THEME, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* CONVERSION PRECISION
|
|
||||||
*/
|
|
||||||
var precision: Int by mutableStateOf(0)
|
|
||||||
private set
|
private set
|
||||||
|
var precision: Int by mutableStateOf(3)
|
||||||
fun setPrecisionPref(value: Int) {
|
|
||||||
viewModelScope.launch {
|
|
||||||
precision = value
|
|
||||||
mySettingsPrefs.saveItem(UserPreferenceKeys.DIGITS_PRECISION, value)
|
|
||||||
convertValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* SEPARATOR
|
|
||||||
*/
|
|
||||||
var separator: Int by mutableStateOf(0)
|
|
||||||
private set
|
private set
|
||||||
|
var separator: Int by mutableStateOf(Separator.SPACES)
|
||||||
fun setSeparatorPref(value: Int) {
|
private set
|
||||||
separator = value
|
var outputFormat: Int by mutableStateOf(OutputFormat.PLAIN)
|
||||||
viewModelScope.launch {
|
|
||||||
Formatter.setSeparator(value)
|
|
||||||
mySettingsPrefs.saveItem(UserPreferenceKeys.SEPARATOR, value)
|
|
||||||
convertValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* OUTPUT FORMAT
|
|
||||||
*/
|
|
||||||
var outputFormat: Int by mutableStateOf(0)
|
|
||||||
private set
|
private set
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets given output format and saves it in user preference store
|
|
||||||
* @param value [OutputFormat] to set
|
|
||||||
*/
|
|
||||||
fun setOutputFormatPref(value: Int) {
|
|
||||||
// Updating value in memory
|
|
||||||
outputFormat = value
|
|
||||||
// Updating value on disk
|
|
||||||
viewModelScope.launch {
|
|
||||||
mySettingsPrefs.saveItem(UserPreferenceKeys.OUTPUT_FORMAT, value)
|
|
||||||
convertValue()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ANALYTICS
|
|
||||||
*/
|
|
||||||
var enableAnalytics: Boolean by mutableStateOf(false)
|
var enableAnalytics: Boolean by mutableStateOf(false)
|
||||||
|
private set
|
||||||
|
|
||||||
fun setAnalyticsPref(value: Boolean) {
|
/**
|
||||||
enableAnalytics = value
|
* See [UserPreferencesRepository.updateCurrentAppTheme]
|
||||||
|
*/
|
||||||
|
fun updateCurrentAppTheme(appTheme: Int) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
mySettingsPrefs.saveItem(UserPreferenceKeys.ENABLE_ANALYTICS, value)
|
userPrefsRepository.updateCurrentAppTheme(appTheme)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See [UserPreferencesRepository.updateDigitsPrecision]
|
||||||
|
*/
|
||||||
|
fun updatePrecision(precision: Int) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
userPrefsRepository.updateDigitsPrecision(precision)
|
||||||
|
convertValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See [UserPreferencesRepository.updateSeparator]
|
||||||
|
*/
|
||||||
|
fun updateSeparator(separator: Int) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
userPrefsRepository.updateSeparator(separator)
|
||||||
|
convertValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See [UserPreferencesRepository.updateOutputFormat]
|
||||||
|
*/
|
||||||
|
fun updateOutputFormat(outputFormat: Int) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
userPrefsRepository.updateOutputFormat(outputFormat)
|
||||||
|
convertValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See [UserPreferencesRepository.updateEnableAnalytics]
|
||||||
|
*/
|
||||||
|
fun updateEnableAnalytics(enableAnalytics: Boolean) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
userPrefsRepository.updateEnableAnalytics(enableAnalytics)
|
||||||
FirebaseAnalytics.getInstance(application).setAnalyticsCollectionEnabled(enableAnalytics)
|
FirebaseAnalytics.getInstance(application).setAnalyticsCollectionEnabled(enableAnalytics)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -412,10 +398,9 @@ class MainViewModel @Inject constructor(
|
|||||||
/**
|
/**
|
||||||
* Saves latest pair of units into datastore
|
* Saves latest pair of units into datastore
|
||||||
*/
|
*/
|
||||||
fun saveMe() {
|
fun saveLatestPairOfUnits() {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
mySettingsPrefs.saveItem(UserPreferenceKeys.LATEST_LEFT_SIDE, unitFrom.unitId)
|
userPrefsRepository.updateLatestPairOfUnits(unitFrom, unitTo)
|
||||||
mySettingsPrefs.saveItem(UserPreferenceKeys.LATEST_RIGHT_SIDE, unitTo.unitId)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,21 +462,34 @@ class MainViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
/**
|
||||||
|
* Observes changes in user preferences and updated values in this ViewModel.
|
||||||
|
*
|
||||||
|
* Any change in user preferences will update mutableStateOf so composables, that rely on this
|
||||||
|
* values recompose when actually needed. For example, when you change output format, composable
|
||||||
|
* in MainActivity will not be recomposed even though it needs currentTheme which is also in
|
||||||
|
* user preferences/
|
||||||
|
*/
|
||||||
|
private fun observePreferenceChanges() {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val latestLeftSideUnitId = mySettingsPrefs.getItem(
|
userPrefsRepository.userPreferencesFlow.collect { userPref ->
|
||||||
UserPreferenceKeys.LATEST_LEFT_SIDE,
|
currentTheme = userPref.currentAppTheme
|
||||||
MyUnitIDS.kilometer
|
precision = userPref.digitsPrecision
|
||||||
).first()
|
separator = userPref.separator.also { Formatter.setSeparator(it) }
|
||||||
|
outputFormat = userPref.outputFormat
|
||||||
|
enableAnalytics = userPref.enableAnalytics
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val latestRightSideUnitId = mySettingsPrefs.getItem(
|
init {
|
||||||
UserPreferenceKeys.LATEST_RIGHT_SIDE,
|
observePreferenceChanges()
|
||||||
MyUnitIDS.mile
|
viewModelScope.launch {
|
||||||
).first()
|
val snapshot = userPrefsRepository.userPreferencesFlow.first()
|
||||||
|
|
||||||
// First we load latest pair of units
|
// First we load latest pair of units
|
||||||
unitFrom = try {
|
unitFrom = try {
|
||||||
ALL_UNITS.first { it.unitId == latestLeftSideUnitId }
|
ALL_UNITS.first { it.unitId == snapshot.latestLeftSideUnit }
|
||||||
} catch (e: java.util.NoSuchElementException) {
|
} catch (e: java.util.NoSuchElementException) {
|
||||||
Log.w("MainViewModel", "No unit with the given unitId")
|
Log.w("MainViewModel", "No unit with the given unitId")
|
||||||
ALL_UNITS.first { it.unitId == MyUnitIDS.kilometer }
|
ALL_UNITS.first { it.unitId == MyUnitIDS.kilometer }
|
||||||
@ -499,25 +497,12 @@ class MainViewModel @Inject constructor(
|
|||||||
|
|
||||||
unitTo = try {
|
unitTo = try {
|
||||||
ALL_UNITS
|
ALL_UNITS
|
||||||
.first { it.unitId == latestRightSideUnitId }
|
.first { it.unitId == snapshot.latestRightSideUnit }
|
||||||
} catch (e: java.util.NoSuchElementException) {
|
} catch (e: java.util.NoSuchElementException) {
|
||||||
Log.w("MainViewModel", "No unit with the given unitId")
|
Log.w("MainViewModel", "No unit with the given unitId")
|
||||||
ALL_UNITS.first { it.unitId == MyUnitIDS.mile }
|
ALL_UNITS.first { it.unitId == MyUnitIDS.mile }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we get the precision so we can convert values
|
|
||||||
precision = mySettingsPrefs.getItem(UserPreferenceKeys.DIGITS_PRECISION, 3).first()
|
|
||||||
// Getting separator and changing it in number formatter
|
|
||||||
separator =
|
|
||||||
mySettingsPrefs
|
|
||||||
.getItem(UserPreferenceKeys.SEPARATOR, Separator.SPACES).first()
|
|
||||||
.also { Formatter.setSeparator(it) }
|
|
||||||
// Getting output format
|
|
||||||
outputFormat =
|
|
||||||
mySettingsPrefs
|
|
||||||
.getItem(UserPreferenceKeys.OUTPUT_FORMAT, OutputFormat.PLAIN)
|
|
||||||
.first()
|
|
||||||
|
|
||||||
convertValue()
|
convertValue()
|
||||||
|
|
||||||
val allBasedUnits = basedUnitRepository.getAll()
|
val allBasedUnits = basedUnitRepository.getAll()
|
||||||
@ -546,9 +531,6 @@ class MainViewModel @Inject constructor(
|
|||||||
* He can choose another unit group and doesn't need to wait for network to appear.
|
* He can choose another unit group and doesn't need to wait for network to appear.
|
||||||
* */
|
* */
|
||||||
updateCurrenciesBasicUnits()
|
updateCurrenciesBasicUnits()
|
||||||
|
|
||||||
enableAnalytics = mySettingsPrefs.getItem(UserPreferenceKeys.ENABLE_ANALYTICS, true).first()
|
|
||||||
FirebaseAnalytics.getInstance(application).setAnalyticsCollectionEnabled(enableAnalytics)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ fun SettingsScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
var currentDialogState: Int by rememberSaveable { mutableStateOf(0) }
|
var currentDialogState: Int by rememberSaveable { mutableStateOf(0) }
|
||||||
val currentAppTheme: Int by mainViewModel.currentAppTheme.collectAsState(AppTheme.NOT_SET)
|
val currentAppTheme: Int = mainViewModel.currentTheme
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@ -134,7 +134,7 @@ fun SettingsScreen(
|
|||||||
label = stringResource(id = R.string.send_usage_statistics),
|
label = stringResource(id = R.string.send_usage_statistics),
|
||||||
supportText = stringResource(id = R.string.send_usage_statistics_support),
|
supportText = stringResource(id = R.string.send_usage_statistics_support),
|
||||||
switchState = mainViewModel.enableAnalytics,
|
switchState = mainViewModel.enableAnalytics,
|
||||||
onSwitchChange = { mainViewModel.setAnalyticsPref(!it) })
|
onSwitchChange = { mainViewModel.updateEnableAnalytics(!it) })
|
||||||
SettingsListItem(
|
SettingsListItem(
|
||||||
label = stringResource(R.string.third_party_licenses),
|
label = stringResource(R.string.third_party_licenses),
|
||||||
onClick = { navControllerAction(ABOUT_SCREEN) }
|
onClick = { navControllerAction(ABOUT_SCREEN) }
|
||||||
@ -164,7 +164,7 @@ fun SettingsScreen(
|
|||||||
title = stringResource(id = R.string.precision_setting),
|
title = stringResource(id = R.string.precision_setting),
|
||||||
listItems = PRECISIONS,
|
listItems = PRECISIONS,
|
||||||
selectedItemIndex = mainViewModel.precision,
|
selectedItemIndex = mainViewModel.precision,
|
||||||
selectAction = { mainViewModel.setPrecisionPref(it) },
|
selectAction = { mainViewModel.updatePrecision(it) },
|
||||||
dismissAction = { currentDialogState = 0 },
|
dismissAction = { currentDialogState = 0 },
|
||||||
supportText = stringResource(id = R.string.precision_setting_info)
|
supportText = stringResource(id = R.string.precision_setting_info)
|
||||||
)
|
)
|
||||||
@ -174,7 +174,7 @@ fun SettingsScreen(
|
|||||||
title = stringResource(id = R.string.separator_setting),
|
title = stringResource(id = R.string.separator_setting),
|
||||||
listItems = SEPARATORS,
|
listItems = SEPARATORS,
|
||||||
selectedItemIndex = mainViewModel.separator,
|
selectedItemIndex = mainViewModel.separator,
|
||||||
selectAction = { mainViewModel.setSeparatorPref(it) },
|
selectAction = { mainViewModel.updateSeparator(it) },
|
||||||
dismissAction = { currentDialogState = 0 }
|
dismissAction = { currentDialogState = 0 }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -183,7 +183,7 @@ fun SettingsScreen(
|
|||||||
title = stringResource(id = R.string.output_format_setting),
|
title = stringResource(id = R.string.output_format_setting),
|
||||||
listItems = OUTPUT_FORMAT,
|
listItems = OUTPUT_FORMAT,
|
||||||
selectedItemIndex = mainViewModel.outputFormat,
|
selectedItemIndex = mainViewModel.outputFormat,
|
||||||
selectAction = { mainViewModel.setOutputFormatPref(it) },
|
selectAction = { mainViewModel.updateOutputFormat(it) },
|
||||||
dismissAction = { currentDialogState = 0 },
|
dismissAction = { currentDialogState = 0 },
|
||||||
supportText = stringResource(id = R.string.output_format_setting_info)
|
supportText = stringResource(id = R.string.output_format_setting_info)
|
||||||
)
|
)
|
||||||
@ -193,7 +193,7 @@ fun SettingsScreen(
|
|||||||
title = stringResource(id = R.string.theme_setting),
|
title = stringResource(id = R.string.theme_setting),
|
||||||
listItems = APP_THEMES,
|
listItems = APP_THEMES,
|
||||||
selectedItemIndex = currentAppTheme,
|
selectedItemIndex = currentAppTheme,
|
||||||
selectAction = { mainViewModel.saveCurrentAppTheme(it) },
|
selectAction = { mainViewModel.updateCurrentAppTheme(it) },
|
||||||
dismissAction = { currentDialogState = 0 },
|
dismissAction = { currentDialogState = 0 },
|
||||||
// Show note for users with devices that support custom Dynamic theming
|
// Show note for users with devices that support custom Dynamic theming
|
||||||
supportText = if (Build.VERSION.SDK_INT in (Build.VERSION_CODES.O_MR1..Build.VERSION_CODES.R)) stringResource(
|
supportText = if (Build.VERSION.SDK_INT in (Build.VERSION_CODES.O_MR1..Build.VERSION_CODES.R)) stringResource(
|
||||||
|
@ -10,7 +10,7 @@ import com.sadellie.unitto.data.preferences.AppTheme
|
|||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AppTheme(
|
fun UnittoTheme(
|
||||||
currentAppTheme: Int,
|
currentAppTheme: Int,
|
||||||
content: @Composable () -> Unit
|
content: @Composable () -> Unit
|
||||||
) {
|
) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user