mirror of
https://github.com/bitwarden/android.git
synced 2026-06-07 23:58:03 -05:00
Adding navigation for generator modals (#627)
This commit is contained in:
committed by
Álison Fernandes
parent
61a162b6de
commit
cd4db46e13
@@ -10,6 +10,8 @@ import com.x8bit.bitwarden.ui.platform.feature.settings.folders.foldersDestinati
|
||||
import com.x8bit.bitwarden.ui.platform.feature.settings.folders.navigateToFolders
|
||||
import com.x8bit.bitwarden.ui.platform.feature.vaultunlockednavbar.VAULT_UNLOCKED_NAV_BAR_ROUTE
|
||||
import com.x8bit.bitwarden.ui.platform.feature.vaultunlockednavbar.vaultUnlockedNavBarDestination
|
||||
import com.x8bit.bitwarden.ui.tools.feature.generator.generatorModalDestination
|
||||
import com.x8bit.bitwarden.ui.tools.feature.generator.navigateToGeneratorModal
|
||||
import com.x8bit.bitwarden.ui.tools.feature.generator.passwordhistory.navigateToPasswordHistory
|
||||
import com.x8bit.bitwarden.ui.tools.feature.generator.passwordhistory.passwordHistoryDestination
|
||||
import com.x8bit.bitwarden.ui.tools.feature.send.addsend.addSendDestination
|
||||
@@ -70,6 +72,7 @@ fun NavGraphBuilder.vaultUnlockedGraph(
|
||||
navController.navigateToManualCodeEntryScreen()
|
||||
},
|
||||
onNavigateBack = { navController.popBackStack() },
|
||||
onNavigateToGeneratorModal = { navController.navigateToGeneratorModal(mode = it) },
|
||||
)
|
||||
vaultMoveToOrganizationDestination(
|
||||
onNavigateBack = { navController.popBackStack() },
|
||||
@@ -90,7 +93,6 @@ fun NavGraphBuilder.vaultUnlockedGraph(
|
||||
},
|
||||
onNavigateBack = { navController.popBackStack() },
|
||||
)
|
||||
|
||||
vaultManualCodeEntryDestination(
|
||||
onNavigateToQrCodeScreen = {
|
||||
navController.popBackStack()
|
||||
@@ -102,5 +104,6 @@ fun NavGraphBuilder.vaultUnlockedGraph(
|
||||
addSendDestination(onNavigateBack = { navController.popBackStack() })
|
||||
passwordHistoryDestination(onNavigateBack = { navController.popBackStack() })
|
||||
foldersDestination(onNavigateBack = { navController.popBackStack() })
|
||||
generatorModalDestination(onNavigateBack = { navController.popBackStack() })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ import com.x8bit.bitwarden.ui.platform.feature.settings.SETTINGS_GRAPH_ROUTE
|
||||
import com.x8bit.bitwarden.ui.platform.feature.settings.navigateToSettingsGraph
|
||||
import com.x8bit.bitwarden.ui.platform.feature.settings.settingsGraph
|
||||
import com.x8bit.bitwarden.ui.platform.theme.RootTransitionProviders
|
||||
import com.x8bit.bitwarden.ui.tools.feature.generator.GENERATOR_ROUTE
|
||||
import com.x8bit.bitwarden.ui.tools.feature.generator.GENERATOR_GRAPH_ROUTE
|
||||
import com.x8bit.bitwarden.ui.tools.feature.generator.generatorGraph
|
||||
import com.x8bit.bitwarden.ui.tools.feature.generator.navigateToGeneratorGraph
|
||||
import com.x8bit.bitwarden.ui.tools.feature.send.SEND_GRAPH_ROUTE
|
||||
@@ -345,7 +345,7 @@ private sealed class VaultUnlockedNavBarTab : Parcelable {
|
||||
override val iconRes get() = R.drawable.ic_generator
|
||||
override val labelRes get() = R.string.generator
|
||||
override val contentDescriptionRes get() = R.string.generator
|
||||
override val route get() = GENERATOR_ROUTE
|
||||
override val route get() = GENERATOR_GRAPH_ROUTE
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,7 @@ import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.navigation
|
||||
|
||||
private const val GENERATOR_GRAPH_ROUTE: String = "generator_graph"
|
||||
const val GENERATOR_GRAPH_ROUTE: String = "generator_graph"
|
||||
|
||||
/**
|
||||
* Add generator destination to the root nav graph.
|
||||
|
||||
@@ -1,20 +1,42 @@
|
||||
package com.x8bit.bitwarden.ui.tools.feature.generator
|
||||
|
||||
import androidx.lifecycle.SavedStateHandle
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.navArgument
|
||||
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.composableWithSlideTransitions
|
||||
import com.x8bit.bitwarden.ui.tools.feature.generator.model.GeneratorMode
|
||||
|
||||
/**
|
||||
* The functions below pertain to entry into the [GeneratorScreen].
|
||||
*/
|
||||
private const val GENERATOR_MODAL_ROUTE_PREFIX: String = "generator_modal"
|
||||
private const val GENERATOR_MODE_TYPE: String = "generator_mode_type"
|
||||
private const val USERNAME_GENERATOR: String = "username_generator"
|
||||
private const val PASSWORD_GENERATOR: String = "password_generator"
|
||||
|
||||
const val GENERATOR_ROUTE: String = "generator"
|
||||
private const val GENERATOR_MODAL_ROUTE: String =
|
||||
"$GENERATOR_MODAL_ROUTE_PREFIX/{$GENERATOR_MODE_TYPE}"
|
||||
|
||||
/**
|
||||
* Navigate to the [GeneratorScreen].
|
||||
* Class to retrieve vault item listing arguments from the [SavedStateHandle].
|
||||
*/
|
||||
fun NavController.navigateToGenerator(navOptions: NavOptions? = null) {
|
||||
navigate(GENERATOR_ROUTE, navOptions)
|
||||
@OmitFromCoverage
|
||||
data class GeneratorArgs(
|
||||
val type: GeneratorMode,
|
||||
) {
|
||||
constructor(savedStateHandle: SavedStateHandle) : this(
|
||||
type = when (savedStateHandle.get<String>(GENERATOR_MODE_TYPE)) {
|
||||
USERNAME_GENERATOR -> GeneratorMode.Modal.Username
|
||||
PASSWORD_GENERATOR -> GeneratorMode.Modal.Password
|
||||
else -> GeneratorMode.Default
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -26,6 +48,43 @@ fun NavGraphBuilder.generatorDestination(
|
||||
composable(GENERATOR_ROUTE) {
|
||||
GeneratorScreen(
|
||||
onNavigateToPasswordHistory = onNavigateToPasswordHistory,
|
||||
onNavigateBack = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the generator modal destination to the nav graph.
|
||||
*/
|
||||
fun NavGraphBuilder.generatorModalDestination(
|
||||
onNavigateBack: () -> Unit,
|
||||
) {
|
||||
composableWithSlideTransitions(
|
||||
route = GENERATOR_MODAL_ROUTE,
|
||||
arguments = listOf(
|
||||
navArgument(GENERATOR_MODE_TYPE) { type = NavType.StringType },
|
||||
),
|
||||
) {
|
||||
GeneratorScreen(
|
||||
onNavigateToPasswordHistory = {},
|
||||
onNavigateBack = onNavigateBack,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate to the generator screen in the username generation mode.
|
||||
*/
|
||||
fun NavController.navigateToGeneratorModal(
|
||||
mode: GeneratorMode.Modal,
|
||||
navOptions: NavOptions? = null,
|
||||
) {
|
||||
val generatorModeType = when (mode) {
|
||||
GeneratorMode.Modal.Password -> PASSWORD_GENERATOR
|
||||
GeneratorMode.Modal.Username -> USERNAME_GENERATOR
|
||||
}
|
||||
navigate(
|
||||
route = "$GENERATOR_MODAL_ROUTE_PREFIX/$generatorModeType",
|
||||
navOptions = navOptions,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -84,6 +84,7 @@ import kotlinx.collections.immutable.toImmutableList
|
||||
fun GeneratorScreen(
|
||||
viewModel: GeneratorViewModel = hiltViewModel(),
|
||||
onNavigateToPasswordHistory: () -> Unit,
|
||||
onNavigateBack: () -> Unit,
|
||||
) {
|
||||
val state by viewModel.stateFlow.collectAsStateWithLifecycle()
|
||||
val context = LocalContext.current
|
||||
@@ -1059,6 +1060,7 @@ private fun GeneratorPreview() {
|
||||
BitwardenTheme {
|
||||
GeneratorScreen(
|
||||
onNavigateToPasswordHistory = {},
|
||||
onNavigateBack = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Us
|
||||
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.ForwardedEmailAlias.ServiceType.SimpleLogin
|
||||
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.PlusAddressedEmail
|
||||
import com.x8bit.bitwarden.ui.tools.feature.generator.GeneratorState.MainType.Username.UsernameType.RandomWord
|
||||
import com.x8bit.bitwarden.ui.tools.feature.generator.model.GeneratorMode
|
||||
import com.x8bit.bitwarden.ui.tools.feature.generator.util.toUsernameGeneratorRequest
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Job
|
||||
@@ -50,6 +51,7 @@ import kotlinx.parcelize.Parcelize
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val KEY_STATE = "state"
|
||||
private const val KEY_GENERATOR_MODE = "key_generator_mode"
|
||||
|
||||
/**
|
||||
* ViewModel responsible for handling user interactions in the generator screen.
|
||||
@@ -73,6 +75,7 @@ class GeneratorViewModel @Inject constructor(
|
||||
selectedType = Passcode(
|
||||
selectedType = Password(),
|
||||
),
|
||||
generatorMode = GeneratorArgs(savedStateHandle).type,
|
||||
currentEmailAddress =
|
||||
requireNotNull(authRepository.userStateFlow.value?.activeAccount?.email),
|
||||
),
|
||||
@@ -1409,6 +1412,7 @@ class GeneratorViewModel @Inject constructor(
|
||||
data class GeneratorState(
|
||||
val generatedText: String,
|
||||
val selectedType: MainType,
|
||||
val generatorMode: GeneratorMode = GeneratorMode.Default,
|
||||
val currentEmailAddress: String,
|
||||
) : Parcelable {
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.x8bit.bitwarden.ui.tools.feature.generator.model
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
/**
|
||||
* A sealed class representing the mode in which the generator displays.
|
||||
*/
|
||||
sealed class GeneratorMode : Parcelable {
|
||||
/**
|
||||
* Represents the main or default generator mode.
|
||||
*/
|
||||
@Parcelize
|
||||
data object Default : GeneratorMode()
|
||||
|
||||
/**
|
||||
* A sealed class representing the types of modals in which the generator displays.
|
||||
*/
|
||||
@Parcelize
|
||||
sealed class Modal : GeneratorMode() {
|
||||
|
||||
/**
|
||||
* Represents the mode for generating passwords.
|
||||
*/
|
||||
@Parcelize
|
||||
data object Password : Modal()
|
||||
|
||||
/**
|
||||
* Represents the mode for generating usernames.
|
||||
*/
|
||||
@Parcelize
|
||||
data object Username : Modal()
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import androidx.navigation.NavType
|
||||
import androidx.navigation.navArgument
|
||||
import com.x8bit.bitwarden.data.platform.annotation.OmitFromCoverage
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.composableWithSlideTransitions
|
||||
import com.x8bit.bitwarden.ui.tools.feature.generator.model.GeneratorMode
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultAddEditType
|
||||
|
||||
private const val ADD_TYPE: String = "add"
|
||||
@@ -43,6 +44,7 @@ fun NavGraphBuilder.vaultAddEditDestination(
|
||||
onNavigateBack: () -> Unit,
|
||||
onNavigateToManualCodeEntryScreen: () -> Unit,
|
||||
onNavigateToQrCodeScanScreen: () -> Unit,
|
||||
onNavigateToGeneratorModal: (GeneratorMode.Modal) -> Unit,
|
||||
) {
|
||||
composableWithSlideTransitions(
|
||||
route = ADD_EDIT_ITEM_ROUTE,
|
||||
@@ -54,6 +56,7 @@ fun NavGraphBuilder.vaultAddEditDestination(
|
||||
onNavigateBack = onNavigateBack,
|
||||
onNavigateToManualCodeEntryScreen = onNavigateToManualCodeEntryScreen,
|
||||
onNavigateToQrCodeScanScreen = onNavigateToQrCodeScanScreen,
|
||||
onNavigateToGeneratorModal = onNavigateToGeneratorModal,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.x8bit.bitwarden.ui.platform.components.BitwardenScaffold
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenTextButton
|
||||
import com.x8bit.bitwarden.ui.platform.components.BitwardenTopAppBar
|
||||
import com.x8bit.bitwarden.ui.platform.components.LoadingDialogState
|
||||
import com.x8bit.bitwarden.ui.tools.feature.generator.model.GeneratorMode
|
||||
import com.x8bit.bitwarden.ui.vault.feature.addedit.handlers.VaultAddEditCardTypeHandlers
|
||||
import com.x8bit.bitwarden.ui.vault.feature.addedit.handlers.VaultAddEditCommonHandlers
|
||||
import com.x8bit.bitwarden.ui.vault.feature.addedit.handlers.VaultAddEditIdentityTypeHandlers
|
||||
@@ -50,6 +51,7 @@ fun VaultAddEditScreen(
|
||||
permissionsManager: PermissionsManager =
|
||||
PermissionsManagerImpl(LocalContext.current as Activity),
|
||||
onNavigateToManualCodeEntryScreen: () -> Unit,
|
||||
onNavigateToGeneratorModal: (GeneratorMode.Modal) -> Unit,
|
||||
) {
|
||||
val state by viewModel.stateFlow.collectAsStateWithLifecycle()
|
||||
val context = LocalContext.current
|
||||
@@ -65,6 +67,10 @@ fun VaultAddEditScreen(
|
||||
onNavigateToManualCodeEntryScreen()
|
||||
}
|
||||
|
||||
is VaultAddEditEvent.NavigateToGeneratorModal -> {
|
||||
onNavigateToGeneratorModal(event.generatorMode)
|
||||
}
|
||||
|
||||
is VaultAddEditEvent.ShowToast -> {
|
||||
Toast.makeText(context, event.message(resources), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.x8bit.bitwarden.ui.platform.base.BaseViewModel
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.Text
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.concat
|
||||
import com.x8bit.bitwarden.ui.tools.feature.generator.model.GeneratorMode
|
||||
import com.x8bit.bitwarden.ui.vault.feature.addedit.model.CustomFieldType
|
||||
import com.x8bit.bitwarden.ui.vault.feature.addedit.model.toCustomField
|
||||
import com.x8bit.bitwarden.ui.vault.feature.addedit.util.toViewState
|
||||
@@ -1316,6 +1317,13 @@ sealed class VaultAddEditEvent {
|
||||
* Navigate to the manual code entry screen.
|
||||
*/
|
||||
data object NavigateToManualCodeEntry : VaultAddEditEvent()
|
||||
|
||||
/**
|
||||
* Navigate to the generator modal.
|
||||
*/
|
||||
data class NavigateToGeneratorModal(
|
||||
val generatorMode: GeneratorMode.Modal,
|
||||
) : VaultAddEditEvent()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user