Make verification screens scrollable and emoji labels multiline (#4449)

* Make self verification screens scrollable

* Remove unused fields from `VerificationEmoji`

* Make only the header and content scroll in `HeaderFooterPage`.

* Use the right 'emoji' icon in both flows (`ReactionSolid`)

---------

Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
Jorge Martin Espinosa 2025-03-21 12:18:38 +01:00 committed by GitHub
parent 93d27735e4
commit d27a61a588
47 changed files with 213 additions and 144 deletions

View file

@ -85,7 +85,7 @@ fun JoinRoomView(
) {
HeaderFooterPage(
containerColor = Color.Transparent,
paddingValues = PaddingValues(
contentPadding = PaddingValues(
horizontal = 16.dp,
vertical = 32.dp
),

View file

@ -51,7 +51,7 @@ fun RoomAliasResolverView(
) {
HeaderFooterPage(
containerColor = Color.Transparent,
paddingValues = PaddingValues(
contentPadding = PaddingValues(
horizontal = 16.dp,
vertical = 32.dp
),

View file

@ -13,9 +13,11 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.TopAppBarDefaults.topAppBarColors
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.PreviewParameter
@ -35,6 +37,7 @@ import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Button
import io.element.android.libraries.designsystem.theme.components.InvisibleButton
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.TextButton
import io.element.android.libraries.designsystem.theme.components.TopAppBar
@ -67,7 +70,8 @@ fun IncomingVerificationView(
step is Step.Completed -> Unit
else -> BackButton(onClick = { state.eventSink(IncomingVerificationViewEvents.GoBack) })
}
}
},
colors = topAppBarColors(containerColor = Color.Transparent),
)
},
header = {
@ -77,7 +81,8 @@ fun IncomingVerificationView(
IncomingVerificationBottomMenu(
state = state,
)
}
},
isScrollable = true,
) {
IncomingVerificationContent(
step = step,
@ -222,7 +227,11 @@ private fun IncomingVerificationBottomMenu(
}
is Step.Verifying -> {
if (step.isWaiting) {
// Show nothing
// Add invisible buttons to keep the same screen layout
VerificationBottomMenu {
InvisibleButton()
InvisibleButton()
}
} else {
VerificationBottomMenu {
Button(

View file

@ -16,9 +16,11 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.TopAppBarDefaults.topAppBarColors
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
@ -91,7 +93,8 @@ fun VerifySelfSessionView(
{ BackButton(onClick = ::cancelOrResetFlow) }
} else {
{}
}
},
colors = topAppBarColors(containerColor = Color.Transparent)
)
},
header = {
@ -103,7 +106,8 @@ fun VerifySelfSessionView(
onCancelClick = ::cancelOrResetFlow,
onContinueClick = onFinish,
)
}
},
isScrollable = true,
) {
VerifySelfSessionContent(
flowState = step,
@ -124,13 +128,13 @@ private fun VerifySelfSessionHeader(step: Step, request: VerificationRequest.Out
}
Step.AwaitingOtherDeviceResponse -> BigIcon.Style.Loading
Step.Canceled -> BigIcon.Style.AlertSolid
Step.Ready -> BigIcon.Style.Default(CompoundIcons.Reaction())
Step.Ready -> BigIcon.Style.Default(CompoundIcons.ReactionSolid())
Step.Completed -> BigIcon.Style.SuccessSolid
is Step.Verifying -> {
if (step.state is AsyncData.Loading<Unit>) {
BigIcon.Style.Loading
} else {
BigIcon.Style.Default(CompoundIcons.Reaction())
BigIcon.Style.Default(CompoundIcons.ReactionSolid())
}
}
is Step.Exit -> return
@ -272,7 +276,11 @@ private fun VerifySelfSessionBottomMenu(
is Step.AwaitingOtherDeviceResponse -> Unit
is Step.Verifying -> {
if (isVerifying) {
// Show nothing
// Add invisible buttons to keep the same screen layout
VerificationBottomMenu {
InvisibleButton()
InvisibleButton()
}
} else {
VerificationBottomMenu {
Button(

View file

@ -23,11 +23,11 @@ internal fun aDecimalsSessionVerificationData(
}
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"),
VerificationEmoji(number = 27),
VerificationEmoji(number = 54),
VerificationEmoji(number = 54),
VerificationEmoji(number = 42),
VerificationEmoji(number = 48),
VerificationEmoji(number = 48),
VerificationEmoji(number = 63),
)

View file

@ -16,6 +16,7 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
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.runtime.Composable
@ -38,7 +39,7 @@ internal fun VerificationContentVerifying(
modifier: Modifier = Modifier,
) {
Box(
modifier = modifier.fillMaxSize(),
modifier = modifier.fillMaxSize().padding(bottom = 20.dp),
contentAlignment = Alignment.Center
) {
when (data) {
@ -86,8 +87,8 @@ private fun EmojiItemView(emoji: VerificationEmoji, modifier: Modifier = Modifie
text = stringResource(id = emojiResource.nameRes),
style = ElementTheme.typography.fontBodyMdRegular,
color = ElementTheme.colors.textSecondary,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
overflow = TextOverflow.Visible,
textAlign = TextAlign.Center,
)
}
}

View file

@ -185,7 +185,7 @@ class VerifySelfSessionPresenterTest {
@Test
fun `present - When verification is approved, the flow completes if there is no error`() = runTest {
val emojis = listOf(
VerificationEmoji(number = 30, emoji = "😀", description = "Smiley")
VerificationEmoji(number = 30)
)
val service = unverifiedSessionService(
requestSessionVerificationLambda = { },