From 78ce22d458aaa13074b28df80792513ae4af7fc7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 8 Dec 2023 16:36:47 +0100 Subject: [PATCH] Update regarding SDK change on verification data --- .../impl/VerifySelfSessionPresenter.kt | 4 +- .../impl/VerifySelfSessionState.kt | 4 +- .../impl/VerifySelfSessionStateMachine.kt | 18 ++++----- .../impl/VerifySelfSessionStateProvider.kt | 34 +++++++++++------ .../impl/VerifySelfSessionView.kt | 30 +++++++++------ ...ionEmoji.kt => SessionVerificationData.kt} | 21 +++++++++- .../SessionVerificationService.kt | 4 +- .../RustSessionVerificationService.kt | 38 +++++++++++++++---- 8 files changed, 105 insertions(+), 48 deletions(-) rename libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/verification/{VerificationEmoji.kt => SessionVerificationData.kt} (59%) diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenter.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenter.kt index 689ff3a154..89751ca604 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenter.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionPresenter.kt @@ -97,7 +97,7 @@ class VerifySelfSessionPresenter @Inject constructor( is StateMachineState.Verifying.Replying -> Async.Loading() else -> Async.Uninitialized } - VerifySelfSessionState.VerificationStep.Verifying(machineState.emojis, async) + VerifySelfSessionState.VerificationStep.Verifying(machineState.data, async) } StateMachineState.Completed -> { @@ -116,7 +116,7 @@ class VerifySelfSessionPresenter @Inject constructor( stateMachine.dispatch(VerifySelfSessionStateMachine.Event.DidStartSasVerification) } is VerificationFlowState.ReceivedVerificationData -> { - stateMachine.dispatch(VerifySelfSessionStateMachine.Event.DidReceiveChallenge(verificationAttemptState.emoji)) + stateMachine.dispatch(VerifySelfSessionStateMachine.Event.DidReceiveChallenge(verificationAttemptState.data)) } VerificationFlowState.Finished -> { stateMachine.dispatch(VerifySelfSessionStateMachine.Event.DidAcceptChallenge) diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionState.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionState.kt index 248e3aec10..f3afd3b7b9 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionState.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionState.kt @@ -19,7 +19,7 @@ package io.element.android.features.verifysession.impl import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable import io.element.android.libraries.architecture.Async -import io.element.android.libraries.matrix.api.verification.VerificationEmoji +import io.element.android.libraries.matrix.api.verification.SessionVerificationData @Immutable data class VerifySelfSessionState( @@ -33,7 +33,7 @@ data class VerifySelfSessionState( data object Canceled : VerificationStep data object AwaitingOtherDeviceResponse : VerificationStep data object Ready : VerificationStep - data class Verifying(val emojiList: List, val state: Async) : VerificationStep + data class Verifying(val data: SessionVerificationData, val state: Async) : VerificationStep data object Completed : VerificationStep } } diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateMachine.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateMachine.kt index ad48294e92..52bd38bfbd 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateMachine.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateMachine.kt @@ -20,8 +20,8 @@ package io.element.android.features.verifysession.impl import com.freeletics.flowredux.dsl.FlowReduxStateMachine +import io.element.android.libraries.matrix.api.verification.SessionVerificationData import io.element.android.libraries.matrix.api.verification.SessionVerificationService -import io.element.android.libraries.matrix.api.verification.VerificationEmoji import kotlinx.coroutines.ExperimentalCoroutinesApi import javax.inject.Inject import com.freeletics.flowredux.dsl.State as MachineState @@ -70,15 +70,15 @@ class VerifySelfSessionStateMachine @Inject constructor( } inState { on { event: Event.DidReceiveChallenge, state: MachineState -> - state.override { State.Verifying.ChallengeReceived(event.emojis) } + state.override { State.Verifying.ChallengeReceived(event.data) } } } inState { on { _: Event.AcceptChallenge, state: MachineState -> - state.override { State.Verifying.Replying(state.snapshot.emojis, accept = true) } + state.override { State.Verifying.Replying(state.snapshot.data, accept = true) } } on { _: Event.DeclineChallenge, state: MachineState -> - state.override { State.Verifying.Replying(state.snapshot.emojis, accept = false) } + state.override { State.Verifying.Replying(state.snapshot.data, accept = false) } } } inState { @@ -139,12 +139,12 @@ class VerifySelfSessionStateMachine @Inject constructor( /** A SaS verification flow has been started. */ data object SasVerificationStarted : State - sealed class Verifying(open val emojis: List) : State { + sealed class Verifying(open val data: SessionVerificationData) : State { /** Verification accepted and emojis received. */ - data class ChallengeReceived(override val emojis: List) : Verifying(emojis) + data class ChallengeReceived(override val data: SessionVerificationData) : Verifying(data) /** Replying to a verification challenge. */ - data class Replying(override val emojis: List, val accept: Boolean) : Verifying(emojis) + data class Replying(override val data: SessionVerificationData, val accept: Boolean) : Verifying(data) } /** The verification is being canceled. */ @@ -170,8 +170,8 @@ class VerifySelfSessionStateMachine @Inject constructor( /** Started a SaS verification flow. */ data object DidStartSasVerification : Event - /** Has received emojis. */ - data class DidReceiveChallenge(val emojis: List) : Event + /** Has received data. */ + data class DidReceiveChallenge(val data: SessionVerificationData) : Event /** Emojis match. */ data object AcceptChallenge : Event diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateProvider.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateProvider.kt index c0d5bc1628..913b43dfd3 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateProvider.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionStateProvider.kt @@ -18,6 +18,7 @@ package io.element.android.features.verifysession.impl import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.libraries.architecture.Async +import io.element.android.libraries.matrix.api.verification.SessionVerificationData import io.element.android.libraries.matrix.api.verification.VerificationEmoji open class VerifySelfSessionStateProvider : PreviewParameterProvider { @@ -28,10 +29,10 @@ open class VerifySelfSessionStateProvider : PreviewParameterProvider = aVerificationEmojiList(), + decimals: List = emptyList(), +): SessionVerificationData { + return if (emojiList.isEmpty()) { + SessionVerificationData.Decimals(decimals) + } else { + SessionVerificationData.Emojis(emojiList) + } +} + +private fun aVerifySelfSessionState() = VerifySelfSessionState( verificationFlowStep = VerifySelfSessionState.VerificationStep.Initial, eventSink = {}, ) -fun aVerificationEmojiList() = listOf( - VerificationEmoji(27, "Pizza"), - VerificationEmoji(54, "Rocket"), - VerificationEmoji(54, "Rocket"), - VerificationEmoji(42, "Book"), - VerificationEmoji(48, "Hammer"), - VerificationEmoji(48, "Hammer"), - VerificationEmoji(63, "Pin"), +private fun aVerificationEmojiList() = listOf( + VerificationEmoji(number = 27, emoji = "🍕", description = "Pizza"), + VerificationEmoji(number = 54, emoji = "🚀", description = "Rocket"), + VerificationEmoji(number = 54, emoji = "🚀", description = "Rocket"), + VerificationEmoji(number = 42, emoji = "📕", description = "Book"), + VerificationEmoji(number = 48, emoji = "🔨", description = "Hammer"), + VerificationEmoji(number = 48, emoji = "🔨", description = "Hammer"), + VerificationEmoji(number = 63, emoji = "📌", description = "Pin"), ) diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionView.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionView.kt index ef047ed1bf..a81693b9b0 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionView.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/VerifySelfSessionView.kt @@ -52,6 +52,7 @@ import io.element.android.libraries.designsystem.theme.components.Button import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TextButton +import io.element.android.libraries.matrix.api.verification.SessionVerificationData import io.element.android.libraries.matrix.api.verification.VerificationEmoji import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.features.verifysession.impl.VerifySelfSessionState.VerificationStep as FlowStep @@ -141,17 +142,22 @@ private fun ContentWaiting(modifier: Modifier = Modifier) { @Composable private fun ContentVerifying(verificationFlowStep: FlowStep.Verifying, modifier: Modifier = Modifier) { - // We want each row to have up to 4 emojis - val rows = verificationFlowStep.emojiList.chunked(4) - Column(modifier = modifier.fillMaxWidth()) { - for ((rowIndex, emojis) in rows.withIndex()) { - // Vertical spacing between rows - if (rowIndex > 0) { - Spacer(modifier = Modifier.height(40.dp)) - } - Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) { - for (emoji in emojis) { - EmojiItemView(emoji = emoji, modifier = Modifier.widthIn(max = 60.dp)) + when (verificationFlowStep.data) { + is SessionVerificationData.Decimals -> Unit // TODO Render decimals + is SessionVerificationData.Emojis -> { + // We want each row to have up to 4 emojis + val rows = verificationFlowStep.data.emojis.chunked(4) + Column(modifier = modifier.fillMaxWidth()) { + for ((rowIndex, emojis) in rows.withIndex()) { + // Vertical spacing between rows + if (rowIndex > 0) { + Spacer(modifier = Modifier.height(40.dp)) + } + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) { + for (emoji in emojis) { + EmojiItemView(emoji = emoji, modifier = Modifier.widthIn(max = 60.dp)) + } + } } } } @@ -160,7 +166,7 @@ private fun ContentVerifying(verificationFlowStep: FlowStep.Verifying, modifier: @Composable private fun EmojiItemView(emoji: VerificationEmoji, modifier: Modifier = Modifier) { - val emojiResource = emoji.code.toEmojiResource() + val emojiResource = emoji.number.toEmojiResource() Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = modifier) { Image( modifier = Modifier.size(48.dp), diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/verification/VerificationEmoji.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/verification/SessionVerificationData.kt similarity index 59% rename from libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/verification/VerificationEmoji.kt rename to libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/verification/SessionVerificationData.kt index af5e49565e..9368773ae8 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/verification/VerificationEmoji.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/verification/SessionVerificationData.kt @@ -16,7 +16,24 @@ package io.element.android.libraries.matrix.api.verification +import androidx.compose.runtime.Immutable + +@Immutable +sealed interface SessionVerificationData { + data class Emojis( + // 7 emojis + val emojis: List, + ) : SessionVerificationData + + data class Decimals( + // 3 numbers + val decimals: List, + ) : SessionVerificationData +} + +// https://spec.matrix.org/unstable/client-server-api/#sas-method-emoji data class VerificationEmoji( - val code: Int, - val name: String, + val number: Int, + val emoji: String, + val description: String, ) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/verification/SessionVerificationService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/verification/SessionVerificationService.kt index 639b704823..8a51f38a8d 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/verification/SessionVerificationService.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/verification/SessionVerificationService.kt @@ -101,8 +101,8 @@ sealed interface VerificationFlowState { /** Short Authentication String (SAS) verification started between the 2 devices. */ data object StartedSasVerification : VerificationFlowState - /** Verification data for the SAS verification (emojis) received. */ - data class ReceivedVerificationData(val emoji: ImmutableList) : VerificationFlowState + /** Verification data for the SAS verification received. */ + data class ReceivedVerificationData(val data: SessionVerificationData) : VerificationFlowState /** Verification completed successfully. */ data object Finished : VerificationFlowState diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt index 6a1a91cba1..0d705d6834 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/verification/RustSessionVerificationService.kt @@ -18,12 +18,12 @@ package io.element.android.libraries.matrix.impl.verification import io.element.android.libraries.core.data.tryOrNull import io.element.android.libraries.matrix.api.sync.SyncState +import io.element.android.libraries.matrix.api.verification.SessionVerificationData import io.element.android.libraries.matrix.api.verification.SessionVerificationService import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus import io.element.android.libraries.matrix.api.verification.VerificationEmoji import io.element.android.libraries.matrix.api.verification.VerificationFlowState import io.element.android.libraries.matrix.impl.sync.RustSyncService -import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -33,7 +33,8 @@ import kotlinx.coroutines.launch import org.matrix.rustcomponents.sdk.SessionVerificationController import org.matrix.rustcomponents.sdk.SessionVerificationControllerDelegate import org.matrix.rustcomponents.sdk.SessionVerificationControllerInterface -import org.matrix.rustcomponents.sdk.SessionVerificationEmoji +import org.matrix.rustcomponents.sdk.use +import org.matrix.rustcomponents.sdk.SessionVerificationData as RustSessionVerificationData class RustSessionVerificationService( private val syncService: RustSyncService, @@ -105,12 +106,8 @@ class RustSessionVerificationService( updateVerificationStatus(isVerified = true) } - override fun didReceiveVerificationData(data: List) { - val emojis = data.map { emoji -> - emoji.use { VerificationEmoji(it.code(), it.description()) } - } - .toImmutableList() - _verificationFlowState.value = VerificationFlowState.ReceivedVerificationData(emojis) + override fun didReceiveVerificationData(data: RustSessionVerificationData) { + _verificationFlowState.value = VerificationFlowState.ReceivedVerificationData(data.map()) } // When the actual SAS verification starts @@ -142,3 +139,28 @@ class RustSessionVerificationService( _sessionVerifiedStatus.value = newValue } } + +private fun RustSessionVerificationData.map(): SessionVerificationData { + return use { sessionVerificationData -> + when (sessionVerificationData) { + is RustSessionVerificationData.Emojis -> { + SessionVerificationData.Emojis( + emojis = sessionVerificationData.emojis.mapIndexed { index, emoji -> + emoji.use { sessionVerificationEmoji -> + VerificationEmoji( + number = sessionVerificationData.indices[index].toInt(), + emoji = sessionVerificationEmoji.symbol(), + description = sessionVerificationEmoji.description(), + ) + } + }, + ) + } + is RustSessionVerificationData.Decimals -> { + SessionVerificationData.Decimals( + decimals = sessionVerificationData.values.map { it.toInt() }, + ) + } + } + } +}