From 15385466f4d3dbe43b414f0fae9d20a781ec779b Mon Sep 17 00:00:00 2001 From: imrannextgeni021 Date: Tue, 15 Oct 2024 01:53:35 +0500 Subject: [PATCH] Removed Any from NavGraph and implemented type safety and static type checking at compile time. Removed Gradle migration to type-safe navigation comment line. Added back Header Comment in NormalScreens file. --- app/build.gradle | 1 - .../com/starry/greenstash/MainViewModel.kt | 11 ++-- .../greenstash/ui/navigation/DrawerScreens.kt | 10 +-- .../greenstash/ui/navigation/NavGraph.kt | 24 ++++---- .../greenstash/ui/navigation/NormalScreens.kt | 61 +++++++++++++++++++ .../starry/greenstash/ui/navigation/Screen.kt | 4 ++ .../greenstash/ui/navigation/Screens.kt | 36 ----------- .../screens/dwscreen/composables/DWScreen.kt | 4 +- .../screens/home/composables/GoalLazyItem.kt | 20 +++--- .../ui/screens/home/composables/HomeScreen.kt | 4 +- .../greenstash/ui/screens/main/MainScreen.kt | 10 +-- .../settings/composables/SettingsScreen.kt | 10 ++- 12 files changed, 110 insertions(+), 85 deletions(-) create mode 100644 app/src/main/java/com/starry/greenstash/ui/navigation/NormalScreens.kt create mode 100644 app/src/main/java/com/starry/greenstash/ui/navigation/Screen.kt delete mode 100644 app/src/main/java/com/starry/greenstash/ui/navigation/Screens.kt diff --git a/app/build.gradle b/app/build.gradle index 4580e8b..bf271b0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -91,7 +91,6 @@ dependencies { implementation 'androidx.activity:activity-compose:1.9.2' implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.8.6" implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.8.6" - // TODO: Needs migration to type-safe navigation in v2.8.x implementation "androidx.navigation:navigation-compose:2.8.2" // Jetpack compose. implementation "androidx.compose.ui:ui" diff --git a/app/src/main/java/com/starry/greenstash/MainViewModel.kt b/app/src/main/java/com/starry/greenstash/MainViewModel.kt index 6d74509..b1b7124 100644 --- a/app/src/main/java/com/starry/greenstash/MainViewModel.kt +++ b/app/src/main/java/com/starry/greenstash/MainViewModel.kt @@ -40,8 +40,9 @@ import androidx.lifecycle.viewModelScope import com.starry.greenstash.database.goal.GoalDao import com.starry.greenstash.other.WelcomeDataStore import com.starry.greenstash.reminder.ReminderManager +import com.starry.greenstash.ui.navigation.NormalScreens import com.starry.greenstash.ui.navigation.DrawerScreens -import com.starry.greenstash.ui.navigation.WelcomeScreen +import com.starry.greenstash.ui.navigation.Screen import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay @@ -66,9 +67,9 @@ class MainViewModel @Inject constructor( private val _isLoading: MutableState = mutableStateOf(true) val isLoading: State = _isLoading - private val _startDestination: MutableState = - mutableStateOf(WelcomeScreen) - val startDestination: State = _startDestination + private val _startDestination: MutableState = + mutableStateOf(NormalScreens.WelcomeScreen) + val startDestination: State = _startDestination companion object { // Must be same as the one in AndroidManifest.xml @@ -87,7 +88,7 @@ class MainViewModel @Inject constructor( if (completed) { _startDestination.value = DrawerScreens.Home } else { - _startDestination.value = WelcomeScreen + _startDestination.value = NormalScreens.WelcomeScreen } delay(120) diff --git a/app/src/main/java/com/starry/greenstash/ui/navigation/DrawerScreens.kt b/app/src/main/java/com/starry/greenstash/ui/navigation/DrawerScreens.kt index 9de280c..3517c3c 100644 --- a/app/src/main/java/com/starry/greenstash/ui/navigation/DrawerScreens.kt +++ b/app/src/main/java/com/starry/greenstash/ui/navigation/DrawerScreens.kt @@ -29,26 +29,26 @@ import com.starry.greenstash.R import kotlinx.serialization.Serializable @Serializable -sealed class DrawerScreens( val nameResId: Int, val iconResId: Int) { +sealed class DrawerScreens(val nameResId: Int, val iconResId: Int) : Screen() { companion object { fun getAllItems() = listOf(Home, Archive, Backups, Settings) } @Serializable - data object Home : DrawerScreens( R.string.drawer_home, R.drawable.ic_nav_home) + data object Home : DrawerScreens(R.string.drawer_home, R.drawable.ic_nav_home) @Serializable data object Archive : - DrawerScreens( R.string.drawer_archive, R.drawable.ic_nav_archive) + DrawerScreens(R.string.drawer_archive, R.drawable.ic_nav_archive) @Serializable data object Backups : - DrawerScreens( R.string.drawer_backup, R.drawable.ic_nav_backups) + DrawerScreens(R.string.drawer_backup, R.drawable.ic_nav_backups) @Serializable data object Settings : - DrawerScreens( R.string.drawer_settings, R.drawable.ic_nav_settings) + DrawerScreens(R.string.drawer_settings, R.drawable.ic_nav_settings) } diff --git a/app/src/main/java/com/starry/greenstash/ui/navigation/NavGraph.kt b/app/src/main/java/com/starry/greenstash/ui/navigation/NavGraph.kt index f7de861..84564e5 100644 --- a/app/src/main/java/com/starry/greenstash/ui/navigation/NavGraph.kt +++ b/app/src/main/java/com/starry/greenstash/ui/navigation/NavGraph.kt @@ -50,7 +50,7 @@ import com.starry.greenstash.ui.screens.welcome.composables.WelcomeScreen @Composable fun NavGraph( navController: NavHostController, - startDestination: Any + startDestination: Screen ) { NavHost( @@ -60,7 +60,7 @@ fun NavGraph( ) { /** Welcome Screen */ - composable( + composable( exitTransition = { exitTransition() }, popEnterTransition = { popEnterTransition() }, ) { @@ -78,13 +78,13 @@ fun NavGraph( } /** Deposit Withdraw Screen */ - composable( + composable( enterTransition = { enterTransition() }, exitTransition = { exitTransition() }, popEnterTransition = { popEnterTransition() }, popExitTransition = { popExitTransition() } ) { backStackEntry -> - val args = backStackEntry.toRoute() + val args = backStackEntry.toRoute() DWScreen( goalId = args.goalId, transactionTypeName = args.transactionType, @@ -93,29 +93,29 @@ fun NavGraph( } /** Goal Info Screen */ - composable( + composable( enterTransition = { enterTransition() }, exitTransition = { exitTransition() }, popEnterTransition = { popEnterTransition() }, popExitTransition = { popExitTransition() } ) { backStackEntry -> - val args = backStackEntry.toRoute() + val args = backStackEntry.toRoute() GoalInfoScreen(goalId = args.goalId, navController = navController) } /** Input Screen */ - composable( + composable( enterTransition = { enterTransition() }, exitTransition = { exitTransition() }, popEnterTransition = { popEnterTransition() }, popExitTransition = { popExitTransition() } ) { backStackEntry -> - val args = backStackEntry.toRoute() + val args = backStackEntry.toRoute() InputScreen(editGoalId = args.goalId, navController = navController) } /** Goal Achieved Screen */ - composable( + composable( enterTransition = { enterTransition() }, exitTransition = { exitTransition() }, popEnterTransition = { popEnterTransition() }, @@ -155,7 +155,7 @@ fun NavGraph( } /** Goal Ui Settings Screen */ - composable( + composable( enterTransition = { enterTransition() }, popExitTransition = { popExitTransition() }, ) { @@ -163,7 +163,7 @@ fun NavGraph( } /** Open Source Licenses Screen */ - composable( + composable( enterTransition = { enterTransition() }, popExitTransition = { popExitTransition() }, ) { @@ -171,7 +171,7 @@ fun NavGraph( } /** About Screen */ - composable( + composable( enterTransition = { enterTransition() }, popExitTransition = { popExitTransition() }, ) { diff --git a/app/src/main/java/com/starry/greenstash/ui/navigation/NormalScreens.kt b/app/src/main/java/com/starry/greenstash/ui/navigation/NormalScreens.kt new file mode 100644 index 0000000..839a2f9 --- /dev/null +++ b/app/src/main/java/com/starry/greenstash/ui/navigation/NormalScreens.kt @@ -0,0 +1,61 @@ +/** + * MIT License + * + * Copyright (c) [2022 - Present] Stɑrry Shivɑm + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + + +package com.starry.greenstash.ui.navigation + +import kotlinx.serialization.Serializable + +sealed class NormalScreens : Screen() { + + @Serializable + data class DWScreen(val goalId: String, val transactionType: String) + + @Serializable + data class InputScreen(val goalId: String? = null) + + @Serializable + data class GoalInfoScreen(val goalId: String) + + @Serializable + data object AboutScreen + + @Serializable + data object OSLScreen + + @Serializable + data object GoalCardStyleScreen + + + // Goal Achieved Screen + @Serializable + data object CongratsScreen + + // Welcome / Onboarding Screen + @Serializable + data object WelcomeScreen : NormalScreens() +} + + diff --git a/app/src/main/java/com/starry/greenstash/ui/navigation/Screen.kt b/app/src/main/java/com/starry/greenstash/ui/navigation/Screen.kt new file mode 100644 index 0000000..3a4a2e8 --- /dev/null +++ b/app/src/main/java/com/starry/greenstash/ui/navigation/Screen.kt @@ -0,0 +1,4 @@ +package com.starry.greenstash.ui.navigation + + +open class Screen \ No newline at end of file diff --git a/app/src/main/java/com/starry/greenstash/ui/navigation/Screens.kt b/app/src/main/java/com/starry/greenstash/ui/navigation/Screens.kt deleted file mode 100644 index d8c0768..0000000 --- a/app/src/main/java/com/starry/greenstash/ui/navigation/Screens.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.starry.greenstash.ui.navigation - -import kotlinx.serialization.Serializable - - -@Serializable -data class DWScreen(val goalId: String, val transactionType: String) - - -@Serializable -data class InputScreen(val goalId: String? = null) - - -@Serializable -data class GoalInfoScreen(val goalId: String) - -@Serializable -object AboutScreen - -@Serializable -object OSLScreen - -@Serializable -object GoalCardStyleScreen - - -// Goal Achieved Screen -@Serializable -object CongratsScreen - -// Welcome / Onboarding Screen -@Serializable -object WelcomeScreen - - - diff --git a/app/src/main/java/com/starry/greenstash/ui/screens/dwscreen/composables/DWScreen.kt b/app/src/main/java/com/starry/greenstash/ui/screens/dwscreen/composables/DWScreen.kt index dac0307..06c962d 100644 --- a/app/src/main/java/com/starry/greenstash/ui/screens/dwscreen/composables/DWScreen.kt +++ b/app/src/main/java/com/starry/greenstash/ui/screens/dwscreen/composables/DWScreen.kt @@ -84,7 +84,7 @@ import com.maxkeppeler.sheets.date_time.models.DateTimeSelection import com.starry.greenstash.R import com.starry.greenstash.database.transaction.TransactionType import com.starry.greenstash.ui.common.DateTimeCard -import com.starry.greenstash.ui.navigation.CongratsScreen +import com.starry.greenstash.ui.navigation.NormalScreens import com.starry.greenstash.ui.navigation.DrawerScreens import com.starry.greenstash.ui.screens.dwscreen.DWViewModel import com.starry.greenstash.ui.theme.greenstashFont @@ -208,7 +208,7 @@ fun DWScreen(goalId: String, transactionTypeName: String, navController: NavCont showTransactionAddedAnim.value = true delay(1100) withContext(Dispatchers.Main) { - navController.navigate(CongratsScreen) + navController.navigate(NormalScreens.CongratsScreen) } } }, onComplete = { diff --git a/app/src/main/java/com/starry/greenstash/ui/screens/home/composables/GoalLazyItem.kt b/app/src/main/java/com/starry/greenstash/ui/screens/home/composables/GoalLazyItem.kt index 6e050ad..f3ca2d7 100644 --- a/app/src/main/java/com/starry/greenstash/ui/screens/home/composables/GoalLazyItem.kt +++ b/app/src/main/java/com/starry/greenstash/ui/screens/home/composables/GoalLazyItem.kt @@ -43,9 +43,7 @@ import com.starry.greenstash.MainActivity import com.starry.greenstash.R import com.starry.greenstash.database.core.GoalWithTransactions import com.starry.greenstash.database.transaction.TransactionType -import com.starry.greenstash.ui.navigation.DWScreen -import com.starry.greenstash.ui.navigation.GoalInfoScreen -import com.starry.greenstash.ui.navigation.InputScreen +import com.starry.greenstash.ui.navigation.NormalScreens import com.starry.greenstash.ui.screens.home.GoalCardStyle import com.starry.greenstash.ui.screens.home.HomeViewModel import com.starry.greenstash.utils.Constants @@ -109,7 +107,7 @@ fun GoalLazyColumnItem( } } else { navController.navigate( - DWScreen( + NormalScreens.DWScreen( goalId = item.goal.goalId.toString(), transactionType = TransactionType.Deposit.name ) @@ -124,7 +122,7 @@ fun GoalLazyColumnItem( } } else { navController.navigate( - DWScreen( + NormalScreens.DWScreen( goalId = item.goal.goalId.toString(), transactionType = TransactionType.Withdraw.name ) @@ -134,7 +132,7 @@ fun GoalLazyColumnItem( onInfoClicked = { localView.weakHapticFeedback() navController.navigate( - GoalInfoScreen( + NormalScreens.GoalInfoScreen( goalId = item.goal.goalId.toString() ) ) @@ -142,7 +140,7 @@ fun GoalLazyColumnItem( onEditClicked = { localView.weakHapticFeedback() navController.navigate( - InputScreen( + NormalScreens.InputScreen( goalId = item.goal.goalId.toString() ) ) @@ -193,7 +191,7 @@ fun GoalLazyColumnItem( } } else { navController.navigate( - DWScreen( + NormalScreens.DWScreen( goalId = item.goal.goalId.toString(), transactionType = TransactionType.Deposit.name ) @@ -208,7 +206,7 @@ fun GoalLazyColumnItem( } } else { navController.navigate( - DWScreen( + NormalScreens.DWScreen( goalId = item.goal.goalId.toString(), transactionType = TransactionType.Withdraw.name ) @@ -218,7 +216,7 @@ fun GoalLazyColumnItem( onInfoClicked = { localView.weakHapticFeedback() navController.navigate( - GoalInfoScreen( + NormalScreens.GoalInfoScreen( goalId = item.goal.goalId.toString() ) ) @@ -226,7 +224,7 @@ fun GoalLazyColumnItem( onEditClicked = { localView.weakHapticFeedback() navController.navigate( - InputScreen( + NormalScreens.InputScreen( goalId = item.goal.goalId.toString() ) ) diff --git a/app/src/main/java/com/starry/greenstash/ui/screens/home/composables/HomeScreen.kt b/app/src/main/java/com/starry/greenstash/ui/screens/home/composables/HomeScreen.kt index de0cdac..9b6a0c1 100644 --- a/app/src/main/java/com/starry/greenstash/ui/screens/home/composables/HomeScreen.kt +++ b/app/src/main/java/com/starry/greenstash/ui/screens/home/composables/HomeScreen.kt @@ -102,7 +102,7 @@ import com.psoffritti.taptargetcompose.TextDefinition import com.starry.greenstash.MainActivity import com.starry.greenstash.R import com.starry.greenstash.database.core.GoalWithTransactions -import com.starry.greenstash.ui.navigation.InputScreen +import com.starry.greenstash.ui.navigation.NormalScreens import com.starry.greenstash.ui.screens.home.FilterField import com.starry.greenstash.ui.screens.home.FilterSortType import com.starry.greenstash.ui.screens.home.HomeViewModel @@ -418,7 +418,7 @@ private fun HomeExtendedFAB( modifier = modifier.padding(end = 10.dp, bottom = 12.dp), onClick = { view.weakHapticFeedback() - navController.navigate(InputScreen()) + navController.navigate(NormalScreens.InputScreen()) }, elevation = FloatingActionButtonDefaults.elevation(8.dp) ) { diff --git a/app/src/main/java/com/starry/greenstash/ui/screens/main/MainScreen.kt b/app/src/main/java/com/starry/greenstash/ui/screens/main/MainScreen.kt index 6db4f3c..d657342 100644 --- a/app/src/main/java/com/starry/greenstash/ui/screens/main/MainScreen.kt +++ b/app/src/main/java/com/starry/greenstash/ui/screens/main/MainScreen.kt @@ -40,9 +40,9 @@ import androidx.navigation.NavController import androidx.navigation.compose.rememberNavController import com.starry.greenstash.MainActivity import com.starry.greenstash.MainViewModel -import com.starry.greenstash.ui.navigation.GoalInfoScreen -import com.starry.greenstash.ui.navigation.InputScreen +import com.starry.greenstash.ui.navigation.NormalScreens import com.starry.greenstash.ui.navigation.NavGraph +import com.starry.greenstash.ui.navigation.Screen import com.starry.greenstash.ui.screens.other.AppLockedScreen import com.starry.greenstash.ui.screens.settings.ThemeMode import com.starry.greenstash.ui.theme.AdjustEdgeToEdge @@ -55,7 +55,7 @@ import com.starry.greenstash.ui.theme.AdjustEdgeToEdge fun MainScreen( activity: MainActivity, showAppContents: Boolean, - startDestination: Any, + startDestination: Screen, currentThemeMode: ThemeMode, onAuthRequest: () -> Unit, ) { @@ -99,11 +99,11 @@ private fun HandleShortcutIntent(intent: Intent, navController: NavController) { if (data != null && data.scheme == MainViewModel.LAUNCHER_SHORTCUT_SCHEME) { val goalId = intent.getLongExtra(MainViewModel.LC_SHORTCUT_GOAL_ID, -100) if (goalId != -100L) { - navController.navigate(GoalInfoScreen(goalId.toString())) + navController.navigate(NormalScreens.GoalInfoScreen(goalId.toString())) return } if (intent.getBooleanExtra(MainViewModel.LC_SHORTCUT_NEW_GOAL, false)) { - navController.navigate(InputScreen) + navController.navigate(NormalScreens.InputScreen) } } } \ No newline at end of file diff --git a/app/src/main/java/com/starry/greenstash/ui/screens/settings/composables/SettingsScreen.kt b/app/src/main/java/com/starry/greenstash/ui/screens/settings/composables/SettingsScreen.kt index 409de09..753819a 100644 --- a/app/src/main/java/com/starry/greenstash/ui/screens/settings/composables/SettingsScreen.kt +++ b/app/src/main/java/com/starry/greenstash/ui/screens/settings/composables/SettingsScreen.kt @@ -93,9 +93,7 @@ import com.starry.greenstash.MainActivity import com.starry.greenstash.R import com.starry.greenstash.ui.common.CurrencyPicker import com.starry.greenstash.ui.common.CurrencyPickerData -import com.starry.greenstash.ui.navigation.AboutScreen -import com.starry.greenstash.ui.navigation.GoalCardStyleScreen -import com.starry.greenstash.ui.navigation.OSLScreen +import com.starry.greenstash.ui.navigation.NormalScreens import com.starry.greenstash.ui.screens.home.GoalCardStyle import com.starry.greenstash.ui.screens.settings.DateStyle import com.starry.greenstash.ui.screens.settings.SettingsViewModel @@ -233,7 +231,7 @@ private fun DisplaySettings(viewModel: SettingsViewModel, navController: NavCont SettingsItem(title = stringResource(id = R.string.goal_card_setting), description = goalStyleValue, icon = Icons.Filled.Style, - onClick = { navController.navigate(GoalCardStyleScreen) }) + onClick = { navController.navigate(NormalScreens.GoalCardStyleScreen) }) if (showThemeSheet.value) { ThemePickerDialog( @@ -555,11 +553,11 @@ private fun MiscSettings(navController: NavController) { SettingsItem(title = stringResource(id = R.string.license_setting), description = stringResource(id = R.string.license_setting_desc), icon = Icons.Filled.LocalPolice, - onClick = { navController.navigate(OSLScreen) }) + onClick = { navController.navigate(NormalScreens.OSLScreen) }) SettingsItem(title = stringResource(id = R.string.app_info_setting), description = stringResource(id = R.string.app_info_setting_desc), icon = Icons.Filled.Info, - onClick = { navController.navigate(AboutScreen) }) + onClick = { navController.navigate(NormalScreens.AboutScreen) }) } Spacer(modifier = Modifier.height(2.dp)) // Last item padding. }