Skip to content

Smooth out tvOS focus, navigation, and readability across the shell - #15

Open
nafields wants to merge 1 commit into
mainfrom
feature/ios-skills-router-ui-99d0d7
Open

Smooth out tvOS focus, navigation, and readability across the shell#15
nafields wants to merge 1 commit into
mainfrom
feature/ios-skills-router-ui-99d0d7

Conversation

@nafields

@nafields nafields commented Jul 9, 2026

Copy link
Copy Markdown
Owner

What changed and why

  • Fixed the root causes of focus jumping and unpredictable back/forward navigation. The shell's Menu handler was installed through a conditional view branch, so the whole shell tree was torn down (dropping focus and scroll state) whenever back-consumption flipped — now an optional closure with stable identity. The shell's programmatic focus-handoff methods were no-ops; they now publish a generational request each screen consumes exactly once, so focus lands on the remembered tile when entering a screen from the side rail, back navigation, or stream exit. Opening the side rail now highlights the current tab (it previously opened unfocused and the engine picked Settings on the next press). Removed all imperative focus writes inside onMoveCommand handlers — they raced the focus engine's own move, so a single D-pad press moved focus twice.
  • Seamless transitions and in-stream escape. Shared motion tokens add a 0.22 s crossfade to tab/utility/load-state/settings-pane switches and the stream handoff, and unify seven scattered focus-animation durations at 0.14 s. The Siri Remote's back button in a stream (previously swallowed silently) now shows/hides the stream overlay while still preventing accidental dismissal. Home's hero carousel stops auto-advancing while its buttons are focused.
  • Readability and menu clarity for 10-foot viewing. Search shows the browse catalog instead of a blank screen for an empty query and no longer clips at the top. Game tiles gain a focus scale plus larger, higher-contrast text; sub-TV font sizes were raised across the detail hero, settings, chips, cards, and console list. Settings panes renamed to plain language (Overview / Streaming / Controller / Video & Audio / Appearance / Advanced) with Controller added to Basic mode; pane raw values are unchanged so persisted selections survive.

Screenshots or recording

N/A — needs a simulator/device pass; validated via builds and unit tests (see test plan). Reviewers should exercise: side-rail open (Menu or left-edge) highlighting the current tab, D-pad movement through Library header/grid, detail push/pop focus restore, and Menu in-stream toggling the overlay.

Test plan

  • Tools/dev/run_debug_build.sh — Stratix-Debug builds clean
  • xcodebuild test (Stratix-Validation, -only-testing:StratixTests) — 134 passed / 0 failed, including new coverage for the generational focus request (CloudLibraryFocusStateTests) and Basic-mode pane visibility (CloudLibrarySettingsPaneTests)
  • Relevant CI lanes: shell state tests, shell UI checkpoints

🤖 Co-authored with Claude Code

Focus & navigation:
- Pass the shell exit-command handler as an optional closure so toggling
  back-consumption no longer rebuilds the entire shell subtree (this was
  dropping focus/scroll state whenever the side rail opened on Home)
- Make CloudLibraryFocusState.requestTopContentFocus a real generational
  request, consumed once per generation by Home/Library/Search/Consoles,
  so focus lands predictably on rail hand-off, back, and stream exit
- Claim side-rail focus on the selected tab when the rail is expanded
  externally (it previously opened unfocused and the engine picked
  Settings on the next press)
- Remove imperative focusedTarget writes from onMoveCommand handlers;
  they raced the focus engine's own move and made focus jump twice per
  press. Handlers now only cover true dead-ends (leading-edge rail
  entry, hero carousel paging)
- Restrict rail entry to the leading item of Library tab/chip rows
- Drop MediaTileView forcedFocus override (could ring two tiles at once)
- Guard console focus restore so background refreshes don't steal focus
- Pause the Home carousel auto-advance while the hero is focused
- Route the swallowed Menu press in-stream to the overlay toggle so the
  Siri Remote back button surfaces/hides the stream overlay
- Settings sidebar declares a single defaultFocus on the selected pane

Transitions & layout:
- Shared Motion tokens: 0.22s route crossfade applied to tab/utility/
  load-state switches, settings panes, and stream-priority handoff;
  0.14s focus curve unifies previously scattered 0.08-0.25s animations
- Search: render the browse catalog for an empty query (was blank),
  apply top content padding, and disable scroll clipping
- Consistent min-height status panels on Home/Library/Search

Readability:
- MediaTileView gains a focus scale and larger, higher-contrast text
- Raised sub-TV font sizes across detail hero, settings components,
  sidebar rows, chips, cards, and profile; textMuted 0.55 -> 0.65
- Settings panes renamed to plain language (Streaming, Controller,
  Video & Audio, Appearance, Advanced) and Controller added to Basic

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Jerrychenshen added a commit to Jerrychenshen/stratix that referenced this pull request Jul 14, 2026
Combine PR nafields#8 language option with PR nafields#15 tvOS fixes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant