Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Verification UI / UX iteration #3829

Merged
merged 8 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,14 @@ fun IncomingVerificationView(
@Composable
private fun IncomingVerificationHeader(step: Step) {
val iconStyle = when (step) {
Step.Canceled,
Step.Canceled -> BigIcon.Style.AlertSolid
is Step.Initial -> BigIcon.Style.Default(CompoundIcons.LockSolid())
is Step.Verifying -> BigIcon.Style.Default(CompoundIcons.Reaction())
Step.Completed -> BigIcon.Style.SuccessSolid
Step.Failure -> BigIcon.Style.AlertSolid
}
val titleTextId = when (step) {
Step.Canceled -> CommonStrings.common_verification_cancelled
Step.Canceled -> R.string.screen_session_verification_request_failure_title
is Step.Initial -> R.string.screen_session_verification_request_title
is Step.Verifying -> when (step.data) {
is SessionVerificationData.Decimals -> R.string.screen_session_verification_compare_numbers_title
Expand All @@ -97,7 +97,7 @@ private fun IncomingVerificationHeader(step: Step) {
Step.Failure -> R.string.screen_session_verification_request_failure_title
}
val subtitleTextId = when (step) {
Step.Canceled -> R.string.screen_session_verification_cancelled_subtitle
Step.Canceled -> R.string.screen_session_verification_request_failure_subtitle
is Step.Initial -> R.string.screen_session_verification_request_subtitle
is Step.Verifying -> when (step.data) {
is SessionVerificationData.Decimals -> R.string.screen_session_verification_compare_numbers_subtitle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ class VerifySelfSessionPresenter @AssistedInject constructor(
fun handleEvents(event: VerifySelfSessionViewEvents) {
Timber.d("Verification user action: ${event::class.simpleName}")
when (event) {
VerifySelfSessionViewEvents.UseAnotherDevice -> stateAndDispatch.dispatchAction(StateMachineEvent.UseAnotherDevice)
VerifySelfSessionViewEvents.RequestVerification -> stateAndDispatch.dispatchAction(StateMachineEvent.RequestVerification)
VerifySelfSessionViewEvents.StartSasVerification -> stateAndDispatch.dispatchAction(StateMachineEvent.StartSasVerification)
VerifySelfSessionViewEvents.ConfirmVerification -> stateAndDispatch.dispatchAction(StateMachineEvent.AcceptChallenge)
Expand Down Expand Up @@ -134,6 +135,9 @@ class VerifySelfSessionPresenter @AssistedInject constructor(
isLastDevice = encryptionService.isLastDevice.value
)
}
VerifySelfSessionStateMachine.State.UseAnotherDevice -> {
VerifySelfSessionState.Step.UseAnotherDevice
}
StateMachineState.RequestingVerification,
StateMachineState.StartingSasVerification,
StateMachineState.SasVerificationStarted,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ data class VerifySelfSessionState(

// FIXME canEnterRecoveryKey value is never read.
data class Initial(val canEnterRecoveryKey: Boolean, val isLastDevice: Boolean = false) : Step
data object UseAnotherDevice : Step
data object Canceled : Step
data object AwaitingOtherDeviceResponse : Step
data object Ready : Step
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ class VerifySelfSessionStateMachine @Inject constructor(
init {
spec {
inState<State.Initial> {
on { _: Event.UseAnotherDevice, state ->
state.override { State.UseAnotherDevice.andLogStateChange() }
}
}
inState<State.UseAnotherDevice> {
on { _: Event.RequestVerification, state ->
state.override { State.RequestingVerification.andLogStateChange() }
}
on { _: Event.StartSasVerification, state ->
state.override { State.StartingSasVerification.andLogStateChange() }
}
}
inState<State.RequestingVerification> {
onEnterEffect {
Expand All @@ -64,9 +66,6 @@ class VerifySelfSessionStateMachine @Inject constructor(
}
}
inState<State.Canceled> {
on { _: Event.RequestVerification, state ->
state.override { State.RequestingVerification.andLogStateChange() }
}
on { _: Event.Reset, state ->
state.override { State.Initial.andLogStateChange() }
}
Expand Down Expand Up @@ -119,6 +118,7 @@ class VerifySelfSessionStateMachine @Inject constructor(
on { _: Event.Cancel, state: MachineState<State> ->
when (state.snapshot) {
State.Initial, State.Completed, State.Canceled -> state.noChange()
State.UseAnotherDevice -> state.override { State.Initial.andLogStateChange() }
// For some reason `cancelVerification` is not calling its delegate `didCancel` method so we don't pass from
// `Canceling` state to `Canceled` automatically anymore
else -> {
Expand All @@ -144,6 +144,9 @@ class VerifySelfSessionStateMachine @Inject constructor(
/** The initial state, before verification started. */
data object Initial : State

/** Let the user know that they need to get ready on their other session. */
data object UseAnotherDevice : State

/** Waiting for verification acceptance. */
data object RequestingVerification : State

Expand Down Expand Up @@ -175,6 +178,9 @@ class VerifySelfSessionStateMachine @Inject constructor(
}

sealed interface Event {
/** User wants to use another session. */
data object UseAnotherDevice : Event

/** Request verification. */
data object RequestVerification : Event

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ open class VerifySelfSessionStateProvider : PreviewParameterProvider<VerifySelfS
aVerifySelfSessionState(
step = Step.Skipped
),
aVerifySelfSessionState(
step = Step.UseAnotherDevice
),
// Add other state here
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ fun VerifySelfSessionView(
fun cancelOrResetFlow() {
when (step) {
is Step.Canceled -> state.eventSink(VerifySelfSessionViewEvents.Reset)
is Step.AwaitingOtherDeviceResponse, Step.Ready -> state.eventSink(VerifySelfSessionViewEvents.Cancel)
is Step.AwaitingOtherDeviceResponse,
Step.UseAnotherDevice,
Step.Ready -> state.eventSink(VerifySelfSessionViewEvents.Cancel)
is Step.Verifying -> {
if (!step.state.isLoading()) {
state.eventSink(VerifySelfSessionViewEvents.DeclineVerification)
Expand Down Expand Up @@ -159,16 +161,20 @@ fun VerifySelfSessionView(
private fun VerifySelfSessionHeader(step: Step) {
val iconStyle = when (step) {
Step.Loading -> error("Should not happen")
is Step.Initial, Step.AwaitingOtherDeviceResponse -> BigIcon.Style.Default(CompoundIcons.LockSolid())
is Step.Initial -> BigIcon.Style.Default(CompoundIcons.LockSolid())
Step.UseAnotherDevice -> BigIcon.Style.Default(CompoundIcons.Devices())
Step.AwaitingOtherDeviceResponse -> BigIcon.Style.Default(CompoundIcons.Devices())
Step.Canceled -> BigIcon.Style.AlertSolid
Step.Ready, is Step.Verifying -> BigIcon.Style.Default(CompoundIcons.Reaction())
Step.Completed -> BigIcon.Style.SuccessSolid
is Step.Skipped -> return
}
val titleTextId = when (step) {
Step.Loading -> error("Should not happen")
is Step.Initial, Step.AwaitingOtherDeviceResponse -> R.string.screen_identity_confirmation_title
Step.Canceled -> CommonStrings.common_verification_cancelled
is Step.Initial -> R.string.screen_identity_confirmation_title
Step.UseAnotherDevice -> R.string.screen_session_verification_use_another_device_title
Step.AwaitingOtherDeviceResponse -> R.string.screen_session_verification_waiting_another_device_title
Step.Canceled -> CommonStrings.common_verification_failed
Step.Ready -> R.string.screen_session_verification_compare_emojis_title
Step.Completed -> R.string.screen_identity_confirmed_title
is Step.Verifying -> when (step.data) {
Expand All @@ -179,8 +185,10 @@ private fun VerifySelfSessionHeader(step: Step) {
}
val subtitleTextId = when (step) {
Step.Loading -> error("Should not happen")
is Step.Initial, Step.AwaitingOtherDeviceResponse -> R.string.screen_identity_confirmation_subtitle
Step.Canceled -> R.string.screen_session_verification_cancelled_subtitle
is Step.Initial -> R.string.screen_identity_confirmation_subtitle
Step.UseAnotherDevice -> R.string.screen_session_verification_use_another_device_subtitle
Step.AwaitingOtherDeviceResponse -> R.string.screen_session_verification_waiting_another_device_subtitle
Step.Canceled -> R.string.screen_session_verification_failed_subtitle
Step.Ready -> R.string.screen_session_verification_ready_subtitle
Step.Completed -> R.string.screen_identity_confirmed_subtitle
is Step.Verifying -> when (step.data) {
Expand Down Expand Up @@ -252,7 +260,7 @@ private fun VerifySelfSessionBottomMenu(
Button(
modifier = Modifier.fillMaxWidth(),
text = stringResource(R.string.screen_identity_use_another_device),
onClick = { eventSink(VerifySelfSessionViewEvents.RequestVerification) },
onClick = { eventSink(VerifySelfSessionViewEvents.UseAnotherDevice) },
)
}
Button(
Expand All @@ -267,18 +275,26 @@ private fun VerifySelfSessionBottomMenu(
)
}
}
is Step.Canceled -> {
is Step.UseAnotherDevice -> {
VerificationBottomMenu {
Button(
modifier = Modifier.fillMaxWidth(),
text = stringResource(R.string.screen_session_verification_positive_button_canceled),
text = stringResource(CommonStrings.action_start_verification),
onClick = { eventSink(VerifySelfSessionViewEvents.RequestVerification) },
)
TextButton(
// Placeholder so the 1st button keeps its vertical position
Spacer(modifier = Modifier.height(40.dp))
}
}
is Step.Canceled -> {
VerificationBottomMenu {
Button(
modifier = Modifier.fillMaxWidth(),
text = stringResource(CommonStrings.action_cancel),
text = stringResource(CommonStrings.action_done),
onClick = onCancelClick,
)
// Placeholder so the 1st button keeps its vertical position
Spacer(modifier = Modifier.height(40.dp))
}
}
is Step.Ready -> {
Expand All @@ -302,6 +318,7 @@ private fun VerifySelfSessionBottomMenu(
text = stringResource(R.string.screen_identity_waiting_on_other_device),
onClick = {},
showProgress = true,
enabled = false,
)
// Placeholder so the 1st button keeps its vertical position
Spacer(modifier = Modifier.height(40.dp))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package io.element.android.features.verifysession.impl.outgoing

sealed interface VerifySelfSessionViewEvents {
data object UseAnotherDevice : VerifySelfSessionViewEvents
data object RequestVerification : VerifySelfSessionViewEvents
data object StartSasVerification : VerifySelfSessionViewEvents
data object ConfirmVerification : VerifySelfSessionViewEvents
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
<string name="screen_session_verification_request_title">"Verification requested"</string>
<string name="screen_session_verification_they_dont_match">"They don’t match"</string>
<string name="screen_session_verification_they_match">"They match"</string>
<string name="screen_session_verification_use_another_device_subtitle">"Make sure you have the app open in the other device before starting verification from here."</string>
<string name="screen_session_verification_use_another_device_title">"Open the app on another verified device"</string>
<string name="screen_session_verification_waiting_another_device_subtitle">"You should see a popup on the other device. Start the verification from there now."</string>
<string name="screen_session_verification_waiting_another_device_title">"Start verification on the other device"</string>
<string name="screen_session_verification_waiting_to_accept_subtitle">"Accept the request to start the verification process in your other session to continue."</string>
<string name="screen_session_verification_waiting_to_accept_title">"Waiting to accept request"</string>
<string name="screen_signout_in_progress_dialog_content">"Signing out…"</string>
Expand Down
Loading
Loading