a11y: Group chat rows and label tapbacks/unread for VoiceOver#2119
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughVoiceOver accessibility labels are added across channel navigation, message rows, reactions, and alert controls. Localized strings describe unread counts, senders, replies, security status, reactions, and muted channels. ChangesVoiceOver accessibility
Estimated code review effort: 2 (Simple) | ~15 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
# Conflicts: # Localizable.xcstrings
garthvh
left a comment
There was a problem hiding this comment.
Approved after detailed review (CodeRabbit confirmed no actionable items). Accessibility grouping/labels verified correct; CI green. Merged current main to resolve the Localizable.xcstrings key conflict (union of both key sets, JSON validated).
What changed?
Makes the chat surface coherent to VoiceOver: each message bubble reads as one element instead of many fragments, and icon/color-only affordances get spoken labels.
messageAccessibilityLabel("You sent: …" / "Message from : …", timestamp, plus "Encrypted"/"Verified" mirroring the visible security badges) applied to the bubble via.accessibilityElement(children: .combine). The sender caption is folded in with.accessibilityHidden(true); the reply-quote button gets its own label. Delivery status, RetryButton, and reactions stay siblings outside the combined element so they remain independently navigable and context-menu actions (reply/tapback) stay on the Actions rotor.channel.unreadMessagesfetch is hoisted to run once per row (was twice).Localizable.xcstringskeys.Why did it change?
Chat rows exposed sender, text, timestamp, security badges, and reactions as separate, out-of-order VoiceOver fragments, and several affordances (reactions, unread, mute, alert) were unlabeled color/icon-only elements. Grouping the bubble and labeling the affordances makes conversations understandable and actionable with VoiceOver.
How is this tested?
Built the
Meshtasticscheme for iOS Simulator (iPhone 17 Pro, Xcode 26) →** BUILD SUCCEEDED **. SwiftLint clean. Passed a focused Swift/SwiftUI review that traced the view composition to confirm.combineis scoped to the bubble only (reactions/retry/actions remain reachable) and that the "Encrypted"/"Verified" conditions are an exact match toMessageText.cornerBadges. A live VoiceOver pass to confirm the Actions rotor enumerates reply/tapback is recommended before merge.Screenshots/Videos (when applicable)
N/A — no visual change; affects spoken VoiceOver grouping/labels only.
Checklist
docs/user/ordocs/developer/. No doc update is needed (VoiceOver labels only, no UI/flow change) — please apply theskip-docs-checklabel.Summary by CodeRabbit