[a11y] Let keyboard shortcut Shift + F10 trigger the same action than a long click

This commit is contained in:
Benoit Marty 2025-08-05 09:41:08 +02:00
parent 27ad6217ec
commit d988ae3082
15 changed files with 104 additions and 30 deletions

View file

@ -38,6 +38,7 @@ import io.element.android.features.messages.impl.timeline.model.bubble.BubbleSta
import io.element.android.features.messages.impl.timeline.model.bubble.BubbleStateProvider
import io.element.android.libraries.core.extensions.to01
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.modifiers.onShiftF10
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.text.toDp
@ -96,12 +97,14 @@ fun MessageEventBubble(
val clickableModifier = if (isTalkbackActive()) {
Modifier
} else {
Modifier.combinedClickable(
onClick = onClick,
onLongClick = onLongClick,
indication = ripple(),
interactionSource = interactionSource
)
Modifier
.combinedClickable(
onClick = onClick,
onLongClick = onLongClick,
indication = ripple(),
interactionSource = interactionSource
)
.onShiftF10(onLongClick)
}
// Ignore state.isHighlighted for now, we need a design decision on it.

View file

@ -19,6 +19,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.modifiers.onShiftF10
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Surface
@ -46,7 +47,8 @@ fun MessageStateEventContainer(
onLongClickLabel = stringResource(CommonStrings.action_open_context_menu),
indication = ripple(),
interactionSource = interactionSource
),
)
.onShiftF10(onLongClick),
color = backgroundColor,
shape = shape,
content = content

View file

@ -43,6 +43,7 @@ import io.element.android.features.messages.impl.timeline.model.AggregatedReacti
import io.element.android.features.messages.impl.timeline.model.AggregatedReactionProvider
import io.element.android.features.messages.impl.timeline.model.aTimelineItemReactions
import io.element.android.libraries.designsystem.icons.CompoundDrawables
import io.element.android.libraries.designsystem.modifiers.onShiftF10
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.text.toDp
@ -107,6 +108,7 @@ fun MessagesReactionButton(
onLongClickLabel = stringResource(CommonStrings.action_open_context_menu),
onLongClick = onLongClick
)
.onShiftF10(onLongClick)
// Inner border, to highlight when selected
.border(BorderStroke(1.dp, borderColor), RoundedCornerShape(corner = CornerSize(12.dp)))
.background(buttonColor, RoundedCornerShape(corner = CornerSize(12.dp)))

View file

@ -34,6 +34,7 @@ import io.element.android.features.roomcall.api.RoomCallState
import io.element.android.features.roomcall.api.RoomCallStateProvider
import io.element.android.libraries.designsystem.components.avatar.Avatar
import io.element.android.libraries.designsystem.components.avatar.AvatarType
import io.element.android.libraries.designsystem.modifiers.onShiftF10
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.text.toDp
@ -57,6 +58,7 @@ internal fun TimelineItemCallNotifyView(
onLongClick = { onLongClick(event) },
onLongClickLabel = stringResource(CommonStrings.action_open_context_menu),
)
.onShiftF10 { onLongClick(event) }
.padding(12.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalAlignment = Alignment.CenterVertically,

View file

@ -37,6 +37,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVoiceContent
import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionEvent
import io.element.android.features.messages.impl.timeline.protection.TimelineProtectionState
import io.element.android.libraries.designsystem.modifiers.onShiftF10
import io.element.android.libraries.designsystem.modifiers.subtleColorStops
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
@ -148,11 +149,13 @@ internal fun TimelineItemRow(
// Custom clickable that applies over the whole item for accessibility
.then(
if (isTalkbackActive()) {
Modifier.combinedClickable(
onClick = { onContentClick(timelineItem) },
onLongClick = { onLongClick(timelineItem) },
onLongClickLabel = stringResource(CommonStrings.action_open_context_menu),
)
Modifier
.combinedClickable(
onClick = { onContentClick(timelineItem) },
onLongClick = { onLongClick(timelineItem) },
onLongClickLabel = stringResource(CommonStrings.action_open_context_menu),
)
.onShiftF10 { onLongClick(timelineItem) }
} else {
Modifier
}

View file

@ -48,6 +48,7 @@ import io.element.android.features.messages.impl.timeline.model.event.aTimelineI
import io.element.android.features.messages.impl.timeline.protection.ProtectedView
import io.element.android.features.messages.impl.timeline.protection.coerceRatioWhenHidingContent
import io.element.android.libraries.designsystem.components.blurhash.blurHashBackground
import io.element.android.libraries.designsystem.modifiers.onShiftF10
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.textcomposer.ElementRichTextEditorStyle
@ -91,10 +92,12 @@ fun TimelineItemImageView(
.then(if (isLoaded) Modifier.background(Color.White) else Modifier)
.then(
if (!isTalkbackActive() && onContentClick != null) {
Modifier.combinedClickable(
onClick = onContentClick,
onLongClick = onLongClick
)
Modifier
.combinedClickable(
onClick = onContentClick,
onLongClick = onLongClick,
)
.onShiftF10(onLongClick)
} else {
Modifier
}

View file

@ -31,6 +31,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
import io.element.android.features.messages.impl.timeline.protection.ProtectedView
import io.element.android.features.messages.impl.timeline.protection.coerceRatioWhenHidingContent
import io.element.android.libraries.designsystem.components.blurhash.blurHashBackground
import io.element.android.libraries.designsystem.modifiers.onShiftF10
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.matrix.ui.media.MediaRequestData
@ -74,6 +75,7 @@ fun TimelineItemStickerView(
onLongClick = onLongClick,
onLongClickLabel = stringResource(CommonStrings.action_open_context_menu),
)
.onShiftF10(onLongClick)
} else {
Modifier
}

View file

@ -54,6 +54,7 @@ import io.element.android.features.messages.impl.timeline.model.event.aTimelineI
import io.element.android.features.messages.impl.timeline.protection.ProtectedView
import io.element.android.features.messages.impl.timeline.protection.coerceRatioWhenHidingContent
import io.element.android.libraries.designsystem.components.blurhash.blurHashBackground
import io.element.android.libraries.designsystem.modifiers.onShiftF10
import io.element.android.libraries.designsystem.modifiers.roundedBackground
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
@ -105,10 +106,12 @@ fun TimelineItemVideoView(
.then(if (isLoaded) Modifier.background(Color.White) else Modifier)
.then(
if (!isTalkbackActive && onContentClick != null) {
Modifier.combinedClickable(
onClick = onContentClick,
onLongClick = onLongClick
)
Modifier
.combinedClickable(
onClick = onContentClick,
onLongClick = onLongClick,
)
.onShiftF10(onLongClick)
} else {
Modifier
}