Build TV libraries and continuous See all grids #30
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fm/tv-slice4-libraries"
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?
Outcome
Build TV Libraries (Movies, Shows and Anime) and continuous See all grids. Ready for review, base
main, pushed head321f2d41bbb401160c5f118eb51f6e522b4b1ce9. Includes the merged shell and navigation, its settings-pill border correction (74033ee1), andorigin/mainmerge7a878b2d. No release or TV-install request.AI-assisted (fork-internal)
Refs: approved TV spec, sections 2, 4.4–4.9, 5, 6.4, 7.1–7.3, 8–10; locked Opus prototype.
Review corrections
Avatarhas an additive optionalletterColordefaulting to the shippedonFocus; onlyLibraryHeaderpassesmuted. This matches the locked header CSS override. Nav, picker, Settings and other callers are untouched; no public API was renamed.expected 19, reached 20) and now passes: twenty titles, index14 → 19 → 24; another Down stays on the visible tail, OK activates recovery once, and Up returns to title 18. No phantom slot can activate recovery along that path.captionSeparatorOpacitytoken multiplies the existing muted colour alpha, matching CSSopacity: .4; preserves the existing separator spacing and accent availability text. No full-strength separator remains in the recaptured movie/catalogue captions.Implemented
library-title/{id}sibling-fill destination. Home/Discover caller API:WolfskinSeeAllLists.open(person, key, title, fullList, navigation, loadNextPage); those screen slices own the callers.Exit-check evidence
Every native half is 1920×1080, density 2.0, Robolectric SDK 34/Roborazzi; frozen prototype left, Compose right. All sixteen pairs were regenerated on final head
321f2d41. The avatar pass inspected the reference/before/native atlas and measured all visible header initials; original full-screen reviews covered the sixteen layouts. No browser/native pixel-equality sign-off.Download current raw captures, references, amplified diffs, numeric reports, header-colour/native-scope smoke, frame-local font measurements, final build log, exact final-head label and all 79 JUnit XML files. No APK is included or distributed. This archive and the table below supersede earlier attached proof, retained only as history.
Font ruling: keep the spec’s platform Roboto; frozen host-browser frames use DejaVu Sans. No font is bundled, and no per-title/per-row compensation is applied. Wrapping parity is not claimed. Each frame’s last column gives measured ink extents or wrapping; measurement rectangles/thresholds are in the font report and raw data. No ellipsis-parity claim is made.
Difference legend: F = Roboto/DejaVu glyph widths, weights, line boxes and rasterisation, vector marks, native image sampling and reference JPEG compression. P = corrected full line boxes/border space preserve panel top/1100 px width; native height 264 px versus Chrome 263 px is integer line-box rounding (the initial 12 px shortfall was repaired). U = review-directed omission of the unavailable header’s fixture count, an explicit difference from st-027’s “29 series”. W = tail explanation wraps differently, measured below. S = prototype-only sample label omitted as required. R = frozen Anime frame shows Chainsaw Man’s 97% critics score despite being named “TMDB only”; the capture is authoritative.
Mean RGB error averages absolute RGB-channel differences on a 0–255 scale. The percentage counts pixels whose maximum channel difference exceeds 12. Nav error covers the top 150 pixels, including background.
Header-avatar colour and unchanged generic avatars
Reference / previous / corrected colour atlas; all sixteen measurements and pixel-scope assertions; raw JSON. RGB below is the median of the strongest inner-glyph pixels, independent of differing glyph shapes. The source now uses the exact existing
mutedtoken; these rendered medians are not a claim of JPEG/PNG pixel equality.The native smoke asserts every visible header initial moved closer to its frozen reference, and zero pixels changed outside the header-avatar rectangle. This includes unchanged dark navigation initials in every frame. Fourteen headers are visible; st-035 and st-095 have scrolled past the header and remain entirely pixel-identical to the prior head. Existing sixteen screenshot tests exercise the surface; no unit test of colour forwarding/default wiring was added.
Accepted separator remeasurement (unchanged by B3)
Brightest RGB channel in isolated separator/year rectangles; bounds and background-adjusted ratios are in the measurement report and raw JSON. The remaining one-level dot difference is [INFERENCE] consistent with JPEG/native glyph rasterisation and alpha quantisation; pixel equality is not asserted. CSS opacity multiplies the muted alpha rather than replacing it.
Keys and data
screens/library.jsonpress-path data replays actual Android events through the real shell/grid: Spirited Away in 20 presses. Other paths cover short rows/recovery tails, toolbar sort, Back/Down restoration, rail threshold/jump/return, and key-up/held-repeat protection.Commands and results — final avatar-correction head
make teston321f2d41BUILD SUCCESSFUL in 2m 9s. All existing tests retained; no assertion weakened. Tail regression and approved 20-key replay passed.make apk-debugon321f2d41BUILD SUCCESSFUL in 51s. Four packaged debug APK branding checks passed, inspecting 1013 resource keys/configurations each. Compile proof only; no APK distributed.origin/mainwas fetched before the correction and had not moved from7a878b2d, so no merge was necessary. The source and documentation were committed before both gates; they ran on the final pushed head. The checkout-scoped untracked offline hook used the approved preseeded Robolectric cache and was removed afterwards; no tracked build/cache/credential workaround changed. The stale final-head proof label is corrected.Upstream files touched
None relative to
main. Runtime edits remain inapp/src/wolfskin/java, debug fixtures, new tests and:wolfskin-design. Existing documentationdocker/README.mdexplains the library/provider/focus/verification rules. Shared shellShellState,Caption,GlyphandAvatarare extended, not forked; tokens regenerate Kotlin/CSS/checksums together. No upstreamapp/src/mainfile, build configuration, player or preference implementation changes in this slice.Not done / boundary
Review-directed follow-ups, not implemented here:
id; move to canonicalcatalogueKeybefore production mixed-catalogue consumers can supply movie/series ID collisions.Conductarr sign-in/live ratings and catalogue integration, Home/Discover/title screens and caller-side cutovers remain their assigned slices. This supplies their full-list/provider/title-destination seams, not replacement screens. Native/browser font and intrinsic-layout residuals above remain visible. No release build/tag/asset/signing/version change, ADB, device interaction, installation or TV profiling occurred. Firstmate arranges review and any merge; release/install still require Justin’s word.
Design and spec review (Claude Sonnet, cross-family): CHANGES REQUESTED
Reviewed head:
3da635b4cb26593521ae2ae89612e9edfad18214, judged asgit diff origin/fm/tv-slice2-shell...HEAD(shell base2ea93010). Read-only review: no Gradle run; the lane'smake testandmake apk-debugresults are taken from the PR body.Blocking (2, both small)
LibraryGridStateDown useslast = tailIndexfor the clamp instead of the last real card. The prototype goes from the short row to the one-card tail row. No existing test has a tail with focus movement. Fix: step to the last real card on a short row, and go to the tail only from the last item row; add a test (20 items,tail = Retry, index 14, Down must reach 19, next Down 24).Design parity. All 16 pairs viewed at native resolution (st-021 to 028, 030, 035, 039, 095, 097, 098, 112, 113) and measured: focus ring 4 px both sides, panel/chip/tail borders 2 px both sides, chip height 68 and gap 16, grid pitch, plate marks and 2-of-3 prefix on st-095, tail row placement on st-035, empty/unreachable/loading panels. Font weight checked by stem width (consistent with Bold on both sides). Nothing else differs beyond Roboto versus browser metrics. The 1 px panel line-box difference the lane reported is real and accepted.
Spec and tests. The Spirited Away test replays the approved
pressPaths(identical to the spec'slibrary.json) as real Android keys through the real shell and grid handler, and asserts the end card; it fails on any clamp, row or sort-order break. The 200-title rail gate is tested at 199/200 and with a non-A-Z sort, including jump and Back. Key-up and hold guard, Back ladder, view memory, ratings formatting and the plate rule all follow the spec. The spec's "68th of 84" is a typo for the 69th card (index 68); no behaviour change needed.Architecture and hygiene. No upstream file touched (spec 2.7 list respected); the existing shell key adapter, tokens, focus and back ladder are reused; no hand-written Conductarr HTTP; no network in tests; OK goes to the named
library-title/{id}stub. No test deleted or weakened, no release/signing/version change, plain imperative commits without trailers.Non-blocking, with severity
readLibrarypublishes only after every 200-item chunk is read; spec 6.4 says read ahead of focus.idwhile the card key usescatalogueKey;LibrarySeeAllCardis unused and unverified; the plate fit is notremembered; 8 MB of posters and the fixture JSON are committed twice (debug assets and design test resources);LibraryFixtureships in the design module's main source set.Full evidence, measurements and file:line references are in the review report held by firstmate.
Design re-review (Claude Sonnet): changes requested, 1 blocking item
Reviewed head:
60a0da13a2d222dc177ed85ad465d8cbedb3c541(previous review head3da635b4cb26593521ae2ae89612e9edfad18214). Read-only pass, no Gradle. Full report:/root/.treehouse/firstmate-7bab20/2/firstmate/data/review-wolfskin-30-r2/report.md.Fixed from the first review
LibraryGridStateDown now clamps to the last real title, then enters the tail card; I traced 20 titles plus a tail (14, 15, 17 now go to 19, then 24; the old code landed on empty slots 20, 21, 23). The new testdownClampsShortLastRowBeforeEnteringRecoveryTailuses a real tail and a short last row and would fail on the old code (first Down gives 20, not 19).captionSeparatorOpacity0.4 applied to the muted colour's alpha). Measured on the refreshed captures against the prototype frames: dot peak 80 vs 81 in all 16 states (was 182 vs 79).Blocking: header avatar initial colour
In every locked frame the person avatar in the library header draws its initial in the muted colour (the prototype's
.lib-h span{color:var(--muted)}overrides.av{color:#0b0b10}). Compose draws it dark (onFocus) via the sharedAvatar(Identity.kt). Measured on st-021: reference glyph about (220,245,218) vs dark ink in Compose; visible in all 16 pairs. This was present on the previous head too and I missed it in round 1. The fix is small: giveAvataran optional letter-colour parameter and passmutedfromLibraryHeader, then re-capture one state. (If Justin prefers the spec'sonFocuswording this needs his explicit approval.)After that fix I see nothing else blocking.