Integrate reviewed Requests and Discover surfaces
Some checks failed
review/design-claude Changes requested: 13 blocking design/behaviour findings (see PR comment)

This commit is contained in:
justinzeus 2026-11-05 20:46:58 +01:00
commit e243894a20
730 changed files with 4496 additions and 92 deletions

View file

@ -59,8 +59,8 @@ cover the Wolfskin nav.
The independent `:wolfskin-design` module owns the shell components, fixed person
colours, focus policy, per-person root-view memory, palette and motion. Its
`tokens.json` is the copied approved TV-spec source, retaining the locked prototype
SHA and provenance. `shell-tokens.json` adds shell and grid measurements;
`title-tokens.json` adds title, performer and playback-sheet measurements from
SHA and provenance. `shell-tokens.json` adds shell/grid/request measurements;
`title-tokens.json` and `discover-tokens.json` add their screen measurements from
that same prototype. Generate the committed Kotlin, CSS and checksum manifest together:
```sh
@ -84,8 +84,8 @@ padding includes it. The 6 px dash / 4 px gap follows the browser's 3:2 stroke-w
ratios. Resting borders are white at 22% opacity; focused borders use ink at 40%.
The small gear under the final person opens Settings with Requests focused.
Settings groups hand off to existing upstream pages; the Requests entry explicitly
has no request data yet. **Advanced settings → Wolfskin screens** is the persistent
Settings groups hand off to existing upstream pages; Requests opens the household
Coming-in sheet described below. **Advanced settings → Wolfskin screens** is the persistent
rollout switch: turning it off renders upstream Home and library destinations with
the upstream Backdrop and top scrim, while retaining Wolfskin's nav, picker and
Settings list. Native Up traversal stays in content until the first focusable row,
@ -97,6 +97,51 @@ prototype fixture in `app/src/debug/assets/wolfskin-shell.json`; release resourc
do not package it. Saved Jellyfin identities use existing upstream services. The
shell makes no Conductarr calls and does not add Conductarr sign-in.
Discover adds the picks hero, type chips, catalogue shelves, service pages, continuous
See all grids, Hidden picks, request chooser and receipts. Its `discover-title/...`
destination is an explicit title-family integration stub exposing only Discover's
request and pick actions. Unheld titles have no trailer control until the pinned
Conductarr title contract supplies a trailer.
The debug-only fixture and local art live in
`app/src/debug/assets/wolfskin-discover/`. Release builds remain on the explicit
Conductarr sign-in state. The fixture host cannot construct a network client:
debug request outcomes and dismissals stay in memory. The real mutation adapter
accepts an injected `ConductarrClient` and uses only its typed routes; it is not
wired to a live server. Unknown request outcomes force a fresh title-requests read
instead of blindly submitting again, including after closing a sheet or choosing
the same uncertain recipient from another chooser. Whole-series requests require every season.
Discover hero and Restore text use explicit per-line CSS allocations so native
paragraph overflow cannot enlarge the bottom-anchored stack. Restore subtitles
retain the sheet's negative top margin and bottom gap. Recovery panels may
overflow their fixed-height scroll row so sign-in copy never shrinks the retry
button. Native regressions cover those three layout boundaries.
Discover's native capture suite covers its 28 named acceptance states and emits
text-layout metrics beside the PNGs. Data-driven Android key replays cover opening
Discover in 4 presses, requesting for yourself in 7, requesting for Mindel in 9 and
Not interested in 8. Additional regressions exercise held-OK safety, uncertain
receipts, per-recipient outcomes, collection recovery and Undo, unknown seasons,
Dutch decimal formatting and short-row/tail clamping. Discover reuses the Libraries
grid, poster, ratings plate, See all and recovery cards, bounded image loader, caption
separator token and the shell's single hold guard. Both frames share the 180 ms scroll tween.
The TV keeps platform Roboto with the approved type sizes and weights. Browser
system-font wrapping is not a per-title contract: no bundled font, forced title
breaks or width compensation is applied. Discover's own stacked text preserves
untrimmed CSS line boxes without changing merged shell/library typography. Hero,
sheet and shared focused-content shadows use tokenized drop shadows, not Material
elevation; their alpha animates in the draw phase. Native text-layout measurements
accompany each acceptance capture; remaining font-driven wrapping and text-block
positions must be listed explicitly in its comparison report.
The asynchronous debug fixture seam hands loading focus back to the first loaded
action when Discover is still the selected destination. A JVM regression releases
the actual host's suspended fixture load and presses Android OK: it must open the
hero rather than activate the nav. Fixture completion does not steal a different
destination or nav selection.
Native Roborazzi captures use Robolectric SDK 34 and
`w960dp-h540dp-xhdpi` (1920×1080 at density 2.0). `make test` writes capture PNGs and
the sampled Compose nav-spring curve to `build/wolfskin-captures/`. Key replays
@ -121,6 +166,68 @@ artifact provider and AAPT2. It checks all string, plural and array configuratio
rejecting user-visible upstream branding while preserving the upstream legal
attribution and project URL. The check does not depend on incremental merge files.
## Requests under Settings
The Requests row and Coming-in sheet share one immutable household snapshot.
Ready requests do not count as open. Rows sort Failed, Downloading/Almost ready,
Checking/Searching, Waiting, Ready. The bounded window shows five rows, or four
with readiness expanded. Right expands Request/Download/Library/Playback; Left
collapses; Up/Down collapse while moving. Opening a title preserves the request
for Back, and closing the sheet restores its opener. Selecting a root or changing
person clears the title-return link. Shared's authenticated actor always reads
“by Shared”, never “by you”.
The debug-only provider loads `app/src/debug/assets/wolfskin-requests.json` and
its eight local posters, projected from the locked prototype fixture. Six stage
rows feed the running debug shell; the Shared and focused-rating records feed
native acceptance states. The identical projection is in design-test resources.
No “sample” or “example stages” pill is drawn. Release builds package none of
these assets and show Requests unavailable until Conductarr sign-in supplies
the generated-client data path. There is no Seerr fallback or handwritten HTTP.
Foreground refreshes once; an open sheet or unsettled requests refresh every
30 seconds while started. The immutable debug projection is loaded once, not
decoded again on every poll.
Thumbnails reuse `LibraryImages` with a 96×144-pixel request, RGB565, no crossfade,
the shared 64 MB memory/128 MB disk cache and four-read limit. Actor separator
dots use the surrounding text colour; the 40% rule applies only to poster captions.
Uncached focused ratings wait 350 ms; moving away cancels the read. Read ratings
show immediately on return; sign-out clears visibility. This follows the frozen
page and spec 6.12, resolving the contradictory no-dwell sentence in spec 7.8.
Deterministic coroutine-clock tests cover cancellation, reentry, cached return,
sign-out and refreshed locale scores; a thin Compose test verifies actual Dutch
rendering and sign-out suppression. The approved nine-key Requests path is JSON
data replayed through the real shell. Home's hero content is not implemented
here: its launch-to-nav shell suffix is the acceptance seam.
Sheet dimensions, padding, glyphs, scales, colours and durations are generated
tokens. Scoped sheet line boxes retain CSS heights and baselines independently
of native leading rounding; shared shell/library typography is unchanged. Platform
Roboto remains required: the host browser used DejaVu Sans, so its width,
wrapping, ellipsis and text-block positions are not a wrapping-parity target.
For example, the 44-pixel “Coming in” ink is 239 pixels wide in the reference
and 194 pixels in native captures. No per-title compensation or font bundle is
used. Native comparisons must report those structural differences explicitly.
Readiness glyphs sit inline on the text baseline with no flex gap, matching the
frozen block-span cascade. Items wrap intrinsically: Roboto fits the expanded
readiness into two lines where the reference uses three; no grouping is forced.
The six rating marks retain the exact locked SVG source in
`wolfskin-design/request-marks/`; native-size PNGs and their hashes are generated
from the JSON dimensions with the locked contain fit (`.rr .rb` outranks `.crow img`).
Inside Coming-in rows they retain the prototype's dark `surface3` chips with 12-pixel rounded corners.
Loaded poster thumbnails have no placeholder fill beneath their clipped edge.
```sh
uv run --with cairosvg==2.9.1 python wolfskin-design/generate_request_marks.py
```
`RequestsCaptureTest` writes `st-081`…`st-086`, `st-088` and `st-111` at 1920×1080,
density 2.0. Title selection opens the shared native title destination by media
type and TMDB identity. Back restores the exact Coming-in row and expansion;
the temporary `request-title/...` placeholder is removed. TV sign-in, release
and device deployment remain separate.
## Libraries and See all
Movies, Shows and Anime use the shell's retained view and a continuous six-column
@ -135,8 +242,8 @@ its unknown item count.
Caption separators use 40% of the existing muted colour's alpha. The rail follows
the locked prototype CSS: bold 24 px letters, with the focused letter bold 28 px,
overriding the spec table's generic caption style for this component.
Library header initials use the muted colour over the person's fill; navigation,
picker and Settings avatars retain their dark initials.
Library and Settings header initials use the muted colour over the person's fill;
navigation and picker avatars retain their dark initials.
The debug-only `wolfskin-library.json` and `library/assets/` contain the locked
prototype's titles and local poster art. Release libraries read through