feat: accessibility pass (VoiceOver, dynamic type, contrast, tap targets)#38
Merged
Conversation
Player controls (video_player_screen.dart): tooltip/semantics labels on the icon-only back, skip-back/forward and play/pause controls (play/pause is state-aware), a label on the 360p preview badge, and a slider role on the seek bar (NullFeedProgressBar) with a spoken time value plus increase/decrease actions so VoiceOver can scrub. Cards: video_card, channel_card and video_list_tile now expose a single merged label (title + channel + state like "downloaded"/"downloading") via Semantics(excludeSemantics:), while keeping secondary controls (channel link, actions menu, download/cancel) as their own operable nodes. Dynamic type: clamp the platform text scaler to 0.8-1.3 at the app root and grow the content rows with the text scale so layouts hold up. Contrast: raise textMuted from #666666 to #858585 to meet WCAG AA (4.5:1 on cards, 5.4:1 on the base background; was ~2.9:1 on cards). Tap targets: inline cancel buttons, the actions menus and the speed button now meet the 44pt minimum. Adds test/widgets/accessibility_test.dart covering the seek-bar slider semantics and the card labels. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RXMKM1rDWn8wNh93MMUtxY
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Accessibility pass (roadmap LATER tier, #20). The app previously had effectively zero a11y.
VoiceOver
NullFeedProgressBar) now exposes slider semantics (role, "Video position", spoken "M:SS of M:SS", ±5% increase/decrease) so VoiceOver can scrub. This also fixed a latent bug: a valued slider with an increase action must define increased/decreased values or Flutter asserts under a screen reader.excludeSemantics+ explicit label, so secondary controls — channel link, actions menu, cancel — stay individually operable rather than merged into one node).Dynamic type
App root clamps the platform text scaler to 0.8–1.3; horizontal content rows grow with the clamped scale so titles keep room. (Text already scaled; this bounds extremes.)
Contrast (WCAG AA)
textMuted#666666 → #858585: was 3.45:1 / 2.90:1 (fail) on base/cards; now 5.37:1 base, 5.08:1 surface, 4.52:1 cards — all ≥ 4.5:1. Smallest bump that clears AA on the worst real surface.Tap targets
Inline cancel/stop and actions menus bumped to a 44×44pt minimum; player speed button padded to ~44pt.
Verification
dart formatclean ·flutter analyze --fatal-infos --fatal-warnings— No issues ·flutter test— 92 passed (+6 inaccessibility_test.dart: seek-bar slider semantics + merged card labels).🤖 Generated with Claude Code
https://claude.ai/code/session_01RXMKM1rDWn8wNh93MMUtxY