Improve session recovery screens (#2657)

* Improve enter recovery key screen UI

* Add instructions to reset the encryption of the logged in account.

* Update screenshots

* Fix maestro flow

---------

Co-authored-by: ElementBot <benoitm+elementbot@element.io>
This commit is contained in:
Jorge Martin Espinosa 2024-04-09 19:01:06 +02:00 committed by GitHub
parent fcf1e6be27
commit 3436351619
164 changed files with 765 additions and 358 deletions

View file

@ -34,17 +34,7 @@ class VerifySelfSessionNode @AssistedInject constructor(
@Assisted plugins: List<Plugin>,
private val presenter: VerifySelfSessionPresenter,
) : Node(buildContext, plugins = plugins) {
private fun onEnterRecoveryKey() {
plugins<VerifySessionEntryPoint.Callback>().forEach {
it.onEnterRecoveryKey()
}
}
private fun onDone() {
plugins<VerifySessionEntryPoint.Callback>().forEach {
it.onDone()
}
}
private val callback = plugins<VerifySessionEntryPoint.Callback>().first()
@Composable
override fun View(modifier: Modifier) {
@ -52,8 +42,9 @@ class VerifySelfSessionNode @AssistedInject constructor(
VerifySelfSessionView(
state = state,
modifier = modifier,
onEnterRecoveryKey = ::onEnterRecoveryKey,
onFinished = ::onDone,
onEnterRecoveryKey = callback::onEnterRecoveryKey,
onCreateNewRecoveryKey = callback::onCreateNewRecoveryKey,
onFinished = callback::onDone,
)
}
}

View file

@ -103,7 +103,7 @@ class VerifySelfSessionPresenter @Inject constructor(
): VerifySelfSessionState.VerificationStep =
when (val machineState = this) {
StateMachineState.Initial, null -> {
VerifySelfSessionState.VerificationStep.Initial(canEnterRecoveryKey = canEnterRecoveryKey)
VerifySelfSessionState.VerificationStep.Initial(canEnterRecoveryKey = canEnterRecoveryKey, isLastDevice = encryptionService.isLastDevice.value)
}
StateMachineState.RequestingVerification,
StateMachineState.StartingSasVerification,

View file

@ -29,7 +29,7 @@ data class VerifySelfSessionState(
) {
@Stable
sealed interface VerificationStep {
data class Initial(val canEnterRecoveryKey: Boolean) : VerificationStep
data class Initial(val canEnterRecoveryKey: Boolean, val isLastDevice: Boolean) : VerificationStep
data object Canceled : VerificationStep
data object AwaitingOtherDeviceResponse : VerificationStep
data object Ready : VerificationStep

View file

@ -17,6 +17,7 @@
package io.element.android.features.verifysession.impl
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.verifysession.impl.VerifySelfSessionState.VerificationStep
import io.element.android.libraries.architecture.AsyncData
import io.element.android.libraries.matrix.api.verification.SessionVerificationData
import io.element.android.libraries.matrix.api.verification.VerificationEmoji
@ -26,28 +27,31 @@ open class VerifySelfSessionStateProvider : PreviewParameterProvider<VerifySelfS
get() = sequenceOf(
aVerifySelfSessionState(displaySkipButton = true),
aVerifySelfSessionState(
verificationFlowStep = VerifySelfSessionState.VerificationStep.AwaitingOtherDeviceResponse
verificationFlowStep = VerificationStep.AwaitingOtherDeviceResponse
),
aVerifySelfSessionState(
verificationFlowStep = VerifySelfSessionState.VerificationStep.Verifying(aEmojisSessionVerificationData(), AsyncData.Uninitialized)
verificationFlowStep = VerificationStep.Verifying(aEmojisSessionVerificationData(), AsyncData.Uninitialized)
),
aVerifySelfSessionState(
verificationFlowStep = VerifySelfSessionState.VerificationStep.Verifying(aEmojisSessionVerificationData(), AsyncData.Loading())
verificationFlowStep = VerificationStep.Verifying(aEmojisSessionVerificationData(), AsyncData.Loading())
),
aVerifySelfSessionState(
verificationFlowStep = VerifySelfSessionState.VerificationStep.Canceled
verificationFlowStep = VerificationStep.Canceled
),
aVerifySelfSessionState(
verificationFlowStep = VerifySelfSessionState.VerificationStep.Ready
verificationFlowStep = VerificationStep.Ready
),
aVerifySelfSessionState(
verificationFlowStep = VerifySelfSessionState.VerificationStep.Verifying(aDecimalsSessionVerificationData(), AsyncData.Uninitialized)
verificationFlowStep = VerificationStep.Verifying(aDecimalsSessionVerificationData(), AsyncData.Uninitialized)
),
aVerifySelfSessionState(
verificationFlowStep = VerifySelfSessionState.VerificationStep.Initial(true)
verificationFlowStep = VerificationStep.Initial(canEnterRecoveryKey = true, isLastDevice = false)
),
aVerifySelfSessionState(
verificationFlowStep = VerifySelfSessionState.VerificationStep.Completed,
verificationFlowStep = VerificationStep.Initial(canEnterRecoveryKey = true, isLastDevice = true)
),
aVerifySelfSessionState(
verificationFlowStep = VerificationStep.Completed,
displaySkipButton = true,
),
// Add other state here
@ -67,7 +71,7 @@ private fun aDecimalsSessionVerificationData(
}
internal fun aVerifySelfSessionState(
verificationFlowStep: VerifySelfSessionState.VerificationStep = VerifySelfSessionState.VerificationStep.Initial(false),
verificationFlowStep: VerificationStep = VerificationStep.Initial(canEnterRecoveryKey = false, isLastDevice = false),
displaySkipButton: Boolean = false,
eventSink: (VerifySelfSessionViewEvents) -> Unit = {},
) = VerifySelfSessionState(

View file

@ -66,6 +66,7 @@ import io.element.android.features.verifysession.impl.VerifySelfSessionState.Ver
fun VerifySelfSessionView(
state: VerifySelfSessionState,
onEnterRecoveryKey: () -> Unit,
onCreateNewRecoveryKey: () -> Unit,
onFinished: () -> Unit,
modifier: Modifier = Modifier,
) {
@ -114,6 +115,7 @@ fun VerifySelfSessionView(
screenState = state,
goBack = ::resetFlow,
onEnterRecoveryKey = onEnterRecoveryKey,
onCreateNewRecoveryKey = onCreateNewRecoveryKey,
onFinished = onFinished,
)
}
@ -226,6 +228,7 @@ private fun EmojiItemView(emoji: VerificationEmoji, modifier: Modifier = Modifie
private fun BottomMenu(
screenState: VerifySelfSessionState,
onEnterRecoveryKey: () -> Unit,
onCreateNewRecoveryKey: () -> Unit,
goBack: () -> Unit,
onFinished: () -> Unit,
) {
@ -236,12 +239,21 @@ private fun BottomMenu(
when (verificationViewState) {
is FlowStep.Initial -> {
BottomMenu(
positiveButtonTitle = stringResource(R.string.screen_identity_use_another_device),
onPositiveButtonClicked = { eventSink(VerifySelfSessionViewEvents.RequestVerification) },
negativeButtonTitle = stringResource(R.string.screen_session_verification_enter_recovery_key),
onNegativeButtonClicked = onEnterRecoveryKey,
)
if (verificationViewState.isLastDevice) {
BottomMenu(
positiveButtonTitle = stringResource(R.string.screen_session_verification_enter_recovery_key),
onPositiveButtonClicked = onEnterRecoveryKey,
negativeButtonTitle = stringResource(R.string.screen_identity_confirmation_create_new_recovery_key),
onNegativeButtonClicked = onCreateNewRecoveryKey,
)
} else {
BottomMenu(
positiveButtonTitle = stringResource(R.string.screen_identity_use_another_device),
onPositiveButtonClicked = { eventSink(VerifySelfSessionViewEvents.RequestVerification) },
negativeButtonTitle = stringResource(R.string.screen_session_verification_enter_recovery_key),
onNegativeButtonClicked = onEnterRecoveryKey,
)
}
}
is FlowStep.Canceled -> {
BottomMenu(
@ -334,6 +346,7 @@ internal fun VerifySelfSessionViewPreview(@PreviewParameter(VerifySelfSessionSta
VerifySelfSessionView(
state = state,
onEnterRecoveryKey = {},
onCreateNewRecoveryKey = {},
onFinished = {},
)
}