Skip to content

Commit

Permalink
Merge pull request #1965 from vector-im/feature/bma/emojiRepresentation
Browse files Browse the repository at this point in the history
Fix emoji representation
  • Loading branch information
bmarty authored Dec 11, 2023
2 parents 9e3fe2a + 0d73a18 commit 0a16af1
Show file tree
Hide file tree
Showing 121 changed files with 4,109 additions and 91 deletions.
35 changes: 35 additions & 0 deletions .github/workflows/sync-sas-strings.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Sync SAS strings
on:
workflow_dispatch:
schedule:
# At 00:00 on every Monday UTC
- cron: '0 0 * * 1'

jobs:
sync-sas-strings:
runs-on: ubuntu-latest
# Skip in forks
if: github.repository == 'vector-im/element-x-android'
# No concurrency required, runs every time on a schedule.
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.8
uses: actions/setup-python@v4
with:
python-version: 3.9
- name: Install Prerequisite dependencies
run: |
pip install requests
- name: Run SAS String script
run: ./tools/sas/import_sas_strings.py
- name: Create Pull Request for SAS Strings
uses: peter-evans/create-pull-request@v5
with:
commit-message: Sync SAS Strings
title: Sync SAS Strings
body: |
- Update SAS Strings from matrix-doc.
branch: sync-sas-strings
base: develop


1 change: 1 addition & 0 deletions changelog.d/1965.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Update rendering of Emojis displayed during verification.
Original file line number Diff line number Diff line change
Expand Up @@ -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 -> {
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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<VerificationEmoji>, val state: Async<Unit>) : VerificationStep
data class Verifying(val data: SessionVerificationData, val state: Async<Unit>) : VerificationStep
data object Completed : VerificationStep
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -70,15 +70,15 @@ class VerifySelfSessionStateMachine @Inject constructor(
}
inState<State.SasVerificationStarted> {
on { event: Event.DidReceiveChallenge, state: MachineState<State.SasVerificationStarted> ->
state.override { State.Verifying.ChallengeReceived(event.emojis) }
state.override { State.Verifying.ChallengeReceived(event.data) }
}
}
inState<State.Verifying.ChallengeReceived> {
on { _: Event.AcceptChallenge, state: MachineState<State.Verifying.ChallengeReceived> ->
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.Verifying.ChallengeReceived> ->
state.override { State.Verifying.Replying(state.snapshot.emojis, accept = false) }
state.override { State.Verifying.Replying(state.snapshot.data, accept = false) }
}
}
inState<State.Verifying.Replying> {
Expand Down Expand Up @@ -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<VerificationEmoji>) : State {
sealed class Verifying(open val data: SessionVerificationData) : State {
/** Verification accepted and emojis received. */
data class ChallengeReceived(override val emojis: List<VerificationEmoji>) : Verifying(emojis)
data class ChallengeReceived(override val data: SessionVerificationData) : Verifying(data)

/** Replying to a verification challenge. */
data class Replying(override val emojis: List<VerificationEmoji>, val accept: Boolean) : Verifying(emojis)
data class Replying(override val data: SessionVerificationData, val accept: Boolean) : Verifying(data)
}

/** The verification is being canceled. */
Expand All @@ -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<VerificationEmoji>) : Event
/** Has received data. */
data class DidReceiveChallenge(val data: SessionVerificationData) : Event

/** Emojis match. */
data object AcceptChallenge : Event
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<VerifySelfSessionState> {
Expand All @@ -28,32 +29,47 @@ open class VerifySelfSessionStateProvider : PreviewParameterProvider<VerifySelfS
verificationFlowStep = VerifySelfSessionState.VerificationStep.AwaitingOtherDeviceResponse
),
aVerifySelfSessionState().copy(
verificationFlowStep = VerifySelfSessionState.VerificationStep.Verifying(aVerificationEmojiList(), Async.Uninitialized)
verificationFlowStep = VerifySelfSessionState.VerificationStep.Verifying(aEmojisSessionVerificationData(), Async.Uninitialized)
),
aVerifySelfSessionState().copy(
verificationFlowStep = VerifySelfSessionState.VerificationStep.Verifying(aVerificationEmojiList(), Async.Loading())
verificationFlowStep = VerifySelfSessionState.VerificationStep.Verifying(aEmojisSessionVerificationData(), Async.Loading())
),
aVerifySelfSessionState().copy(
verificationFlowStep = VerifySelfSessionState.VerificationStep.Canceled
),
aVerifySelfSessionState().copy(
verificationFlowStep = VerifySelfSessionState.VerificationStep.Ready
),
aVerifySelfSessionState().copy(
verificationFlowStep = VerifySelfSessionState.VerificationStep.Verifying(aDecimalsSessionVerificationData(), Async.Uninitialized)
),
// Add other state here
)
}

