diff --git a/app/src/main/java/dev/medzik/librepass/android/MainActivity.kt b/app/src/main/java/dev/medzik/librepass/android/MainActivity.kt index 78341f02..2862ee2f 100644 --- a/app/src/main/java/dev/medzik/librepass/android/MainActivity.kt +++ b/app/src/main/java/dev/medzik/librepass/android/MainActivity.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.isSystemInDarkTheme import androidx.core.view.WindowCompat import androidx.fragment.app.FragmentActivity import androidx.navigation.NavController +import dev.medzik.android.components.navigate import dev.medzik.librepass.android.data.getRepository import dev.medzik.librepass.android.ui.LibrePassNavigation import dev.medzik.librepass.android.ui.Screen @@ -17,7 +18,6 @@ import dev.medzik.librepass.android.utils.StoreKey import dev.medzik.librepass.android.utils.ThemeValues import dev.medzik.librepass.android.utils.UserSecrets import dev.medzik.librepass.android.utils.VaultTimeoutValues -import dev.medzik.librepass.android.utils.navigation.navigate class MainActivity : FragmentActivity() { lateinit var userSecrets: UserSecrets diff --git a/app/src/main/java/dev/medzik/librepass/android/ui/Screen.kt b/app/src/main/java/dev/medzik/librepass/android/ui/Screen.kt index a4a2f036..6563bb2f 100644 --- a/app/src/main/java/dev/medzik/librepass/android/ui/Screen.kt +++ b/app/src/main/java/dev/medzik/librepass/android/ui/Screen.kt @@ -1,10 +1,19 @@ package dev.medzik.librepass.android.ui import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalLifecycleOwner +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.compose.currentStateAsState import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController +import dev.medzik.android.components.NavArgument +import dev.medzik.android.components.NavScreen +import dev.medzik.android.components.getString +import dev.medzik.librepass.android.MainActivity import dev.medzik.librepass.android.data.getRepository import dev.medzik.librepass.android.ui.screens.PasswordGenerator import dev.medzik.librepass.android.ui.screens.WelcomeScreen @@ -19,15 +28,14 @@ import dev.medzik.librepass.android.ui.screens.dashboard.settings.SettingsAccoun import dev.medzik.librepass.android.ui.screens.dashboard.settings.SettingsAppearance import dev.medzik.librepass.android.ui.screens.dashboard.settings.SettingsSecurity import dev.medzik.librepass.android.utils.SecretStore.getUserSecrets -import dev.medzik.librepass.android.utils.navigation.getString import dev.medzik.librepass.types.cipher.Cipher import java.util.UUID -enum class Argument { +enum class Argument : NavArgument { CipherId } -enum class Screen(private val argument: Argument? = null) { +enum class Screen(override val args: Array? = null) : NavScreen { Welcome, Register, @@ -36,29 +44,14 @@ enum class Screen(private val argument: Argument? = null) { Unlock, Dashboard, - CipherView(Argument.CipherId), + CipherView(arrayOf(Argument.CipherId)), CipherAdd, - CipherEdit(Argument.CipherId), + CipherEdit(arrayOf(Argument.CipherId)), PasswordGenerator, SettingsAppearance, SettingsSecurity, - SettingsAccount; - - val route = if (argument != null) "$name/{${argument.name}}" else name - - fun fill(argumentPair: Pair? = null): String { - val arg = argumentPair?.first - val value = argumentPair?.second - - if (arg != argument) - throw IllegalArgumentException("Invalid arguments. Expected ${this.argument?.name}, got $arg") - - return when (argumentPair) { - null -> route - else -> route.replace("{${arg!!.name}}", value!!) - } - } + SettingsAccount } @Composable @@ -67,17 +60,17 @@ fun LibrePassNavigation() { val navController = rememberNavController() -// val lifecycleOwner = LocalLifecycleOwner.current -// val lifecycleState by lifecycleOwner.lifecycle.currentStateAsState() -// LaunchedEffect(lifecycleState) { -// when (lifecycleState) { -// Lifecycle.State.RESUMED -> { -// (context as MainActivity).onResume(navController) -// } -// -// else -> {} -// } -// } + val lifecycleOwner = LocalLifecycleOwner.current + val lifecycleState by lifecycleOwner.lifecycle.currentStateAsState() + LaunchedEffect(lifecycleState) { + when (lifecycleState) { + Lifecycle.State.RESUMED -> { + (context as MainActivity).onResume(navController) + } + + else -> {} + } + } val repository = context.getRepository() val userSecrets = context.getUserSecrets() @@ -85,53 +78,53 @@ fun LibrePassNavigation() { fun getStartRoute(): String { // if a user is not logged in, show welcome screen repository.credentials.get() - ?: return Screen.Welcome.route + ?: return Screen.Welcome.getRoute() // if user secrets are not set, show unlock screen userSecrets - ?: return Screen.Unlock.route + ?: return Screen.Unlock.getRoute() // else where the user secrets are set, show dashboard screen - return Screen.Dashboard.route + return Screen.Dashboard.getRoute() } NavHost( navController = navController, startDestination = getStartRoute() ) { - composable(Screen.Welcome.route) { + composable(Screen.Welcome.getRoute()) { WelcomeScreen(navController) } - composable(Screen.Register.route) { + composable(Screen.Register.getRoute()) { RegisterScreen(navController) } - composable(Screen.Login.route) { + composable(Screen.Login.getRoute()) { LoginScreen(navController) } - composable(Screen.AddCustomServer.route) { + composable(Screen.AddCustomServer.getRoute()) { AddCustomServer(navController) } - composable(Screen.Unlock.route) { + composable(Screen.Unlock.getRoute()) { UnlockScreen(navController) } - composable(Screen.Dashboard.route) { + composable(Screen.Dashboard.getRoute()) { DashboardNavigation(mainNavController = navController) } - composable(Screen.CipherView.route) { + composable(Screen.CipherView.getRoute()) { CipherViewScreen(navController = navController) } - composable(Screen.CipherAdd.route) { + composable(Screen.CipherAdd.getRoute()) { CipherAddEditView(navController = navController) } - composable(Screen.CipherEdit.route) { + composable(Screen.CipherEdit.getRoute()) { val cipherId = navController.getString(Argument.CipherId) ?: return@composable @@ -143,19 +136,19 @@ fun LibrePassNavigation() { CipherAddEditView(navController = navController, baseCipher = cipher) } - composable(Screen.PasswordGenerator.route) { + composable(Screen.PasswordGenerator.getRoute()) { PasswordGenerator(navController) } - composable(Screen.SettingsAppearance.route) { + composable(Screen.SettingsAppearance.getRoute()) { SettingsAppearance(navController) } - composable(Screen.SettingsSecurity.route) { + composable(Screen.SettingsSecurity.getRoute()) { SettingsSecurity(navController) } - composable(Screen.SettingsAccount.route) { + composable(Screen.SettingsAccount.getRoute()) { SettingsAccount(navController) } } diff --git a/app/src/main/java/dev/medzik/librepass/android/ui/screens/WelcomeScreen.kt b/app/src/main/java/dev/medzik/librepass/android/ui/screens/WelcomeScreen.kt index da49ae76..c45a6c56 100644 --- a/app/src/main/java/dev/medzik/librepass/android/ui/screens/WelcomeScreen.kt +++ b/app/src/main/java/dev/medzik/librepass/android/ui/screens/WelcomeScreen.kt @@ -19,10 +19,10 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.navigation.NavController import com.google.accompanist.drawablepainter.DrawablePainter +import dev.medzik.android.components.navigate import dev.medzik.librepass.android.R import dev.medzik.librepass.android.ui.Screen import dev.medzik.librepass.android.utils.TopBarTwoColor -import dev.medzik.librepass.android.utils.navigation.navigate @Composable fun WelcomeScreen(navController: NavController) { diff --git a/app/src/main/java/dev/medzik/librepass/android/ui/screens/auth/LoginScreen.kt b/app/src/main/java/dev/medzik/librepass/android/ui/screens/auth/LoginScreen.kt index 7d19cda0..50d2a4fc 100644 --- a/app/src/main/java/dev/medzik/librepass/android/ui/screens/auth/LoginScreen.kt +++ b/app/src/main/java/dev/medzik/librepass/android/ui/screens/auth/LoginScreen.kt @@ -21,6 +21,7 @@ import androidx.compose.ui.unit.dp import androidx.navigation.NavController import dev.medzik.android.components.LoadingButton import dev.medzik.android.components.PickerDialog +import dev.medzik.android.components.navigate import dev.medzik.android.components.rememberDialogState import dev.medzik.libcrypto.Hex import dev.medzik.librepass.android.R @@ -35,7 +36,6 @@ import dev.medzik.librepass.android.utils.TopBar import dev.medzik.librepass.android.utils.TopBarBackIcon import dev.medzik.librepass.android.utils.UserSecrets import dev.medzik.librepass.android.utils.exception.handle -import dev.medzik.librepass.android.utils.navigation.navigate import dev.medzik.librepass.android.utils.rememberLoadingState import dev.medzik.librepass.android.utils.rememberStringData import dev.medzik.librepass.android.utils.showToast diff --git a/app/src/main/java/dev/medzik/librepass/android/ui/screens/auth/RegisterScreen.kt b/app/src/main/java/dev/medzik/librepass/android/ui/screens/auth/RegisterScreen.kt index 4746ec46..8a34d5a4 100644 --- a/app/src/main/java/dev/medzik/librepass/android/ui/screens/auth/RegisterScreen.kt +++ b/app/src/main/java/dev/medzik/librepass/android/ui/screens/auth/RegisterScreen.kt @@ -21,6 +21,7 @@ import androidx.compose.ui.unit.dp import androidx.navigation.NavController import dev.medzik.android.components.LoadingButton import dev.medzik.android.components.PickerDialog +import dev.medzik.android.components.navigate import dev.medzik.android.components.rememberDialogState import dev.medzik.librepass.android.R import dev.medzik.librepass.android.ui.Screen @@ -30,7 +31,6 @@ import dev.medzik.librepass.android.utils.TextInputField import dev.medzik.librepass.android.utils.TopBar import dev.medzik.librepass.android.utils.TopBarBackIcon import dev.medzik.librepass.android.utils.exception.handle -import dev.medzik.librepass.android.utils.navigation.navigate import dev.medzik.librepass.android.utils.rememberLoadingState import dev.medzik.librepass.android.utils.rememberStringData import dev.medzik.librepass.android.utils.showToast @@ -69,10 +69,7 @@ fun RegisterScreen(navController: NavController) { navController.navigate( screen = Screen.Login, - options = { - // disable back to this page - popUpTo(Screen.Register.route) { inclusive = true } - } + disableBack = true ) } } catch (e: Exception) { diff --git a/app/src/main/java/dev/medzik/librepass/android/ui/screens/auth/UnlockScreen.kt b/app/src/main/java/dev/medzik/librepass/android/ui/screens/auth/UnlockScreen.kt index c4c483e5..74295f8e 100644 --- a/app/src/main/java/dev/medzik/librepass/android/ui/screens/auth/UnlockScreen.kt +++ b/app/src/main/java/dev/medzik/librepass/android/ui/screens/auth/UnlockScreen.kt @@ -20,6 +20,7 @@ import androidx.compose.ui.unit.dp import androidx.fragment.app.FragmentActivity import androidx.navigation.NavController import dev.medzik.android.components.LoadingButton +import dev.medzik.android.components.navigate import dev.medzik.android.crypto.KeyStore import dev.medzik.libcrypto.Argon2 import dev.medzik.libcrypto.Hex @@ -34,7 +35,6 @@ import dev.medzik.librepass.android.utils.TextInputField import dev.medzik.librepass.android.utils.TopBar import dev.medzik.librepass.android.utils.UserSecrets import dev.medzik.librepass.android.utils.exception.EncryptException -import dev.medzik.librepass.android.utils.navigation.navigate import dev.medzik.librepass.android.utils.rememberLoadingState import dev.medzik.librepass.android.utils.rememberStringData import dev.medzik.librepass.android.utils.showToast diff --git a/app/src/main/java/dev/medzik/librepass/android/ui/screens/ciphers/AddEditScreen.kt b/app/src/main/java/dev/medzik/librepass/android/ui/screens/ciphers/AddEditScreen.kt index 7a5a0dc3..766d8a38 100644 --- a/app/src/main/java/dev/medzik/librepass/android/ui/screens/ciphers/AddEditScreen.kt +++ b/app/src/main/java/dev/medzik/librepass/android/ui/screens/ciphers/AddEditScreen.kt @@ -27,6 +27,7 @@ import androidx.navigation.NavController import com.google.gson.Gson import dev.medzik.android.components.LoadingButton import dev.medzik.android.components.PreferenceGroupTitle +import dev.medzik.android.components.navigate import dev.medzik.librepass.android.R import dev.medzik.librepass.android.data.CipherTable import dev.medzik.librepass.android.data.getRepository @@ -37,7 +38,6 @@ import dev.medzik.librepass.android.utils.TextInputFieldBase import dev.medzik.librepass.android.utils.TopBar import dev.medzik.librepass.android.utils.TopBarBackIcon import dev.medzik.librepass.android.utils.exception.handle -import dev.medzik.librepass.android.utils.navigation.navigate import dev.medzik.librepass.android.utils.rememberLoadingState import dev.medzik.librepass.android.utils.shorten import dev.medzik.librepass.client.Server diff --git a/app/src/main/java/dev/medzik/librepass/android/ui/screens/ciphers/ViewScreen.kt b/app/src/main/java/dev/medzik/librepass/android/ui/screens/ciphers/ViewScreen.kt index 6f4a1337..27559130 100644 --- a/app/src/main/java/dev/medzik/librepass/android/ui/screens/ciphers/ViewScreen.kt +++ b/app/src/main/java/dev/medzik/librepass/android/ui/screens/ciphers/ViewScreen.kt @@ -33,6 +33,8 @@ import androidx.compose.ui.unit.dp import androidx.navigation.NavController import dev.medzik.android.components.BaseDialog import dev.medzik.android.components.PreferenceGroupTitle +import dev.medzik.android.components.getString +import dev.medzik.android.components.navigate import dev.medzik.android.components.rememberDialogState import dev.medzik.librepass.android.R import dev.medzik.librepass.android.data.getRepository @@ -42,8 +44,6 @@ import dev.medzik.librepass.android.utils.SHORTEN_NAME_LENGTH import dev.medzik.librepass.android.utils.SecretStore.getUserSecrets import dev.medzik.librepass.android.utils.TopBar import dev.medzik.librepass.android.utils.TopBarBackIcon -import dev.medzik.librepass.android.utils.navigation.getString -import dev.medzik.librepass.android.utils.navigation.navigate import dev.medzik.librepass.android.utils.shorten import dev.medzik.librepass.types.cipher.Cipher import java.text.SimpleDateFormat @@ -80,7 +80,7 @@ fun CipherViewScreen(navController: NavController) { FloatingActionButton(onClick = { navController.navigate( screen = Screen.CipherEdit, - argument = Argument.CipherId to cipherId + args = arrayOf(Argument.CipherId to cipherId) ) }) { Icon( diff --git a/app/src/main/java/dev/medzik/librepass/android/ui/screens/dashboard/DashboardNavigation.kt b/app/src/main/java/dev/medzik/librepass/android/ui/screens/dashboard/DashboardNavigation.kt index 4f78b866..cb7ba5b1 100644 --- a/app/src/main/java/dev/medzik/librepass/android/ui/screens/dashboard/DashboardNavigation.kt +++ b/app/src/main/java/dev/medzik/librepass/android/ui/screens/dashboard/DashboardNavigation.kt @@ -27,11 +27,11 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import dev.medzik.android.components.ElevationTokens +import dev.medzik.android.components.navigate import dev.medzik.librepass.android.R import dev.medzik.librepass.android.ui.Screen import dev.medzik.librepass.android.ui.screens.dashboard.settings.SettingsScreen import dev.medzik.librepass.android.utils.TopBar -import dev.medzik.librepass.android.utils.navigation.navigate enum class DashboardNavigationItem(val route: String, val icon: ImageVector, val titleId: Int) { Dashboard("dashboard", Icons.Default.Lock, R.string.DashboardBottomNav_Dashboard), diff --git a/app/src/main/java/dev/medzik/librepass/android/ui/screens/dashboard/DashboardScreen.kt b/app/src/main/java/dev/medzik/librepass/android/ui/screens/dashboard/DashboardScreen.kt index f37c1446..1ff21fdd 100644 --- a/app/src/main/java/dev/medzik/librepass/android/ui/screens/dashboard/DashboardScreen.kt +++ b/app/src/main/java/dev/medzik/librepass/android/ui/screens/dashboard/DashboardScreen.kt @@ -12,6 +12,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.navigation.NavController +import dev.medzik.android.components.navigate import dev.medzik.librepass.android.data.CipherTable import dev.medzik.librepass.android.data.getRepository import dev.medzik.librepass.android.ui.Argument @@ -19,7 +20,6 @@ import dev.medzik.librepass.android.ui.Screen import dev.medzik.librepass.android.ui.composables.CipherCard import dev.medzik.librepass.android.utils.SecretStore.getUserSecrets import dev.medzik.librepass.android.utils.exception.handle -import dev.medzik.librepass.android.utils.navigation.navigate import dev.medzik.librepass.android.utils.rememberLoadingState import dev.medzik.librepass.client.Server import dev.medzik.librepass.client.api.CipherClient @@ -159,13 +159,13 @@ fun DashboardScreen(navController: NavController) { onClick = { cipher -> navController.navigate( screen = Screen.CipherView, - argument = Argument.CipherId to cipher.id.toString() + args = arrayOf(Argument.CipherId to cipher.id.toString()) ) }, onEdit = { cipher -> navController.navigate( screen = Screen.CipherEdit, - argument = Argument.CipherId to cipher.id.toString() + args = arrayOf(Argument.CipherId to cipher.id.toString()) ) }, onDelete = { cipher -> diff --git a/app/src/main/java/dev/medzik/librepass/android/ui/screens/dashboard/settings/Settings.kt b/app/src/main/java/dev/medzik/librepass/android/ui/screens/dashboard/settings/Settings.kt index 9cdc8475..a686ebb4 100644 --- a/app/src/main/java/dev/medzik/librepass/android/ui/screens/dashboard/settings/Settings.kt +++ b/app/src/main/java/dev/medzik/librepass/android/ui/screens/dashboard/settings/Settings.kt @@ -10,9 +10,9 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource import androidx.navigation.NavController import dev.medzik.android.components.PreferenceEntry +import dev.medzik.android.components.navigate import dev.medzik.librepass.android.R import dev.medzik.librepass.android.ui.Screen -import dev.medzik.librepass.android.utils.navigation.navigate @Composable fun SettingsScreen(navController: NavController) { diff --git a/app/src/main/java/dev/medzik/librepass/android/ui/screens/dashboard/settings/SettingsAccount.kt b/app/src/main/java/dev/medzik/librepass/android/ui/screens/dashboard/settings/SettingsAccount.kt index 8dfdd244..ee956143 100644 --- a/app/src/main/java/dev/medzik/librepass/android/ui/screens/dashboard/settings/SettingsAccount.kt +++ b/app/src/main/java/dev/medzik/librepass/android/ui/screens/dashboard/settings/SettingsAccount.kt @@ -12,12 +12,12 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.navigation.NavController import dev.medzik.android.components.PreferenceEntry +import dev.medzik.android.components.navigate import dev.medzik.librepass.android.R import dev.medzik.librepass.android.data.getRepository import dev.medzik.librepass.android.ui.Screen import dev.medzik.librepass.android.utils.TopBar import dev.medzik.librepass.android.utils.TopBarBackIcon -import dev.medzik.librepass.android.utils.navigation.navigate import kotlinx.coroutines.runBlocking @Composable diff --git a/app/src/main/java/dev/medzik/librepass/android/utils/navigation/Navigation.kt b/app/src/main/java/dev/medzik/librepass/android/utils/navigation/Navigation.kt deleted file mode 100644 index 0d7bf3c7..00000000 --- a/app/src/main/java/dev/medzik/librepass/android/utils/navigation/Navigation.kt +++ /dev/null @@ -1,59 +0,0 @@ -package dev.medzik.librepass.android.utils.navigation - -import androidx.navigation.NavController -import androidx.navigation.NavOptionsBuilder -import dev.medzik.librepass.android.ui.Argument -import dev.medzik.librepass.android.ui.Screen - -/** - * Get string argument from current screen in [NavController]. - */ -fun NavController.getString(argument: Argument): String? { - return currentBackStackEntry?.arguments?.getString(argument.name) -} - -/** - * Navigate to [Screen] with given [argument]. - * @param screen [Screen] to navigate to. - * @param argument Pair of [Argument] and [String]. - * @param disableBack [Boolean] to disable back navigation. - */ -fun NavController.navigate( - screen: Screen, - argument: Pair, - disableBack: Boolean = false, - options: (NavOptionsBuilder.() -> Unit)? = null -) { - navigate( - route = screen.fill(argument), - builder = { - if (disableBack) - popUpTo(graph.startDestinationId) { inclusive = true } - - if (options != null) - options() - } - ) -} - -/** - * Navigate to [Screen] without arguments. - * @param screen [Screen] to navigate to. - * @param disableBack [Boolean] to disable back navigation. - */ -fun NavController.navigate( - screen: Screen, - disableBack: Boolean = false, - options: (NavOptionsBuilder.() -> Unit)? = null -) { - navigate( - route = screen.fill(), - builder = { - if (disableBack) - popUpTo(graph.startDestinationId) { inclusive = true } - - if (options != null) - options() - } - ) -}