Make send event state UI easier to click (#6739)

* Make send event state UI easier to click

Make it so the whole timestamp view can be clicked

* Update screenshots

* Simplify `clickableModifier`

---------

Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
Jorge Martin Espinosa 2026-05-07 11:11:07 +02:00 committed by GitHub
parent 7cbecc6b94
commit d3e0ed059b
18 changed files with 68 additions and 49 deletions

View file

@ -15,9 +15,12 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
@ -47,9 +50,39 @@ fun TimelineEventTimestampView(
val isMessageEdited = event.content.isEdited()
val isMessageRedacted = event.content.isRedacted()
val tint = if (hasError || hasEncryptionCritical && !isMessageRedacted) ElementTheme.colors.textCriticalPrimary else ElementTheme.colors.textSecondary
val shield = event.messageShield
val isVerifiedUserSendFailure = event.localSendState is LocalEventSendState.Failed.VerifiedUser
val onClickLabel = when {
shield != null -> stringResource(CommonStrings.a11y_view_details)
hasError && isVerifiedUserSendFailure -> stringResource(CommonStrings.action_open_context_menu)
else -> null
}
val clickableModifier = remember(shield, hasError) {
when {
shield != null -> {
Modifier.clickable(
onClickLabel = onClickLabel,
) {
eventSink(TimelineEvent.ShowShieldDialog(shield))
}
}
hasError -> Modifier
.clickable(
enabled = isVerifiedUserSendFailure,
onClickLabel = onClickLabel,
) {
eventSink(TimelineEvent.ComputeVerifiedUserSendFailure(event))
}
else -> Modifier
}
}
Row(
modifier = Modifier
.padding(PaddingValues(start = TimelineEventTimestampViewDefaults.spacing))
// For a better click target, make the corners rounded
.clip(RoundedCornerShape(8.dp))
.then(clickableModifier)
.then(modifier),
verticalAlignment = Alignment.CenterVertically,
) {
@ -67,36 +100,22 @@ fun TimelineEventTimestampView(
color = tint,
)
if (hasError) {
val isVerifiedUserSendFailure = event.localSendState is LocalEventSendState.Failed.VerifiedUser
Spacer(modifier = Modifier.width(2.dp))
Icon(
imageVector = CompoundIcons.ErrorSolid(),
contentDescription = stringResource(id = CommonStrings.common_sending_failed),
tint = tint,
modifier = Modifier
.size(15.dp, 18.dp)
.clickable(
enabled = isVerifiedUserSendFailure,
onClickLabel = stringResource(CommonStrings.action_open_context_menu),
) {
eventSink(TimelineEvent.ComputeVerifiedUserSendFailure(event))
}
modifier = Modifier.size(15.dp, 18.dp),
)
}
if (!isMessageRedacted) {
event.messageShield?.let { shield ->
shield?.let { shield ->
Spacer(modifier = Modifier.width(2.dp))
Icon(
imageVector = shield.toIcon(),
contentDescription = stringResource(id = CommonStrings.a11y_encryption_details),
modifier = Modifier
.size(15.dp)
.clickable(
onClickLabel = stringResource(CommonStrings.a11y_view_details),
) {
eventSink(TimelineEvent.ShowShieldDialog(shield))
},
modifier = Modifier.size(15.dp),
tint = shield.toIconColor(),
)
Spacer(modifier = Modifier.width(4.dp))