Commit 75cc14b
authored
Improve message list TalkBack accessibility (#6440)
* Make message rows accessible to TalkBack
Message rows previously announced as "Message item, …" with the sender
name silently hidden from TalkBack and no action labels on the row's
clickable, so users heard the generic "double-tap to activate" hint with
no verb and could not tell who sent an incoming message in a group or
thread.
Push the a11y content down to the leaves so Compose's natural merge
composes them:
- `MessageFooter` sender name dropped its `clearAndSetSemantics { testTag
= … }` wrapper, which had been wiping the Text's natural `text`
semantic. Replaced with `Modifier.testTag(…)` so the testTag survives
and the user name is announced.
- `MessageContainer` dropped the static "Message item" placeholder
`contentDescription` on the outer Row. `combinedClickable` gains
`onClickLabel = "Open thread"` (when `canOpenThread`) and
`onLongClickLabel = "Show message options"` (when `canOpenActions`),
each gated to the actions that actually fire.
Adds the two new strings across all 7 supported locales and drops the
now-unused `stream_compose_cd_message_item` placeholder from all 8
locales.
* Make message list separators accessible as headings
The date and unread separators in the message list are visual landmarks
that screen-reader users need to skim a long conversation, but neither
exposed a `heading()` semantic, so TalkBack's swipe-by-heading gesture
skipped them. The unread separator also rendered "1 unread messages"
because its label was a `<string>` with no plural form.
Add `Modifier.semantics { heading() }` to both the date separator
(`DefaultMessageDateSeparatorContent`) and the unread separator
(`DefaultMessageUnreadSeparatorContent`).
Convert `stream_compose_message_list_unread_separator` from `<string>`
to `<plurals>` across all 8 locales so n=1 reads as a singular ("1
unread message") and n>1 keeps the plural. Update the caller to use
`pluralStringResource`.
* Announce typing indicator to TalkBack
The typing indicator in the message list shows avatars and animated dots
but no text, so TalkBack picked nothing up — it neither focused the
bubble nor announced when someone started typing.
Wrap the indicator's outer Row in a polite live region with a localized
description ("X is typing" / "X and Y are typing" / "N people are
typing", reusing the existing `stream_compose_channel_list_typing_*`
strings since the wording is identical), and merge descendants so the
bubble announces as a single unit. The description-building logic is
extracted to a small private helper to keep the composable under
detekt's method-length cap.
* Announce reaction state to TalkBack
The reaction toggles in the long-press reactions picker rendered a
checked background to indicate the user's own reactions, but exposed
nothing to TalkBack — no role, no selected state, just "double-tap to
activate". A user could not tell which reactions they had already
chosen. In-bubble reactions had a similar gap: each chip's clickable
had no `onClickLabel`, so TalkBack announced the generic "double-tap to
activate" with no verb.
- `ReactionToggle` swaps `Modifier.clickable { onChange(!checked) }` for
`Modifier.toggleable(value = checked, role = Role.Switch,
onValueChange = onChange)`. TalkBack now announces the emoji plus
"switch, on / off, double-tap to toggle".
- `MessageReactions` adds `onClickLabel = "Show reactions"` to both the
`ClusteredMessageReactions` row clickable and the per-chip
`ReactionChip` clickable, so focusing a chip says "<emoji>, double
tap to Show reactions".
Adds `stream_compose_message_reactions_show` across the 7 supported
locales. No public API surface change.
* Label message attachment tap action for TalkBack
Image, video, file and link attachments in the message list previously
announced as "double-tap to activate" — generic, no verb. The
`combinedClickable` on each of those attachment containers had no
`onClickLabel`, so TalkBack fell back to the platform default.
Add `onClickLabel = "Open attachment"` to `MediaAttachmentContent`,
`FileAttachmentContent`, and `LinkAttachmentContent`. TalkBack now reads
"<type> attachment, double tap to Open attachment" for images and
videos, and "<filename>, <size>, double tap to Open attachment" for
files (the inner Texts already carry the name and size).
Adds `stream_compose_message_attachment_open` across the 7 supported
locales. No public API surface change.
Poll, location, giphy and audio attachments are left for a follow-up —
each has its own composable and a different interaction model. Multi-
attachment disambiguation (e.g. "Image 1 of 4") is also a separate
follow-up; it needs index/total plumbing through the multi-attachment
grid.
* Use Role.Checkbox for reaction toggle
A reaction is a binary checked / unchecked state with no slider
metaphor, so Role.Checkbox communicates the semantics more accurately
than Role.Switch.
* Use pluralStringResource for typing indicator description
`pluralStringResource` is the Compose-idiomatic API for plural string
lookups; drops the manual `LocalResources.current.getQuantityString`
indirection.1 parent 677ebe7 commit 75cc14b
16 files changed
Lines changed: 128 additions & 34 deletions
File tree
- stream-chat-android-compose/src/main
- java/io/getstream/chat/android/compose/ui
- attachments/content
- components
- messages
- reactions
- messages/list
- res
- values-es
- values-fr
- values-hi
- values-in
- values-it
- values-ja
- values-ko
- values
Lines changed: 4 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
| 40 | + | |
40 | 41 | | |
41 | 42 | | |
42 | 43 | | |
| |||
45 | 46 | | |
46 | 47 | | |
47 | 48 | | |
| 49 | + | |
48 | 50 | | |
49 | 51 | | |
50 | 52 | | |
| |||
100 | 102 | | |
101 | 103 | | |
102 | 104 | | |
| 105 | + | |
103 | 106 | | |
104 | 107 | | |
105 | 108 | | |
| |||
114 | 117 | | |
115 | 118 | | |
116 | 119 | | |
| 120 | + | |
117 | 121 | | |
118 | 122 | | |
119 | 123 | | |
| |||
Lines changed: 3 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
| 53 | + | |
53 | 54 | | |
54 | 55 | | |
55 | 56 | | |
| |||
105 | 106 | | |
106 | 107 | | |
107 | 108 | | |
| 109 | + | |
108 | 110 | | |
109 | 111 | | |
110 | 112 | | |
| |||
114 | 116 | | |
115 | 117 | | |
116 | 118 | | |
| 119 | + | |
117 | 120 | | |
118 | 121 | | |
119 | 122 | | |
| |||
Lines changed: 2 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
452 | 452 | | |
453 | 453 | | |
454 | 454 | | |
| 455 | + | |
455 | 456 | | |
456 | 457 | | |
457 | 458 | | |
| |||
465 | 466 | | |
466 | 467 | | |
467 | 468 | | |
| 469 | + | |
468 | 470 | | |
469 | 471 | | |
470 | 472 | | |
| |||
Lines changed: 1 addition & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
30 | | - | |
31 | | - | |
32 | 30 | | |
33 | 31 | | |
34 | 32 | | |
| |||
91 | 89 | | |
92 | 90 | | |
93 | 91 | | |
94 | | - | |
95 | | - | |
96 | | - | |
| 92 | + | |
97 | 93 | | |
98 | 94 | | |
99 | 95 | | |
| |||
Lines changed: 6 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
| 37 | + | |
37 | 38 | | |
38 | 39 | | |
39 | 40 | | |
40 | 41 | | |
41 | 42 | | |
| 43 | + | |
42 | 44 | | |
43 | 45 | | |
44 | 46 | | |
| |||
67 | 69 | | |
68 | 70 | | |
69 | 71 | | |
| 72 | + | |
70 | 73 | | |
71 | 74 | | |
72 | 75 | | |
| |||
78 | 81 | | |
79 | 82 | | |
80 | 83 | | |
81 | | - | |
| 84 | + | |
82 | 85 | | |
83 | 86 | | |
84 | 87 | | |
| |||
175 | 178 | | |
176 | 179 | | |
177 | 180 | | |
| 181 | + | |
178 | 182 | | |
179 | 183 | | |
180 | 184 | | |
181 | 185 | | |
182 | 186 | | |
183 | 187 | | |
184 | | - | |
| 188 | + | |
185 | 189 | | |
186 | 190 | | |
187 | 191 | | |
| |||
Lines changed: 7 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| 26 | + | |
26 | 27 | | |
27 | 28 | | |
28 | 29 | | |
29 | 30 | | |
30 | 31 | | |
| 32 | + | |
31 | 33 | | |
32 | 34 | | |
33 | 35 | | |
34 | 36 | | |
35 | 37 | | |
36 | 38 | | |
37 | 39 | | |
38 | | - | |
39 | 40 | | |
40 | 41 | | |
41 | 42 | | |
| |||
69 | 70 | | |
70 | 71 | | |
71 | 72 | | |
72 | | - | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
73 | 78 | | |
74 | 79 | | |
75 | 80 | | |
| |||
Lines changed: 5 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
62 | 62 | | |
63 | 63 | | |
64 | 64 | | |
65 | | - | |
66 | | - | |
67 | 65 | | |
68 | 66 | | |
69 | 67 | | |
| |||
177 | 175 | | |
178 | 176 | | |
179 | 177 | | |
| 178 | + | |
| 179 | + | |
180 | 180 | | |
181 | 181 | | |
182 | 182 | | |
183 | 183 | | |
184 | 184 | | |
185 | 185 | | |
| 186 | + | |
| 187 | + | |
186 | 188 | | |
187 | 189 | | |
188 | 190 | | |
| |||
198 | 200 | | |
199 | 201 | | |
200 | 202 | | |
201 | | - | |
202 | 203 | | |
203 | 204 | | |
204 | 205 | | |
| |||
223 | 224 | | |
224 | 225 | | |
225 | 226 | | |
226 | | - | |
227 | | - | |
| 227 | + | |
228 | 228 | | |
229 | 229 | | |
230 | 230 | | |
| |||
Lines changed: 36 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
45 | 49 | | |
46 | 50 | | |
47 | 51 | | |
| |||
220 | 224 | | |
221 | 225 | | |
222 | 226 | | |
| 227 | + | |
223 | 228 | | |
224 | 229 | | |
225 | 230 | | |
| |||
233 | 238 | | |
234 | 239 | | |
235 | 240 | | |
| 241 | + | |
236 | 242 | | |
237 | 243 | | |
238 | 244 | | |
| 245 | + | |
239 | 246 | | |
240 | | - | |
241 | | - | |
242 | | - | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
243 | 251 | | |
244 | 252 | | |
245 | 253 | | |
| |||
326 | 334 | | |
327 | 335 | | |
328 | 336 | | |
| 337 | + | |
329 | 338 | | |
330 | 339 | | |
331 | 340 | | |
332 | | - | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
333 | 346 | | |
334 | 347 | | |
335 | 348 | | |
| |||
364 | 377 | | |
365 | 378 | | |
366 | 379 | | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
367 | 399 | | |
368 | 400 | | |
369 | 401 | | |
| |||
Lines changed: 8 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
62 | | - | |
63 | 62 | | |
64 | 63 | | |
65 | 64 | | |
| |||
123 | 122 | | |
124 | 123 | | |
125 | 124 | | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
126 | 129 | | |
127 | 130 | | |
128 | 131 | | |
| |||
135 | 138 | | |
136 | 139 | | |
137 | 140 | | |
138 | | - | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
139 | 145 | | |
140 | 146 | | |
141 | 147 | | |
| |||
Lines changed: 8 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
62 | | - | |
63 | 62 | | |
64 | 63 | | |
65 | 64 | | |
| |||
123 | 122 | | |
124 | 123 | | |
125 | 124 | | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
126 | 129 | | |
127 | 130 | | |
128 | 131 | | |
| |||
135 | 138 | | |
136 | 139 | | |
137 | 140 | | |
138 | | - | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
139 | 145 | | |
140 | 146 | | |
141 | 147 | | |
| |||
0 commit comments