Add loading states and navigation events to LoginWithDeviceScreen. (#890)

This commit is contained in:
David Perez
2024-01-31 01:41:53 -06:00
committed by Álison Fernandes
parent a985cfaccc
commit d9d5eaeea2
5 changed files with 123 additions and 6 deletions

View File

@@ -93,6 +93,12 @@ fun NavGraphBuilder.authGraph(navController: NavHostController) {
)
loginWithDeviceDestination(
onNavigateBack = { navController.popBackStack() },
onNavigateToTwoFactorLogin = {
navController.navigateToTwoFactorLogin(
emailAddress = it,
password = null,
)
},
)
environmentDestination(
onNavigateBack = { navController.popBackStack() },

View File

@@ -36,12 +36,14 @@ fun NavController.navigateToLoginWithDevice(
*/
fun NavGraphBuilder.loginWithDeviceDestination(
onNavigateBack: () -> Unit,
onNavigateToTwoFactorLogin: (emailAddress: String) -> Unit,
) {
composableWithSlideTransitions(
route = LOGIN_WITH_DEVICE_ROUTE,
) {
LoginWithDeviceScreen(
onNavigateBack = onNavigateBack,
onNavigateToTwoFactorLogin = onNavigateToTwoFactorLogin,
)
}
}

View File

@@ -42,8 +42,12 @@ import com.x8bit.bitwarden.ui.platform.components.BasicDialogState
import com.x8bit.bitwarden.ui.platform.components.BitwardenBasicDialog
import com.x8bit.bitwarden.ui.platform.components.BitwardenClickableText
import com.x8bit.bitwarden.ui.platform.components.BitwardenLoadingContent
import com.x8bit.bitwarden.ui.platform.components.BitwardenLoadingDialog
import com.x8bit.bitwarden.ui.platform.components.BitwardenScaffold
import com.x8bit.bitwarden.ui.platform.components.BitwardenTopAppBar
import com.x8bit.bitwarden.ui.platform.components.LoadingDialogState
import com.x8bit.bitwarden.ui.platform.manager.intent.IntentManager
import com.x8bit.bitwarden.ui.platform.theme.LocalIntentManager
import com.x8bit.bitwarden.ui.platform.theme.LocalNonMaterialColors
import com.x8bit.bitwarden.ui.platform.theme.LocalNonMaterialTypography
@@ -55,13 +59,23 @@ import com.x8bit.bitwarden.ui.platform.theme.LocalNonMaterialTypography
@Composable
fun LoginWithDeviceScreen(
onNavigateBack: () -> Unit,
onNavigateToTwoFactorLogin: (emailAddress: String) -> Unit,
viewModel: LoginWithDeviceViewModel = hiltViewModel(),
intentManager: IntentManager = LocalIntentManager.current,
) {
val state by viewModel.stateFlow.collectAsStateWithLifecycle()
val context = LocalContext.current
EventsEffect(viewModel = viewModel) { event ->
when (event) {
LoginWithDeviceEvent.NavigateBack -> onNavigateBack()
is LoginWithDeviceEvent.NavigateToCaptcha -> {
intentManager.startCustomTabsActivity(uri = event.uri)
}
is LoginWithDeviceEvent.NavigateToTwoFactorLogin -> {
onNavigateToTwoFactorLogin(event.emailAddress)
}
is LoginWithDeviceEvent.ShowToast -> {
Toast.makeText(context, event.message, Toast.LENGTH_SHORT).show()
}
@@ -250,6 +264,10 @@ private fun LoginWithDeviceDialogs(
onDismissDialog: () -> Unit,
) {
when (state) {
is LoginWithDeviceState.DialogState.Loading -> BitwardenLoadingDialog(
visibilityState = LoadingDialogState.Shown(text = state.message),
)
is LoginWithDeviceState.DialogState.Error -> BitwardenBasicDialog(
visibilityState = BasicDialogState.Shown(
title = state.title,

View File

@@ -1,5 +1,6 @@
package com.x8bit.bitwarden.ui.auth.feature.loginwithdevice
import android.net.Uri
import android.os.Parcelable
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
@@ -47,10 +48,7 @@ class LoginWithDeviceViewModel @Inject constructor(
LoginWithDeviceAction.DismissDialog -> handleErrorDialogDismissed()
LoginWithDeviceAction.ResendNotificationClick -> handleResendNotificationClicked()
LoginWithDeviceAction.ViewAllLogInOptionsClick -> handleViewAllLogInOptionsClicked()
is LoginWithDeviceAction.Internal.NewAuthRequestResultReceive -> {
handleNewAuthRequestResultReceived(action)
}
is LoginWithDeviceAction.Internal -> handleInternalActions(action)
}
}
@@ -70,6 +68,14 @@ class LoginWithDeviceViewModel @Inject constructor(
sendEvent(LoginWithDeviceEvent.NavigateBack)
}
private fun handleInternalActions(action: LoginWithDeviceAction.Internal) {
when (action) {
is LoginWithDeviceAction.Internal.NewAuthRequestResultReceive -> {
handleNewAuthRequestResultReceived(action)
}
}
}
@Suppress("LongMethod")
private fun handleNewAuthRequestResultReceived(
action: LoginWithDeviceAction.Internal.NewAuthRequestResultReceive,
@@ -211,6 +217,14 @@ data class LoginWithDeviceState(
* Represents the current state of any dialogs on the screen.
*/
sealed class DialogState : Parcelable {
/**
* Displays an loading dialog to the user.
*/
@Parcelize
data class Loading(
val message: Text,
) : DialogState()
/**
* Displays an error dialog to the user.
*/
@@ -231,6 +245,18 @@ sealed class LoginWithDeviceEvent {
*/
data object NavigateBack : LoginWithDeviceEvent()
/**
* Navigates to the captcha verification screen.
*/
data class NavigateToCaptcha(val uri: Uri) : LoginWithDeviceEvent()
/**
* Navigates to the two-factor login screen.
*/
data class NavigateToTwoFactorLogin(
val emailAddress: String,
) : LoginWithDeviceEvent()
/**
* Shows a toast with the given [message].
*/