diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/other/OtherScreen.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/other/OtherScreen.kt index 260c6e94b7..ff2cbbf1de 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/other/OtherScreen.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/other/OtherScreen.kt @@ -31,6 +31,7 @@ import androidx.hilt.navigation.compose.hiltViewModel import com.x8bit.bitwarden.R import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect import com.x8bit.bitwarden.ui.platform.components.BitwardenFilledTonalButton +import com.x8bit.bitwarden.ui.platform.components.BitwardenLoadingDialog import com.x8bit.bitwarden.ui.platform.components.BitwardenScaffold import com.x8bit.bitwarden.ui.platform.components.BitwardenSelectionDialog import com.x8bit.bitwarden.ui.platform.components.BitwardenSelectionRow @@ -38,6 +39,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 /** * Displays the other screen. @@ -56,6 +58,10 @@ fun OtherScreen( } } + OtherDialogs( + dialogState = state.dialogState, + ) + val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState()) BitwardenScaffold( modifier = Modifier @@ -224,3 +230,16 @@ private fun ClearClipboardFrequencyRow( } } } + +@Composable +private fun OtherDialogs( + dialogState: OtherState.DialogState?, +) { + when (dialogState) { + is OtherState.DialogState.Loading -> BitwardenLoadingDialog( + visibilityState = LoadingDialogState.Shown(dialogState.message), + ) + + null -> Unit + } +} diff --git a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/other/OtherViewModel.kt b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/other/OtherViewModel.kt index dd170efb60..c57dee1154 100644 --- a/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/other/OtherViewModel.kt +++ b/app/src/main/java/com/x8bit/bitwarden/ui/platform/feature/settings/other/OtherViewModel.kt @@ -30,6 +30,7 @@ class OtherViewModel @Inject constructor( allowSyncOnRefresh = settingsRepo.getPullToRefreshEnabledFlow().value, clearClipboardFrequency = OtherState.ClearClipboardFrequency.DEFAULT, lastSyncTime = "5/14/2023 4:52 PM", + dialogState = null, ), ) { override fun handleAction(action: OtherAction): Unit = when (action) { @@ -80,6 +81,7 @@ data class OtherState( val allowSyncOnRefresh: Boolean, val clearClipboardFrequency: ClearClipboardFrequency, val lastSyncTime: String, + val dialogState: DialogState?, ) : Parcelable { /** * Represents the different frequencies with which the user clipboard can be cleared. @@ -93,6 +95,19 @@ data class OtherState( TWO_MINUTES(text = R.string.two_minutes.asText()), FIVE_MINUTES(text = R.string.five_minutes.asText()), } + + /** + * Represents the current state of any dialogs on the screen. + */ + sealed class DialogState : Parcelable { + /** + * Represents a loading dialog with the given [message]. + */ + @Parcelize + data class Loading( + val message: Text, + ) : DialogState() + } } /** diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/settings/other/OtherScreenTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/settings/other/OtherScreenTest.kt index 69aa85b7ea..8e13ce7c7e 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/settings/other/OtherScreenTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/settings/other/OtherScreenTest.kt @@ -1,5 +1,6 @@ package com.x8bit.bitwarden.ui.platform.feature.settings.other +import androidx.compose.ui.test.assert import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.filterToOne import androidx.compose.ui.test.hasAnyAncestor @@ -10,11 +11,13 @@ import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import com.x8bit.bitwarden.data.platform.repository.util.bufferedMutableSharedFlow import com.x8bit.bitwarden.ui.platform.base.BaseComposeTest +import com.x8bit.bitwarden.ui.platform.base.util.asText import com.x8bit.bitwarden.ui.util.assertNoDialogExists import io.mockk.every import io.mockk.mockk import io.mockk.verify import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.update import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test @@ -124,6 +127,22 @@ class OtherScreenTest : BaseComposeTest() { mutableEventFlow.tryEmit(OtherEvent.NavigateBack) assertTrue(haveCalledNavigateBack) } + + @Test + fun `loading dialog should be displayed according to state`() { + val loadingMessage = "syncing" + composeTestRule.onNode(isDialog()).assertDoesNotExist() + composeTestRule.onNodeWithText(loadingMessage).assertDoesNotExist() + + mutableStateFlow.update { + it.copy(dialogState = OtherState.DialogState.Loading(loadingMessage.asText())) + } + + composeTestRule + .onNodeWithText(loadingMessage) + .assertIsDisplayed() + .assert(hasAnyAncestor(isDialog())) + } } private val DEFAULT_STATE = OtherState( @@ -131,4 +150,5 @@ private val DEFAULT_STATE = OtherState( allowSyncOnRefresh = false, clearClipboardFrequency = OtherState.ClearClipboardFrequency.DEFAULT, lastSyncTime = "5/14/2023 4:52 PM", + dialogState = null, ) diff --git a/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/settings/other/OtherViewModelTest.kt b/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/settings/other/OtherViewModelTest.kt index 18ad2e5848..37b3a2d313 100644 --- a/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/settings/other/OtherViewModelTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/ui/platform/feature/settings/other/OtherViewModelTest.kt @@ -130,6 +130,7 @@ class OtherViewModelTest : BaseViewModelTest() { allowSyncOnRefresh = false, clearClipboardFrequency = OtherState.ClearClipboardFrequency.DEFAULT, lastSyncTime = "5/14/2023 4:52 PM", + dialogState = null, ) } }