BIT-1563: Handle POST auth-requests error on Login with Device (#828)

This commit is contained in:
Caleb Derosier
2024-01-28 09:34:51 -07:00
committed by Álison Fernandes
parent ab0cfdfdc2
commit fa551fa6ab
4 changed files with 79 additions and 56 deletions

View File

@@ -39,8 +39,10 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.ui.platform.base.util.EventsEffect
import com.x8bit.bitwarden.ui.platform.base.util.asText
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.BitwardenErrorContent
import com.x8bit.bitwarden.ui.platform.components.BitwardenScaffold
import com.x8bit.bitwarden.ui.platform.components.BitwardenTopAppBar
import com.x8bit.bitwarden.ui.platform.theme.LocalNonMaterialColors
@@ -91,6 +93,9 @@ fun LoginWithDeviceScreen(
is LoginWithDeviceState.ViewState.Content -> {
LoginWithDeviceScreenContent(
state = viewState,
onErrorDialogDismiss = remember(viewModel) {
{ viewModel.trySendAction(LoginWithDeviceAction.ErrorDialogDismiss) }
},
onResendNotificationClick = remember(viewModel) {
{ viewModel.trySendAction(LoginWithDeviceAction.ResendNotificationClick) }
},
@@ -101,13 +106,6 @@ fun LoginWithDeviceScreen(
)
}
is LoginWithDeviceState.ViewState.Error -> {
BitwardenErrorContent(
message = viewState.message(),
modifier = modifier,
)
}
LoginWithDeviceState.ViewState.Loading -> {
Column(
modifier = modifier,
@@ -127,10 +125,23 @@ fun LoginWithDeviceScreen(
@Composable
private fun LoginWithDeviceScreenContent(
state: LoginWithDeviceState.ViewState.Content,
onErrorDialogDismiss: () -> Unit,
onResendNotificationClick: () -> Unit,
onViewAllLogInOptionsClick: () -> Unit,
modifier: Modifier = Modifier,
) {
BitwardenBasicDialog(
visibilityState = if (state.shouldShowErrorDialog) {
BasicDialogState.Shown(
title = R.string.an_error_has_occurred.asText(),
message = R.string.generic_error_message.asText(),
)
} else {
BasicDialogState.Hidden
},
onDismissRequest = onErrorDialogDismiss,
)
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = modifier
@@ -210,7 +221,7 @@ private fun LoginWithDeviceScreenContent(
modifier = Modifier
.padding(horizontal = 64.dp)
.size(size = 16.dp),
)
)
} else {
BitwardenClickableText(
modifier = Modifier

View File

@@ -3,12 +3,9 @@ package com.x8bit.bitwarden.ui.auth.feature.loginwithdevice
import android.os.Parcelable
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import com.x8bit.bitwarden.R
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
import com.x8bit.bitwarden.data.auth.repository.model.AuthRequestResult
import com.x8bit.bitwarden.ui.platform.base.BaseViewModel
import com.x8bit.bitwarden.ui.platform.base.util.Text
import com.x8bit.bitwarden.ui.platform.base.util.asText
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
@@ -38,6 +35,7 @@ class LoginWithDeviceViewModel @Inject constructor(
override fun handleAction(action: LoginWithDeviceAction) {
when (action) {
LoginWithDeviceAction.CloseButtonClick -> handleCloseButtonClicked()
LoginWithDeviceAction.ErrorDialogDismiss -> handleErrorDialogDismissed()
LoginWithDeviceAction.ResendNotificationClick -> handleResendNotificationClicked()
LoginWithDeviceAction.ViewAllLogInOptionsClick -> handleViewAllLogInOptionsClicked()
@@ -51,6 +49,19 @@ class LoginWithDeviceViewModel @Inject constructor(
sendEvent(LoginWithDeviceEvent.NavigateBack)
}
private fun handleErrorDialogDismissed() {
val viewState = mutableStateFlow.value.viewState as? LoginWithDeviceState.ViewState.Content
if (viewState != null) {
mutableStateFlow.update {
it.copy(
viewState = viewState.copy(
shouldShowErrorDialog = false,
),
)
}
}
}
private fun handleResendNotificationClicked() {
sendNewAuthRequest()
}
@@ -69,17 +80,20 @@ class LoginWithDeviceViewModel @Inject constructor(
viewState = LoginWithDeviceState.ViewState.Content(
fingerprintPhrase = action.result.authRequest.fingerprint,
isResendNotificationLoading = false,
shouldShowErrorDialog = false,
),
)
}
}
is AuthRequestResult.Error -> {
// TODO BIT-1563 display error dialog
mutableStateFlow.update {
it.copy(
viewState = LoginWithDeviceState.ViewState.Error(
message = R.string.generic_error_message.asText(),
viewState = LoginWithDeviceState.ViewState.Content(
fingerprintPhrase = "",
isResendNotificationLoading = false,
shouldShowErrorDialog = true,
),
)
}
@@ -136,17 +150,6 @@ data class LoginWithDeviceState(
@Parcelize
data object Loading : ViewState()
/**
* Represents a state where the [LoginWithDeviceScreen] is unable to display data due to an
* error retrieving it.
*
* @property message The message to display on the error screen.
*/
@Parcelize
data class Error(
val message: Text,
) : ViewState()
/**
* Content state for the [LoginWithDeviceScreen] showing the actual content or items.
*
@@ -156,6 +159,7 @@ data class LoginWithDeviceState(
data class Content(
val fingerprintPhrase: String,
val isResendNotificationLoading: Boolean,
val shouldShowErrorDialog: Boolean,
) : ViewState()
}
}
@@ -186,6 +190,11 @@ sealed class LoginWithDeviceAction {
*/
data object CloseButtonClick : LoginWithDeviceAction()
/**
* Indicates that the error dialog was dismissed.
*/
data object ErrorDialogDismiss : LoginWithDeviceAction()
/**
* Indicates that the "Resend notification" text has been clicked.
*/