From d6cb2b25c5cdddda1b2761c1ec9f85a5230c34d5 Mon Sep 17 00:00:00 2001 From: Ramsey Smith <142836716+ramsey-livefront@users.noreply.github.com> Date: Mon, 29 Apr 2024 08:05:15 -0600 Subject: [PATCH] BIT-2214: Sync complete toast (#1305) --- .../feature/settings/other/OtherScreen.kt | 12 +++++++++ .../feature/settings/other/OtherViewModel.kt | 25 +++++++++++++++++++ .../settings/other/OtherViewModelTest.kt | 13 ++++++++++ 3 files changed, 50 insertions(+) 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 a9000aeb8..800354b99 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 @@ -1,5 +1,6 @@ package com.x8bit.bitwarden.ui.platform.feature.settings.other +import android.widget.Toast import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -24,6 +25,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp @@ -55,9 +57,19 @@ fun OtherScreen( viewModel: OtherViewModel = hiltViewModel(), ) { val state by viewModel.stateFlow.collectAsState() + val context = LocalContext.current EventsEffect(viewModel = viewModel) { event -> when (event) { OtherEvent.NavigateBack -> onNavigateBack.invoke() + is OtherEvent.ShowToast -> { + Toast + .makeText( + context, + event.message(context.resources), + Toast.LENGTH_SHORT, + ) + .show() + } } } 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 a19f32a01..1ee361d74 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 @@ -12,6 +12,7 @@ import com.x8bit.bitwarden.ui.platform.base.util.Text import com.x8bit.bitwarden.ui.platform.base.util.asText import com.x8bit.bitwarden.ui.platform.util.toFormattedPattern import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach @@ -53,6 +54,13 @@ class OtherViewModel @Inject constructor( .map { OtherAction.Internal.VaultLastSyncReceive(it) } .onEach(::sendAction) .launchIn(viewModelScope) + + settingsRepo + .vaultLastSyncStateFlow + .drop(1) + .map { OtherAction.Internal.ManualVaultSyncReceive } + .onEach(::sendAction) + .launchIn(viewModelScope) } override fun handleAction(action: OtherAction): Unit = when (action) { @@ -97,6 +105,7 @@ class OtherViewModel @Inject constructor( private fun handleInternalAction(action: OtherAction.Internal) { when (action) { is OtherAction.Internal.VaultLastSyncReceive -> handleVaultDataReceive(action) + is OtherAction.Internal.ManualVaultSyncReceive -> handleManualVaultSyncReceive() } } @@ -111,6 +120,10 @@ class OtherViewModel @Inject constructor( ) } } + + private fun handleManualVaultSyncReceive() { + sendEvent(OtherEvent.ShowToast(R.string.syncing_complete.asText())) + } } /** @@ -146,6 +159,13 @@ sealed class OtherEvent { * Navigate back. */ data object NavigateBack : OtherEvent() + + /** + * Show a toast with the given message. + */ + data class ShowToast( + val message: Text, + ) : OtherEvent() } /** @@ -193,5 +213,10 @@ sealed class OtherAction { data class VaultLastSyncReceive( val vaultLastSyncTime: Instant?, ) : Internal() + + /** + * Indicates a manual vault sync has been received. + */ + data object ManualVaultSyncReceive : Internal() } } 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 d85f2d974..6d13125e1 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 @@ -166,6 +166,19 @@ class OtherViewModelTest : BaseViewModelTest() { verify { vaultRepository.sync() } } + @Test + fun `ManualVaultSyncReceive should emit ShowToast`() = runTest { + val newSyncTime = Instant.parse("2023-10-27T12:00:00Z") + val viewModel = createViewModel() + viewModel.eventFlow.test { + mutableVaultLastSyncStateFlow.tryEmit(newSyncTime) + assertEquals( + OtherEvent.ShowToast(R.string.syncing_complete.asText()), + awaitItem(), + ) + } + } + private fun createViewModel( state: OtherState? = null, ) = OtherViewModel(