fun aVerifySelfSessionState() = VerifySelfSessionState(
private fun aEmojisSessionVerificationData(
emojiList: List<VerificationEmoji> = aVerificationEmojiList(),
): SessionVerificationData {
return SessionVerificationData.Emojis(emojiList)
}

private fun aDecimalsSessionVerificationData(
decimals: List<Int> = listOf(123, 456, 789),
): SessionVerificationData {
return SessionVerificationData.Decimals(decimals)
}

private fun aVerifySelfSessionState() = VerifySelfSessionState(
verificationFlowStep = VerifySelfSessionState.VerificationStep.Initial,
eventSink = {},
)

fun aVerificationEmojiList() = listOf(
VerificationEmoji("🍕", "Pizza"),
VerificationEmoji("🚀", "Rocket"),
VerificationEmoji("🚀", "Rocket"),
VerificationEmoji("🗺️", "Map"),
VerificationEmoji("🎳", "Bowling"),
VerificationEmoji("🎳", "Bowling"),
VerificationEmoji("📌", "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"),
)
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package io.element.android.features.verifysession.impl

import androidx.activity.compose.BackHandler
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
Expand All @@ -25,6 +26,7 @@ import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.widthIn
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
Expand All @@ -33,11 +35,14 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.element.android.compound.theme.ElementTheme
import io.element.android.features.verifysession.impl.emoji.toEmojiResource
import io.element.android.libraries.architecture.Async
import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
Expand All @@ -48,8 +53,8 @@ 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.compound.theme.ElementTheme
import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.features.verifysession.impl.VerifySelfSessionState.VerificationStep as FlowStep

Expand Down Expand Up @@ -100,14 +105,23 @@ private fun HeaderContent(verificationFlowStep: FlowStep, modifier: Modifier = M
FlowStep.Initial -> R.string.screen_session_verification_open_existing_session_title
FlowStep.Canceled -> CommonStrings.common_verification_cancelled
FlowStep.AwaitingOtherDeviceResponse -> R.string.screen_session_verification_waiting_to_accept_title
FlowStep.Ready, is FlowStep.Verifying, FlowStep.Completed -> R.string.screen_session_verification_compare_emojis_title
FlowStep.Ready,
FlowStep.Completed -> R.string.screen_session_verification_compare_emojis_title
is FlowStep.Verifying -> when (verificationFlowStep.data) {
is SessionVerificationData.Decimals -> R.string.screen_session_verification_compare_numbers_title
is SessionVerificationData.Emojis -> R.string.screen_session_verification_compare_emojis_title
}
}
val subtitleTextId = when (verificationFlowStep) {
FlowStep.Initial -> R.string.screen_session_verification_open_existing_session_subtitle
FlowStep.Canceled -> R.string.screen_session_verification_cancelled_subtitle
FlowStep.AwaitingOtherDeviceResponse -> R.string.screen_session_verification_waiting_to_accept_subtitle
is FlowStep.Verifying, FlowStep.Completed -> R.string.screen_session_verification_compare_emojis_subtitle
FlowStep.Ready -> R.string.screen_session_verification_ready_subtitle
FlowStep.Completed -> R.string.screen_session_verification_compare_emojis_subtitle
is FlowStep.Verifying -> when (verificationFlowStep.data) {
is SessionVerificationData.Decimals -> R.string.screen_session_verification_compare_numbers_subtitle
is SessionVerificationData.Emojis -> R.string.screen_session_verification_compare_emojis_subtitle
}
}

IconTitleSubtitleMolecule(
Expand Down Expand Up @@ -138,17 +152,30 @@ 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 -> {
val text = verificationFlowStep.data.decimals.joinToString(separator = " - ") { it.toString() }
Text(
modifier = modifier.fillMaxWidth(),
text = text,
style = ElementTheme.typography.fontHeadingLgBold,
color = MaterialTheme.colorScheme.primary,
textAlign = TextAlign.Center,
)
}
is SessionVerificationData.Emojis -> {
// We want each row to have up to 4 emojis
val rows = verificationFlowStep.data.emojis.chunked(4)
Column(
modifier = modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(40.dp),
) {
rows.forEach { emojis ->
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceEvenly) {
for (emoji in emojis) {
EmojiItemView(emoji = emoji, modifier = Modifier.widthIn(max = 60.dp))
}
}
}
}
}
Expand All @@ -157,14 +184,16 @@ private fun ContentVerifying(verificationFlowStep: FlowStep.Verifying, modifier:

@Composable
private fun EmojiItemView(emoji: VerificationEmoji, modifier: Modifier = Modifier) {
val emojiResource = emoji.number.toEmojiResource()
Column(horizontalAlignment = Alignment.CenterHorizontally, modifier = modifier) {
Text(
text = emoji.code,
style = ElementTheme.typography.fontBodyMdRegular.copy(fontSize = 34.sp),
Image(
modifier = Modifier.size(48.dp),
painter = painterResource(id = emojiResource.drawableRes),
contentDescription = null,
)
Spacer(modifier = Modifier.height(16.dp))
Text(
emoji.name,
text = stringResource(id = emojiResource.nameRes),
style = ElementTheme.typography.fontBodyMdRegular,
color = MaterialTheme.colorScheme.secondary,
maxLines = 1,
Expand Down
Loading

0 comments on commit 0a16af1

Please sign in to comment.