diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/AccountSecurityScreen.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/AccountSecurityScreen.kt index 29d5a490a..665acf033 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/AccountSecurityScreen.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/AccountSecurityScreen.kt @@ -39,6 +39,7 @@ import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect import com.x8bit.bitwarden.ui.platform.base.util.Text import com.x8bit.bitwarden.ui.platform.components.BitwardenExternalLinkRow import com.x8bit.bitwarden.ui.platform.components.BitwardenListHeaderText +import com.x8bit.bitwarden.ui.platform.components.BitwardenLoadingDialog import com.x8bit.bitwarden.ui.platform.components.BitwardenLogoutConfirmationDialog import com.x8bit.bitwarden.ui.platform.components.BitwardenScaffold import com.x8bit.bitwarden.ui.platform.components.BitwardenSelectionDialog @@ -48,6 +49,7 @@ import com.x8bit.bitwarden.ui.platform.components.BitwardenTextRow import com.x8bit.bitwarden.ui.platform.components.BitwardenTopAppBar import com.x8bit.bitwarden.ui.platform.components.BitwardenTwoButtonDialog import com.x8bit.bitwarden.ui.platform.components.BitwardenWideSwitch +import com.x8bit.bitwarden.ui.platform.components.LoadingDialogState import com.x8bit.bitwarden.ui.platform.components.dialog.BitwardenTimePickerDialog import com.x8bit.bitwarden.ui.platform.manager.biometrics.BiometricsManager import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager @@ -111,28 +113,18 @@ fun AccountSecurityScreen( } } - when (state.dialog) { - AccountSecurityDialog.ConfirmLogout -> BitwardenLogoutConfirmationDialog( - onDismissRequest = remember(viewModel) { - { viewModel.trySendAction(AccountSecurityAction.DismissDialog) } - }, - onConfirmClick = remember(viewModel) { - { viewModel.trySendAction(AccountSecurityAction.ConfirmLogoutClick) } - }, - ) - - AccountSecurityDialog.FingerprintPhrase -> FingerPrintPhraseDialog( - fingerprintPhrase = state.fingerprintPhrase, - onDismissRequest = remember(viewModel) { - { viewModel.trySendAction(AccountSecurityAction.DismissDialog) } - }, - onLearnMore = remember(viewModel) { - { viewModel.trySendAction(AccountSecurityAction.FingerPrintLearnMoreClick) } - }, - ) - - null -> Unit - } + AccountSecurityDialogs( + state = state, + onDismissRequest = remember(viewModel) { + { viewModel.trySendAction(AccountSecurityAction.DismissDialog) } + }, + onConfirmLogoutClick = remember(viewModel) { + { viewModel.trySendAction(AccountSecurityAction.ConfirmLogoutClick) } + }, + onFingerprintLearnMore = remember(viewModel) { + { viewModel.trySendAction(AccountSecurityAction.FingerPrintLearnMoreClick) } + }, + ) val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()) BitwardenScaffold( modifier = Modifier @@ -307,6 +299,33 @@ fun AccountSecurityScreen( } } +@Composable +private fun AccountSecurityDialogs( + state: AccountSecurityState, + onDismissRequest: () -> Unit, + onConfirmLogoutClick: () -> Unit, + onFingerprintLearnMore: () -> Unit, +) { + when (val dialogState = state.dialog) { + AccountSecurityDialog.ConfirmLogout -> BitwardenLogoutConfirmationDialog( + onDismissRequest = onDismissRequest, + onConfirmClick = onConfirmLogoutClick, + ) + + AccountSecurityDialog.FingerprintPhrase -> FingerPrintPhraseDialog( + fingerprintPhrase = state.fingerprintPhrase, + onDismissRequest = onDismissRequest, + onLearnMore = onFingerprintLearnMore, + ) + + is AccountSecurityDialog.Loading -> BitwardenLoadingDialog( + visibilityState = LoadingDialogState.Shown(text = dialogState.message), + ) + + null -> Unit + } +} + @Composable private fun UnlockWithBiometricsRow( isChecked: Boolean, diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/AccountSecurityViewModel.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/AccountSecurityViewModel.kt index d6b1cdffd..1df6829bc 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/AccountSecurityViewModel.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/AccountSecurityViewModel.kt @@ -323,6 +323,14 @@ sealed class AccountSecurityDialog : Parcelable { */ @Parcelize data object FingerprintPhrase : AccountSecurityDialog() + + /** + * Displays a loading dialog. + */ + @Parcelize + data class Loading( + val message: Text, + ) : AccountSecurityDialog() } /** diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/AccountSecurityScreenTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/AccountSecurityScreenTest.kt index c8c27b768..d471752dd 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/AccountSecurityScreenTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/settings/accountsecurity/AccountSecurityScreenTest.kt @@ -1329,6 +1329,22 @@ class AccountSecurityScreenTest : BaseComposeTest() { } } + @Test + fun `loading dialog should be displayed according to state`() { + val loadingMessage = "Loading" + composeTestRule.onNode(isDialog()).assertDoesNotExist() + composeTestRule.onNodeWithText(loadingMessage).assertDoesNotExist() + + mutableStateFlow.update { + it.copy(dialog = AccountSecurityDialog.Loading(loadingMessage.asText())) + } + + composeTestRule + .onNodeWithText("Loading") + .assertIsDisplayed() + .assert(hasAnyAncestor(isDialog())) + } + companion object { private val DEFAULT_STATE = AccountSecurityState( dialog = null,