mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-10-31 16:22:49 +00:00
Expose the timeline item long press and swipe to reply as TalkBack actions (#7458)
* Expose the timeline item gestures as TalkBack actions Long pressing a timeline item opens the action list, and swiping it starts a reply. Neither gesture is reachable with a screen reader enabled, so those two actions were unavailable to TalkBack users. Publish them as accessibility custom actions on the event row, reusing the existing "Message actions" and "Reply" strings. The reply action is only offered when the user is allowed to reply, matching the swipe. * Update screenshots --------- Co-authored-by: ElementBot <android@element.io>
This commit is contained in:
+48
-2
@@ -49,7 +49,9 @@ import androidx.compose.ui.platform.LocalViewConfiguration
|
||||
import androidx.compose.ui.platform.ViewConfiguration
|
||||
import androidx.compose.ui.res.pluralStringResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.CustomAccessibilityAction
|
||||
import androidx.compose.ui.semantics.clearAndSetSemantics
|
||||
import androidx.compose.ui.semantics.customActions
|
||||
import androidx.compose.ui.semantics.hideFromAccessibility
|
||||
import androidx.compose.ui.semantics.isTraversalGroup
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
@@ -217,13 +219,23 @@ fun TimelineItemEventRow(
|
||||
inReplyToClick(inReplyToEventId)
|
||||
}
|
||||
|
||||
Column(modifier = modifier.fillMaxWidth()) {
|
||||
val canReply = timelineRoomInfo.userHasPermissionToSendMessage && event.canBeRepliedTo
|
||||
val accessibilityActions = rememberTimelineItemAccessibilityActions(
|
||||
canReply = canReply,
|
||||
onLongClick = onLongClick,
|
||||
onSwipeToReply = onSwipeToReply,
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.semantics { customActions = accessibilityActions }
|
||||
) {
|
||||
if (event.groupPosition.isNew()) {
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
} else {
|
||||
Spacer(modifier = Modifier.height(2.dp))
|
||||
}
|
||||
val canReply = timelineRoomInfo.userHasPermissionToSendMessage && event.canBeRepliedTo
|
||||
if (canReply) {
|
||||
val state: SwipeableActionsState = rememberSwipeableActionsState()
|
||||
val offset = state.offset.floatValue
|
||||
@@ -319,6 +331,40 @@ fun TimelineItemEventRow(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes the gestures of a timeline item — long press for the action list, swipe for a reply — as TalkBack actions, since neither gesture is reachable
|
||||
* with a screen reader enabled.
|
||||
*/
|
||||
@Composable
|
||||
private fun rememberTimelineItemAccessibilityActions(
|
||||
canReply: Boolean,
|
||||
onLongClick: () -> Unit,
|
||||
onSwipeToReply: () -> Unit,
|
||||
): List<CustomAccessibilityAction> {
|
||||
val messageActionsLabel = stringResource(CommonStrings.common_message_actions)
|
||||
val replyLabel = stringResource(CommonStrings.action_reply)
|
||||
val latestOnLongClick by rememberUpdatedState(onLongClick)
|
||||
val latestOnSwipeToReply by rememberUpdatedState(onSwipeToReply)
|
||||
return remember(canReply, messageActionsLabel, replyLabel) {
|
||||
buildList {
|
||||
add(
|
||||
CustomAccessibilityAction(messageActionsLabel) {
|
||||
latestOnLongClick()
|
||||
true
|
||||
}
|
||||
)
|
||||
if (canReply) {
|
||||
add(
|
||||
CustomAccessibilityAction(replyLabel) {
|
||||
latestOnSwipeToReply()
|
||||
true
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ThreadSummaryView(
|
||||
threadSummary: ThreadSummary,
|
||||
|
||||
BIN
Binary file not shown.
Reference in New Issue
Block a user