PM-10094: Disable double-navigation by default (#3660)
Some checks failed
Crowdin Push / Crowdin Push (push) Waiting to run
Scan / Check PR run (push) Failing after 0s
Scan / SAST scan (push) Has been skipped
Scan / Quality scan (push) Has been skipped
Test / Check PR run (push) Failing after 0s
Test / Test (push) Has been skipped

This commit is contained in:
Shannon Draeker 2024-08-01 15:31:04 -06:00 committed by GitHub
parent d0edca67c5
commit 055fbc1277
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 29 additions and 8 deletions

View file

@ -0,0 +1,8 @@
package com.x8bit.bitwarden.ui.platform.base.util
/**
* Almost all the events in the app involve navigation or toasts. To prevent accidentally
* navigating to the same view twice, by default, events are ignored if the view is not currently
* resumed. To avoid that restriction, specific events can implement [BackgroundEvent].
*/
interface BackgroundEvent

View file

@ -2,20 +2,32 @@ package com.x8bit.bitwarden.ui.platform.base.util
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.lifecycle.Lifecycle
import com.x8bit.bitwarden.ui.platform.base.BaseViewModel
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
/**
* Convenience method for observing event flow from [BaseViewModel].
*
* By default, events will only be consumed when the associated screen is
* resumed, to avoid bugs like duplicate navigation calls. To override
* this behavior, a given event type can implement [BackgroundEvent].
*/
@Composable
fun <E> EventsEffect(
viewModel: BaseViewModel<*, E, *>,
lifecycleOwner: Lifecycle = LocalLifecycleOwner.current.lifecycle,
handler: suspend (E) -> Unit,
) {
LaunchedEffect(key1 = Unit) {
viewModel.eventFlow
.filter {
it is BackgroundEvent ||
lifecycleOwner.currentState.isAtLeast(Lifecycle.State.RESUMED)
}
.onEach { handler.invoke(it) }
.launchIn(this)
}

View file

@ -37,6 +37,7 @@ import com.x8bit.bitwarden.data.vault.repository.model.TotpCodeResult
import com.x8bit.bitwarden.data.vault.repository.model.UpdateCipherResult
import com.x8bit.bitwarden.data.vault.repository.model.VaultData
import com.x8bit.bitwarden.ui.platform.base.BaseViewModel
import com.x8bit.bitwarden.ui.platform.base.util.BackgroundEvent
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
@ -2358,8 +2359,7 @@ sealed class VaultAddEditEvent {
/**
* Navigate the user to the tooltip URI.
*/
data object NavigateToTooltipUri :
VaultAddEditEvent()
data object NavigateToTooltipUri : VaultAddEditEvent()
/**
* Navigate to the QR code scan screen.
@ -2385,7 +2385,7 @@ sealed class VaultAddEditEvent {
*/
data class CompleteFido2Registration(
val result: Fido2RegisterCredentialResult,
) : VaultAddEditEvent()
) : BackgroundEvent, VaultAddEditEvent()
/**
* Perform user verification for a FIDO 2 credential operation.
@ -2394,7 +2394,7 @@ sealed class VaultAddEditEvent {
*/
data class Fido2UserVerification(
val isRequired: Boolean,
) : VaultAddEditEvent()
) : BackgroundEvent, VaultAddEditEvent()
}
/**

View file

@ -46,6 +46,7 @@ import com.x8bit.bitwarden.data.vault.repository.model.GenerateTotpResult
import com.x8bit.bitwarden.data.vault.repository.model.RemovePasswordSendResult
import com.x8bit.bitwarden.data.vault.repository.model.VaultData
import com.x8bit.bitwarden.ui.platform.base.BaseViewModel
import com.x8bit.bitwarden.ui.platform.base.util.BackgroundEvent
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
@ -2102,7 +2103,7 @@ sealed class VaultItemListingEvent {
*/
data class CompleteFido2Registration(
val result: Fido2RegisterCredentialResult,
) : VaultItemListingEvent()
) : BackgroundEvent, VaultItemListingEvent()
/**
* Perform user verification for a FIDO 2 credential operation.
@ -2110,7 +2111,7 @@ sealed class VaultItemListingEvent {
data class Fido2UserVerification(
val isRequired: Boolean,
val selectedCipherView: CipherView,
) : VaultItemListingEvent()
) : BackgroundEvent, VaultItemListingEvent()
/**
* FIDO 2 credential assertion result has been received and the process is ready to be
@ -2120,7 +2121,7 @@ sealed class VaultItemListingEvent {
*/
data class CompleteFido2Assertion(
val result: Fido2CredentialAssertionResult,
) : VaultItemListingEvent()
) : BackgroundEvent, VaultItemListingEvent()
/**
* FIDO 2 credential lookup result has been received and the process is ready to be completed.
@ -2129,7 +2130,7 @@ sealed class VaultItemListingEvent {
*/
data class CompleteFido2GetCredentialsRequest(
val result: Fido2GetCredentialsResult,
) : VaultItemListingEvent()
) : BackgroundEvent, VaultItemListingEvent()
}
/**