diff --git a/app/src/main/java/com/sadellie/unitto/UnittoApp.kt b/app/src/main/java/com/sadellie/unitto/UnittoApp.kt index 08eb588b..2dae44e1 100644 --- a/app/src/main/java/com/sadellie/unitto/UnittoApp.kt +++ b/app/src/main/java/com/sadellie/unitto/UnittoApp.kt @@ -45,7 +45,7 @@ fun UnittoApp() { val themmoController = rememberThemmoController( lightColorScheme = LightThemeColors, darkColorScheme = DarkThemeColors, - // Anything below will not 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.value.themingMode ?: return, dynamicThemeEnabled = userPrefs.value.enableDynamicTheme, amoledThemeEnabled = userPrefs.value.enableAmoledTheme @@ -65,7 +65,8 @@ fun UnittoApp() { converterViewModel = converterViewModel, secondViewModel = secondViewModel, settingsViewModel = settingsViewModel, - themmoController = it + themmoController = it, + startDestination = userPrefs.value.startingScreen ) SideEffect { sysUiController.setSystemBarsColor(backgroundColor) } diff --git a/app/src/main/java/com/sadellie/unitto/UnittoNavigation.kt b/app/src/main/java/com/sadellie/unitto/UnittoNavigation.kt index 0fa67c7e..ff4e5316 100644 --- a/app/src/main/java/com/sadellie/unitto/UnittoNavigation.kt +++ b/app/src/main/java/com/sadellie/unitto/UnittoNavigation.kt @@ -26,7 +26,6 @@ import androidx.navigation.compose.NavHost import com.sadellie.unitto.feature.calculator.navigation.calculatorScreen import com.sadellie.unitto.feature.calculator.navigation.navigateToCalculator import com.sadellie.unitto.feature.converter.ConverterViewModel -import com.sadellie.unitto.feature.converter.navigation.converterRoute import com.sadellie.unitto.feature.converter.navigation.converterScreen import com.sadellie.unitto.feature.converter.navigation.navigateToConverter import com.sadellie.unitto.feature.epoch.navigation.epochScreen @@ -50,11 +49,12 @@ fun UnittoNavigation( converterViewModel: ConverterViewModel, secondViewModel: SecondViewModel, settingsViewModel: SettingsViewModel, - themmoController: ThemmoController + themmoController: ThemmoController, + startDestination: String ) { NavHost( navController = navController, - startDestination = converterRoute + startDestination = startDestination ) { converterScreen( navigateToLeftScreen = navController::navigateToLeftSide, diff --git a/core/base/src/main/java/com/sadellie/unitto/core/base/TopLevelDestinations.kt b/core/base/src/main/java/com/sadellie/unitto/core/base/TopLevelDestinations.kt new file mode 100644 index 00000000..d69e0b5c --- /dev/null +++ b/core/base/src/main/java/com/sadellie/unitto/core/base/TopLevelDestinations.kt @@ -0,0 +1,32 @@ +/* + * 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 . + */ + +package com.sadellie.unitto.core.base + +object TopLevelDestinations { + const val CONVERTER = "converter_route" + const val CALCULATOR = "calculator_route" + const val EPOCH = "epoch_route" +} + +val TOP_LEVEL_DESTINATIONS: Map by lazy { + mapOf( + TopLevelDestinations.CONVERTER to R.string.unit_converter, + TopLevelDestinations.CALCULATOR to R.string.calculator, + ) +} diff --git a/core/base/src/main/res/values/strings.xml b/core/base/src/main/res/values/strings.xml index 3a4da175..704073a5 100644 --- a/core/base/src/main/res/values/strings.xml +++ b/core/base/src/main/res/values/strings.xml @@ -999,6 +999,8 @@ Precision Separator Output format + Starting screen + Choose which screen is shown when you launch the app Unit groups Vibrations Haptic feedback when clicking keyboard buttons diff --git a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt index 797dc82b..c75ea6ab 100644 --- a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt +++ b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt @@ -27,6 +27,7 @@ import androidx.datastore.preferences.core.intPreferencesKey import androidx.datastore.preferences.core.stringPreferencesKey import com.sadellie.unitto.core.base.OutputFormat import com.sadellie.unitto.core.base.Separator +import com.sadellie.unitto.core.base.TopLevelDestinations import com.sadellie.unitto.data.model.ALL_UNIT_GROUPS import com.sadellie.unitto.data.model.AbstractUnit import com.sadellie.unitto.data.model.UnitGroup @@ -65,7 +66,8 @@ data class UserPreferences( val latestRightSideUnit: String = MyUnitIDS.mile, val shownUnitGroups: List = ALL_UNIT_GROUPS, val enableVibrations: Boolean = true, - val enableToolsExperiment: Boolean = false + val enableToolsExperiment: Boolean = false, + val startingScreen: String = TopLevelDestinations.CONVERTER ) /** @@ -87,6 +89,7 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS val SHOWN_UNIT_GROUPS = stringPreferencesKey("SHOWN_UNIT_GROUPS_PREF_KEY") val ENABLE_VIBRATIONS = booleanPreferencesKey("ENABLE_VIBRATIONS_PREF_KEY") val ENABLE_TOOLS_EXPERIMENT = booleanPreferencesKey("ENABLE_TOOLS_EXPERIMENT_PREF_KEY") + val STARTING_SCREEN = stringPreferencesKey("STARTING_SCREEN_PREF_KEY") } val userPreferencesFlow: Flow = dataStore.data @@ -130,6 +133,7 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS } ?: ALL_UNIT_GROUPS 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 UserPreferences( themingMode = themingMode, @@ -142,7 +146,8 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS latestRightSideUnit = latestRightSideUnit, shownUnitGroups = shownUnitGroups, enableVibrations = enableVibrations, - enableToolsExperiment = enableToolsExperiment + enableToolsExperiment = enableToolsExperiment, + startingScreen = startingScreen ) } @@ -226,6 +231,17 @@ class UserPreferencesRepository @Inject constructor(private val dataStore: DataS } } + /** + * Update preference on starting screen route. + * + * @param startingScreen Route from [TopLevelDestinations]. + */ + suspend fun updateStartingScreen(startingScreen: String) { + dataStore.edit { preferences -> + preferences[PrefsKeys.STARTING_SCREEN] = startingScreen + } + } + suspend fun updateShownUnitGroups(shownUnitGroups: List) { dataStore.edit { preferences -> preferences[PrefsKeys.SHOWN_UNIT_GROUPS] = shownUnitGroups.joinToString(",") diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/navigation/CalculatorNavigation.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/navigation/CalculatorNavigation.kt index d6912e45..80571915 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/navigation/CalculatorNavigation.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/navigation/CalculatorNavigation.kt @@ -23,9 +23,10 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable import androidx.navigation.navDeepLink +import com.sadellie.unitto.core.base.TopLevelDestinations import com.sadellie.unitto.feature.calculator.CalculatorRoute -private const val calculatorRoute = "calculator_route" +private const val calculatorRoute = TopLevelDestinations.CALCULATOR fun NavController.navigateToCalculator(navOptions: NavOptions) { navigate(calculatorRoute, navOptions) diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/navigation/ConverterNavigation.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/navigation/ConverterNavigation.kt index 866e01ba..d8d8cc53 100644 --- a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/navigation/ConverterNavigation.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/navigation/ConverterNavigation.kt @@ -22,10 +22,11 @@ import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable +import com.sadellie.unitto.core.base.TopLevelDestinations import com.sadellie.unitto.feature.converter.ConverterRoute import com.sadellie.unitto.feature.converter.ConverterViewModel -const val converterRoute = "converter_route" +const val converterRoute = TopLevelDestinations.CONVERTER fun NavController.navigateToConverter(navOptions: NavOptions) { navigate(converterRoute, navOptions) diff --git a/feature/epoch/src/main/java/com/sadellie/unitto/feature/epoch/navigation/EpochNavigation.kt b/feature/epoch/src/main/java/com/sadellie/unitto/feature/epoch/navigation/EpochNavigation.kt index 70a12d7d..7f12e485 100644 --- a/feature/epoch/src/main/java/com/sadellie/unitto/feature/epoch/navigation/EpochNavigation.kt +++ b/feature/epoch/src/main/java/com/sadellie/unitto/feature/epoch/navigation/EpochNavigation.kt @@ -23,9 +23,10 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable import androidx.navigation.navDeepLink +import com.sadellie.unitto.core.base.TopLevelDestinations import com.sadellie.unitto.feature.epoch.EpochRoute -private const val epochRoute = "epoch_route" +private const val epochRoute = TopLevelDestinations.EPOCH fun NavController.navigateToEpoch(navOptions: NavOptions) { navigate(epochRoute, navOptions) diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/AboutScreen.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/AboutScreen.kt index 218dd5d8..af3905ee 100644 --- a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/AboutScreen.kt +++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/AboutScreen.kt @@ -30,9 +30,11 @@ import androidx.compose.material.icons.filled.Info import androidx.compose.material.icons.filled.Policy import androidx.compose.material.icons.filled.PrivacyTip import androidx.compose.material.icons.filled.Translate +import androidx.compose.material3.AlertDialog import androidx.compose.material3.Icon import androidx.compose.material3.ListItem import androidx.compose.material3.Text +import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -46,7 +48,6 @@ import com.sadellie.unitto.core.base.BuildConfig import com.sadellie.unitto.core.ui.R import com.sadellie.unitto.core.ui.common.UnittoLargeTopAppBar import com.sadellie.unitto.core.ui.openLink -import com.sadellie.unitto.feature.settings.components.AlertDialogWithList @Composable internal fun AboutScreen( @@ -198,11 +199,19 @@ internal fun AboutScreen( } if (showDialog) { - AlertDialogWithList( - title = stringResource(R.string.currency_rates_note_title), - dismissAction = { showDialog = false }, - supportText = stringResource(R.string.currency_rates_note_text), - dismissButtonLabel = stringResource(R.string.ok_label) + AlertDialog( + title = { + Text(stringResource(R.string.currency_rates_note_title)) + }, + text = { + Text(stringResource(R.string.currency_rates_note_text)) + }, + confirmButton = { + TextButton(onClick = { showDialog = false }) { + Text(stringResource(R.string.ok_label)) + } + }, + onDismissRequest = { showDialog = false } ) } } diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsScreen.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsScreen.kt index 19254959..06c3cbb9 100644 --- a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsScreen.kt +++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsScreen.kt @@ -22,6 +22,7 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Home import androidx.compose.material.icons.filled.Info import androidx.compose.material.icons.filled.Palette import androidx.compose.material.icons.filled.RateReview @@ -45,6 +46,7 @@ import com.sadellie.unitto.core.base.BuildConfig import com.sadellie.unitto.core.base.OUTPUT_FORMAT import com.sadellie.unitto.core.base.PRECISIONS import com.sadellie.unitto.core.base.SEPARATORS +import com.sadellie.unitto.core.base.TOP_LEVEL_DESTINATIONS import com.sadellie.unitto.core.ui.R import com.sadellie.unitto.core.ui.common.Header import com.sadellie.unitto.core.ui.common.UnittoLargeTopAppBar @@ -103,6 +105,21 @@ internal fun SettingsScreen( ) } + // START SCREEN + item { + ListItem( + leadingContent = { + Icon( + Icons.Default.Home, + stringResource(R.string.starting_screen_setting), + ) + }, + headlineText = { Text(stringResource(R.string.starting_screen_setting)) }, + supportingText = { Text(stringResource(R.string.starting_screen_setting_support)) }, + modifier = Modifier.clickable { dialogState = DialogState.START_SCREEN } + ) + } + // GENERAL GROUP item { Header(stringResource(R.string.formatting_settings_group)) } @@ -209,7 +226,7 @@ internal fun SettingsScreen( title = stringResource(R.string.precision_setting), listItems = PRECISIONS, selectedItemIndex = userPrefs.value.digitsPrecision, - selectAction = { viewModel.updatePrecision(it) }, + selectAction = viewModel::updatePrecision, dismissAction = { resetDialog() }, supportText = stringResource(R.string.precision_setting_info) ) @@ -219,7 +236,7 @@ internal fun SettingsScreen( title = stringResource(R.string.separator_setting), listItems = SEPARATORS, selectedItemIndex = userPrefs.value.separator, - selectAction = { viewModel.updateSeparator(it) }, + selectAction = viewModel::updateSeparator, dismissAction = { resetDialog() } ) } @@ -228,11 +245,20 @@ internal fun SettingsScreen( title = stringResource(R.string.output_format_setting), listItems = OUTPUT_FORMAT, selectedItemIndex = userPrefs.value.outputFormat, - selectAction = { viewModel.updateOutputFormat(it) }, + selectAction = viewModel::updateOutputFormat, dismissAction = { resetDialog() }, supportText = stringResource(R.string.output_format_setting_info) ) } + DialogState.START_SCREEN -> { + AlertDialogWithList( + title = stringResource(R.string.starting_screen_setting), + selectedItemIndex = userPrefs.value.startingScreen, + listItems = TOP_LEVEL_DESTINATIONS, + selectAction = viewModel::updateStartingScreen, + dismissAction = { resetDialog() } + ) + } // Dismissing alert dialog else -> {} } @@ -242,5 +268,5 @@ internal fun SettingsScreen( * All possible states for alert dialog that opens when user clicks on settings. */ private enum class DialogState { - NONE, PRECISION, SEPARATOR, OUTPUT_FORMAT, + NONE, PRECISION, SEPARATOR, OUTPUT_FORMAT, START_SCREEN } diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsViewModel.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsViewModel.kt index 3495458e..3b3e77cf 100644 --- a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsViewModel.kt +++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsViewModel.kt @@ -110,6 +110,15 @@ class SettingsViewModel @Inject constructor( } } + /** + * @see UserPreferencesRepository.updateStartingScreen + */ + fun updateStartingScreen(startingScreen: String) { + viewModelScope.launch { + userPrefsRepository.updateStartingScreen(startingScreen) + } + } + /** * @see UnitGroupsRepository.markUnitGroupAsHidden * @see UserPreferencesRepository.updateShownUnitGroups diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/components/AlertDialogWithList.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/components/AlertDialogWithList.kt index 031b78d3..179d669f 100644 --- a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/components/AlertDialogWithList.kt +++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/components/AlertDialogWithList.kt @@ -44,18 +44,18 @@ import com.sadellie.unitto.feature.settings.R * Alert dialog that has a list of options in it * * @param title Dialog title - * @param listItems List of options + * @param listItems List of options. Map, where key is an option and value is a string (option name) * @param selectedItemIndex Currently selected item index * @param selectAction Action to perform when clicking an option * @param dismissAction Action to perform when clicking "cancel" * @param supportText Text above list of options */ @Composable -internal fun AlertDialogWithList( +internal fun AlertDialogWithList( title: String, - listItems: Map = emptyMap(), - selectedItemIndex: Int = 0, - selectAction: (Int) -> Unit = {}, + listItems: Map, + selectedItemIndex: T, + selectAction: (T) -> Unit, dismissAction: () -> Unit, supportText: String? = null, dismissButtonLabel: String = stringResource(R.string.cancel_label)