Fix TV artwork, episode layout and focus visibility #47
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fm/tv-fb1-visual"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
TV feedback: artwork, episode layout and focus visibility
Implements the real-TV feedback against the approved revision-4 frames, with revision 5 documenting the requested deltas. AI-assisted implementation. No TV connection, ADB, installation or optimized-APK build was used.
Diagnosis and decisions
Dimensions and memory
The one-pixel Jellyfin response excess is aspect-ratio rounding; native Coil decoding measured 1920×1079 for both comparison sources, so the old source was upscaled while the new source supplies real detail. Decode fitting prevents oversized off-ratio allocations. Memory cache stays 64 MiB, disk cache 128 MiB, image concurrency 4, JPEG quality 96. No 4K hero decode. These are bounds, not measured Xiaomi RSS; no claim of device playback/performance verification.
Specification revision 5 · native prototype delta board · source/measurement evidence
Committed sources:
data/tv-spec/spec.md,data/tv-v2/feedback-2026-11-06/, the three token JSON files, generated Kotlin/CSS and drift manifest. The frozen revision-4 prototype is unchanged.Native before / after — 1920×1080
Captured with Robolectric native graphics, not browser approximations. Bear frames use recorded real Jellyfin metadata through
TitleReadFacade; other page frames use the existing native fixtures. All published PNGs have mode 0660. Pages are behind the existing sign-in gate.Hero source-quality comparison: same native renderer, real old/new Jellyfin responses; this isolates source resolution rather than pretending the renderer changed between these two captures.
Focus sequence coverage and excluded timing case
HomeViewportTestexercises short/long poster, tile and wide shelves: first item, row end, Up/Down and OK into the shipped title surface followed by native Back. It checks full card width, ring clearance, ≥40 px screen-side margin, nav clearance and bottom visibility. Native scenario frames: poster 6, poster 12, tile 4, tile 12, wide 3, wide 12.Known excluded case: a synthetic sequence disposes Home mid-animation, forcibly rewinds the retained lazy row to index 0, then restores logical selection. That interrupted/forced-rewind case still fails and was explicitly excluded by firstmate after two repair attempts. It is not presented as fixed or as normal Back behavior. No failing/ignored test or throwaway capture harness remains in the diff; no issue was filed for the excluded case.
Verification on
12fd12f754PersonPickerSessionTest: 7 passed.make test: 696 app tests, 3 person-picker session timeouts.make testthrough the approved scratch serial overlay: Gradle workers=1, test forks=1 verified in output; 696 app tests, 4 person-picker session timeouts. The selected person and closed picker were correct, but sign-in/identity remained empty. No picker session source/test change, excluded test or ignored test was used to hide these failures.launchRightThenOneOkKeepsPickerClosed,fastLeftLeftOkKeepsPickerClosed,avatarRightThenOneOkKeepsPickerClosed,gearAndBackThenOneOkKeepsPickerClosed. No SIGABRT occurred. The failure remains full-suite/order-dependent; a causal regression or baseline comparison is not yet established.make apk-debug: passed, including branding checks for all four debug APK packages. Debug uses stub playback codecs; this is not optimized-release playback proof.Session-timeout investigation
The observed failure is after
selectPersonclears the old identity but before setup creates the replacement model:models=1, emptysignedInPerson, null identity, correct selected person andpicker=false. Session, input routing andWolfskinApp.ktare unchanged; the picker change is offset/ring only. The only new test class,HomeViewportTest, belongs to the separate design-module test JVM and does not replace dispatchers or mutate a singleton. Full-run timestamps put the app Title classes after the picker, ruling out a preceding Title-class leak in that failed run.Forced ordered diagnostics passed 139 design cases + 77 app cases, zero failures/skips: design viewport/Home/Discover/shell/captures, then app native capture and title classes, with all seven picker tests last in the same app JVM (identity logged for every class). The throwaway ordered suite was removed before the full gate. Ordered results. No lifecycle leak was reproduced by that sequence. The failed full log also showed GCLocker allocation retries, but their causal connection is unproven.
Gate decision: both full serial runs on this head reached 696 app tests and four
PersonPickerSessionTesttimeouts, with Gradle workers=1 / test forks=1. The Discover watch-claims and request-history work passed the same full serial suite on a different base state; that does not clear this head. Noorigin/mainA/B was run; cause is not isolated. Firstmate explicitly chose review now rather than another baseline run. The four timeouts must be bisected on main as a follow-up; they are not fixed or waived as a known flake. Firstmate will verify real-box person switching (one OK per switch) before anything ships.Device review after merge
Firstmate builds/installs Opt after merge. Check centered gear and its ring/navigation; short and long row ends/Up/Down/Back on Home, Discover, Library, Person and Title; Bear S3 stills, episode descriptions, initial thumbnail visibility and Cast clearance; Home/Discover/title hero sharpness; consistent Discover lane gaps.