Session verification: add new screen to get ready on the other session.
This commit is contained in:
parent
4952c2f89f
commit
b8d6c47532
7 changed files with 41 additions and 5 deletions
|
|
@ -104,6 +104,7 @@ class VerifySelfSessionPresenter @AssistedInject constructor(
|
||||||
fun handleEvents(event: VerifySelfSessionViewEvents) {
|
fun handleEvents(event: VerifySelfSessionViewEvents) {
|
||||||
Timber.d("Verification user action: ${event::class.simpleName}")
|
Timber.d("Verification user action: ${event::class.simpleName}")
|
||||||
when (event) {
|
when (event) {
|
||||||
|
VerifySelfSessionViewEvents.UseAnotherDevice -> stateAndDispatch.dispatchAction(StateMachineEvent.UseAnotherDevice)
|
||||||
VerifySelfSessionViewEvents.RequestVerification -> stateAndDispatch.dispatchAction(StateMachineEvent.RequestVerification)
|
VerifySelfSessionViewEvents.RequestVerification -> stateAndDispatch.dispatchAction(StateMachineEvent.RequestVerification)
|
||||||
VerifySelfSessionViewEvents.StartSasVerification -> stateAndDispatch.dispatchAction(StateMachineEvent.StartSasVerification)
|
VerifySelfSessionViewEvents.StartSasVerification -> stateAndDispatch.dispatchAction(StateMachineEvent.StartSasVerification)
|
||||||
VerifySelfSessionViewEvents.ConfirmVerification -> stateAndDispatch.dispatchAction(StateMachineEvent.AcceptChallenge)
|
VerifySelfSessionViewEvents.ConfirmVerification -> stateAndDispatch.dispatchAction(StateMachineEvent.AcceptChallenge)
|
||||||
|
|
@ -134,6 +135,9 @@ class VerifySelfSessionPresenter @AssistedInject constructor(
|
||||||
isLastDevice = encryptionService.isLastDevice.value
|
isLastDevice = encryptionService.isLastDevice.value
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
VerifySelfSessionStateMachine.State.UseAnotherDevice -> {
|
||||||
|
VerifySelfSessionState.Step.UseAnotherDevice
|
||||||
|
}
|
||||||
StateMachineState.RequestingVerification,
|
StateMachineState.RequestingVerification,
|
||||||
StateMachineState.StartingSasVerification,
|
StateMachineState.StartingSasVerification,
|
||||||
StateMachineState.SasVerificationStarted,
|
StateMachineState.SasVerificationStarted,
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ data class VerifySelfSessionState(
|
||||||
|
|
||||||
// FIXME canEnterRecoveryKey value is never read.
|
// FIXME canEnterRecoveryKey value is never read.
|
||||||
data class Initial(val canEnterRecoveryKey: Boolean, val isLastDevice: Boolean = false) : Step
|
data class Initial(val canEnterRecoveryKey: Boolean, val isLastDevice: Boolean = false) : Step
|
||||||
|
data object UseAnotherDevice : Step
|
||||||
data object Canceled : Step
|
data object Canceled : Step
|
||||||
data object AwaitingOtherDeviceResponse : Step
|
data object AwaitingOtherDeviceResponse : Step
|
||||||
data object Ready : Step
|
data object Ready : Step
|
||||||
|
|
|
||||||
|
|
@ -38,12 +38,14 @@ class VerifySelfSessionStateMachine @Inject constructor(
|
||||||
init {
|
init {
|
||||||
spec {
|
spec {
|
||||||
inState<State.Initial> {
|
inState<State.Initial> {
|
||||||
|
on { _: Event.UseAnotherDevice, state ->
|
||||||
|
state.override { State.UseAnotherDevice.andLogStateChange() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inState<State.UseAnotherDevice> {
|
||||||
on { _: Event.RequestVerification, state ->
|
on { _: Event.RequestVerification, state ->
|
||||||
state.override { State.RequestingVerification.andLogStateChange() }
|
state.override { State.RequestingVerification.andLogStateChange() }
|
||||||
}
|
}
|
||||||
on { _: Event.StartSasVerification, state ->
|
|
||||||
state.override { State.StartingSasVerification.andLogStateChange() }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
inState<State.RequestingVerification> {
|
inState<State.RequestingVerification> {
|
||||||
onEnterEffect {
|
onEnterEffect {
|
||||||
|
|
@ -119,6 +121,7 @@ class VerifySelfSessionStateMachine @Inject constructor(
|
||||||
on { _: Event.Cancel, state: MachineState<State> ->
|
on { _: Event.Cancel, state: MachineState<State> ->
|
||||||
when (state.snapshot) {
|
when (state.snapshot) {
|
||||||
State.Initial, State.Completed, State.Canceled -> state.noChange()
|
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
|
// For some reason `cancelVerification` is not calling its delegate `didCancel` method so we don't pass from
|
||||||
// `Canceling` state to `Canceled` automatically anymore
|
// `Canceling` state to `Canceled` automatically anymore
|
||||||
else -> {
|
else -> {
|
||||||
|
|
@ -144,6 +147,9 @@ class VerifySelfSessionStateMachine @Inject constructor(
|
||||||
/** The initial state, before verification started. */
|
/** The initial state, before verification started. */
|
||||||
data object Initial : State
|
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. */
|
/** Waiting for verification acceptance. */
|
||||||
data object RequestingVerification : State
|
data object RequestingVerification : State
|
||||||
|
|
||||||
|
|
@ -175,6 +181,9 @@ class VerifySelfSessionStateMachine @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed interface Event {
|
sealed interface Event {
|
||||||
|
/** User wants to use another session. */
|
||||||
|
data object UseAnotherDevice : Event
|
||||||
|
|
||||||
/** Request verification. */
|
/** Request verification. */
|
||||||
data object RequestVerification : Event
|
data object RequestVerification : Event
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,9 @@ open class VerifySelfSessionStateProvider : PreviewParameterProvider<VerifySelfS
|
||||||
aVerifySelfSessionState(
|
aVerifySelfSessionState(
|
||||||
step = Step.Skipped
|
step = Step.Skipped
|
||||||
),
|
),
|
||||||
|
aVerifySelfSessionState(
|
||||||
|
step = Step.UseAnotherDevice
|
||||||
|
),
|
||||||
// Add other state here
|
// Add other state here
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,9 @@ fun VerifySelfSessionView(
|
||||||
fun cancelOrResetFlow() {
|
fun cancelOrResetFlow() {
|
||||||
when (step) {
|
when (step) {
|
||||||
is Step.Canceled -> state.eventSink(VerifySelfSessionViewEvents.Reset)
|
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 -> {
|
is Step.Verifying -> {
|
||||||
if (!step.state.isLoading()) {
|
if (!step.state.isLoading()) {
|
||||||
state.eventSink(VerifySelfSessionViewEvents.DeclineVerification)
|
state.eventSink(VerifySelfSessionViewEvents.DeclineVerification)
|
||||||
|
|
@ -159,6 +161,7 @@ fun VerifySelfSessionView(
|
||||||
private fun VerifySelfSessionHeader(step: Step) {
|
private fun VerifySelfSessionHeader(step: Step) {
|
||||||
val iconStyle = when (step) {
|
val iconStyle = when (step) {
|
||||||
Step.Loading -> error("Should not happen")
|
Step.Loading -> error("Should not happen")
|
||||||
|
Step.UseAnotherDevice -> BigIcon.Style.Default(CompoundIcons.Devices())
|
||||||
is Step.Initial, Step.AwaitingOtherDeviceResponse -> BigIcon.Style.Default(CompoundIcons.LockSolid())
|
is Step.Initial, Step.AwaitingOtherDeviceResponse -> BigIcon.Style.Default(CompoundIcons.LockSolid())
|
||||||
Step.Canceled -> BigIcon.Style.AlertSolid
|
Step.Canceled -> BigIcon.Style.AlertSolid
|
||||||
Step.Ready, is Step.Verifying -> BigIcon.Style.Default(CompoundIcons.Reaction())
|
Step.Ready, is Step.Verifying -> BigIcon.Style.Default(CompoundIcons.Reaction())
|
||||||
|
|
@ -167,6 +170,7 @@ private fun VerifySelfSessionHeader(step: Step) {
|
||||||
}
|
}
|
||||||
val titleTextId = when (step) {
|
val titleTextId = when (step) {
|
||||||
Step.Loading -> error("Should not happen")
|
Step.Loading -> error("Should not happen")
|
||||||
|
Step.UseAnotherDevice -> R.string.screen_session_verification_use_another_device_title
|
||||||
is Step.Initial, Step.AwaitingOtherDeviceResponse -> R.string.screen_identity_confirmation_title
|
is Step.Initial, Step.AwaitingOtherDeviceResponse -> R.string.screen_identity_confirmation_title
|
||||||
Step.Canceled -> CommonStrings.common_verification_cancelled
|
Step.Canceled -> CommonStrings.common_verification_cancelled
|
||||||
Step.Ready -> R.string.screen_session_verification_compare_emojis_title
|
Step.Ready -> R.string.screen_session_verification_compare_emojis_title
|
||||||
|
|
@ -179,6 +183,7 @@ private fun VerifySelfSessionHeader(step: Step) {
|
||||||
}
|
}
|
||||||
val subtitleTextId = when (step) {
|
val subtitleTextId = when (step) {
|
||||||
Step.Loading -> error("Should not happen")
|
Step.Loading -> error("Should not happen")
|
||||||
|
Step.UseAnotherDevice -> R.string.screen_session_verification_use_another_device_subtitle
|
||||||
is Step.Initial, Step.AwaitingOtherDeviceResponse -> R.string.screen_identity_confirmation_subtitle
|
is Step.Initial, Step.AwaitingOtherDeviceResponse -> R.string.screen_identity_confirmation_subtitle
|
||||||
Step.Canceled -> R.string.screen_session_verification_cancelled_subtitle
|
Step.Canceled -> R.string.screen_session_verification_cancelled_subtitle
|
||||||
Step.Ready -> R.string.screen_session_verification_ready_subtitle
|
Step.Ready -> R.string.screen_session_verification_ready_subtitle
|
||||||
|
|
@ -252,7 +257,7 @@ private fun VerifySelfSessionBottomMenu(
|
||||||
Button(
|
Button(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
text = stringResource(R.string.screen_identity_use_another_device),
|
text = stringResource(R.string.screen_identity_use_another_device),
|
||||||
onClick = { eventSink(VerifySelfSessionViewEvents.RequestVerification) },
|
onClick = { eventSink(VerifySelfSessionViewEvents.UseAnotherDevice) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Button(
|
Button(
|
||||||
|
|
@ -267,6 +272,17 @@ private fun VerifySelfSessionBottomMenu(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
is Step.UseAnotherDevice -> {
|
||||||
|
VerificationBottomMenu {
|
||||||
|
Button(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
text = stringResource(CommonStrings.action_start_verification),
|
||||||
|
onClick = { eventSink(VerifySelfSessionViewEvents.RequestVerification) },
|
||||||
|
)
|
||||||
|
// Placeholder so the 1st button keeps its vertical position
|
||||||
|
Spacer(modifier = Modifier.height(40.dp))
|
||||||
|
}
|
||||||
|
}
|
||||||
is Step.Canceled -> {
|
is Step.Canceled -> {
|
||||||
VerificationBottomMenu {
|
VerificationBottomMenu {
|
||||||
Button(
|
Button(
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
package io.element.android.features.verifysession.impl.outgoing
|
package io.element.android.features.verifysession.impl.outgoing
|
||||||
|
|
||||||
sealed interface VerifySelfSessionViewEvents {
|
sealed interface VerifySelfSessionViewEvents {
|
||||||
|
data object UseAnotherDevice : VerifySelfSessionViewEvents
|
||||||
data object RequestVerification : VerifySelfSessionViewEvents
|
data object RequestVerification : VerifySelfSessionViewEvents
|
||||||
data object StartSasVerification : VerifySelfSessionViewEvents
|
data object StartSasVerification : VerifySelfSessionViewEvents
|
||||||
data object ConfirmVerification : VerifySelfSessionViewEvents
|
data object ConfirmVerification : VerifySelfSessionViewEvents
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@
|
||||||
<string name="screen_session_verification_request_title">"Verification requested"</string>
|
<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_dont_match">"They don’t match"</string>
|
||||||
<string name="screen_session_verification_they_match">"They 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_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_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_session_verification_waiting_to_accept_title">"Waiting to accept request"</string>
|
||||||
<string name="screen_signout_in_progress_dialog_content">"Signing out…"</string>
|
<string name="screen_signout_in_progress_dialog_content">"Signing out…"</string>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue