Merge current TV recovery states into Conductarr wiring
This commit is contained in:
commit
a00db96dc8
43 changed files with 1041 additions and 199 deletions
156
docker/README.md
156
docker/README.md
|
|
@ -92,10 +92,10 @@ Settings list. Native Up traversal stays in content until the first focusable ro
|
|||
then enters the nav. Turning the switch on renders Wolfskin Home and Libraries.
|
||||
Discover and Requests are integrated Wolfskin surfaces; title hand-offs remain labelled.
|
||||
|
||||
Debug people, tabs and initials come from the shell-only projection of the locked
|
||||
prototype fixture in `app/src/debug/assets/wolfskin-shell.json`; release resources
|
||||
do not package it. Saved Jellyfin identities use existing upstream services. The
|
||||
shell makes no Conductarr calls and does not add Conductarr sign-in.
|
||||
Saved Jellyfin identities use the existing upstream session. Conductarr supplies
|
||||
household labels, requester capabilities and library audiences after sign-in.
|
||||
The locked shell projection in `app/src/debug/assets/wolfskin-shell.json` is used
|
||||
only when the Advanced debug fixture switch is enabled; release excludes it.
|
||||
|
||||
Discover adds the picks hero, type chips, catalogue shelves, service pages, continuous
|
||||
See all grids, Hidden picks, request chooser and receipts. Its `discover-title/...`
|
||||
|
|
@ -104,13 +104,12 @@ 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.
|
||||
`app/src/debug/assets/wolfskin-discover/`. The Advanced preview switch selects a
|
||||
network-free fixture host; real providers are the default in debug and release.
|
||||
The mutation adapter accepts the selected person's `ConductarrClient` and uses
|
||||
only typed routes. Request submission first reads title receipts. Unknown outcomes
|
||||
are checked, never blindly re-sent, including after closing a sheet or choosing
|
||||
the same uncertain recipient again. Whole-series requests require season metadata.
|
||||
|
||||
Discover hero and Restore text use explicit per-line CSS allocations so native
|
||||
paragraph overflow cannot enlarge the bottom-anchored stack. Restore subtitles
|
||||
|
|
@ -205,15 +204,15 @@ disk cache. A missing saved library becomes a recovery panel; a saved library
|
|||
stays visible when Jellyfin is unreachable. Playback resolves an actual film or
|
||||
episode and checks Jellyfin before opening upstream's player. No season,
|
||||
recommendation stub or different person's session is promoted to playback.
|
||||
An unresolved person switch shows the same sign-in guard for Home as for native
|
||||
library content, before mounting Home's source reads.
|
||||
An unresolved person switch guards Home and both owned/upstream library content
|
||||
before mounting any source read with the prior person's Jellyfin session.
|
||||
|
||||
Debug variants additionally package the locked fixture and local artwork under
|
||||
`wolfskin-design/src/debug/assets/wolfskin-home/`; release variants exclude them.
|
||||
The fixture provider supplies the approved household data and Home states without
|
||||
network reads in tests. Conductarr sign-in is not implemented here: real signed-out
|
||||
Home hides every rating and shows "Discover needs sign-in". No Seerr fallback is
|
||||
used. Catalogue data and ratings in debug captures are fixture-backed.
|
||||
The explicit fixture provider supplies approved household data and Home states
|
||||
without network reads in tests. Real signed-out Home hides every rating and shows
|
||||
"Discover needs sign-in"; signed-in Home reads the Conductarr continuation and
|
||||
ratings-only endpoint. No Seerr fallback is used.
|
||||
|
||||
Home, Libraries and Discover reuse `TitleCard`, `Caption` and `LibrarySeeAllCard`;
|
||||
those screens and Requests share one `WolfskinImages` loader. Exact-slot requests use RGB565 for posters,
|
||||
|
|
@ -251,13 +250,12 @@ for Back, and closing the sheet restores its opener. Selecting a root or changin
|
|||
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.
|
||||
The debug fixture switch loads `app/src/debug/assets/wolfskin-requests.json` and
|
||||
its eight local posters. Shared and focused-rating records also feed the native
|
||||
acceptance states; the identical projection is in design-test resources.
|
||||
No “sample” or “example stages” pill is drawn. The default provider instead maps
|
||||
Conductarr household activity, authenticated actors and display artwork into
|
||||
the same sheet. Release excludes all fixture assets. There is no Seerr fallback.
|
||||
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.
|
||||
|
|
@ -299,8 +297,7 @@ 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 currently uses an explicitly labelled
|
||||
`request-title/...` destination until the independent title screen is integrated;
|
||||
this slice does not claim to implement title pages, TV sign-in, release or device
|
||||
deployment.
|
||||
title pages, release and device deployment remain outside the Requests component.
|
||||
|
||||
## Libraries and See all
|
||||
|
||||
|
|
@ -323,8 +320,8 @@ The debug-only `wolfskin-library.json` and `library/assets/` contain the locked
|
|||
prototype's titles and local poster art. Release libraries read through
|
||||
`LibraryReadFacade`, with 200-item Jellyfin chunks and ten-minute per-server/person
|
||||
snapshots using the existing atomic disk cache. Saved data is painted before a
|
||||
quiet refresh; a failed refresh keeps it. Production ratings remain hidden until
|
||||
Conductarr sign-in exists.
|
||||
quiet refresh; a failed refresh keeps it. Production ratings remain hidden before
|
||||
Conductarr sign-in and use the shared ratings-only provider afterwards.
|
||||
|
||||
Home/Discover shelves open a full list through
|
||||
`WolfskinSeeAllLists.open(person, key, title, fullList, navigation, loadNextPage)`.
|
||||
|
|
@ -340,6 +337,109 @@ the title-screen implementation; this slice does not implement title pages.
|
|||
failure/retry, stale copies, and person/server isolation. Library captures are written
|
||||
to `build/wolfskin-captures/library/`; Discover's independent captures use `discover/`.
|
||||
|
||||
## Offline states and recovery
|
||||
|
||||
Owned screens share `RecoveryToast`: the warning glyph, 760 px maximum width,
|
||||
22/28 px padding, 14 px icon gap, 22 px corners and CSS-sized body line boxes.
|
||||
Network failures never expose transport exception text. Playback failure reads
|
||||
“Can’t reach Jellyfin to play. Check the network and try again.” and leaves the
|
||||
originating card focused; no simulated player hand-off panel is shipped. Retry
|
||||
failure reads “Still can’t reach it. The last saved view stays on screen.”
|
||||
|
||||
Library headers and the nav publish the same saved-copy timestamp. Failed library
|
||||
refreshes retain cards and expose a reachable Try again tail. Discover retains its
|
||||
current catalogue after a failed refresh, adds a recovery tail and disables request
|
||||
and dismissal writes until recovery; a revoked sign-in discards that saved projection.
|
||||
Previously observed plates can remain visible offline, but moving to an uncached
|
||||
card cannot start a ratings read. `SavedPill` shares the compact cached-header
|
||||
treatment across Home, Libraries and Requests; the nav retains its larger wifi chip.
|
||||
|
||||
Requests focus, observed ratings and retained rows are partitioned by selected person.
|
||||
A failed authenticated read preserves the last rows and their timestamp; Down from
|
||||
the final row reaches Try again and Up returns to the row. Signed-out data is not
|
||||
retained as an authenticated copy. Returning to a foreground person triggers that
|
||||
person's refresh rather than waiting for the prior person's polling timer.
|
||||
|
||||
Home disk snapshots remain server/user scoped. A new identity starts with its own
|
||||
skeleton or saved copy, never the previous person's projection; late responses from
|
||||
an older read cannot overwrite the current identity. A disk-write failure does not
|
||||
turn a successful Jellyfin read into an outage. Skeleton-only Home, Library and
|
||||
Discover screens keep focus in the nav even when Down is pressed repeatedly.
|
||||
|
||||
Library/Discover posters use the same title/glyph/160-degree gradient fallback as
|
||||
Home, including an actual Coil read failure. Discover hero image failures use the
|
||||
shared ambient background; missing artwork is not a successful data refresh.
|
||||
|
||||
`RecoveryStateTest`, `RecoveryCaptureTest`, `HomeRecoveryTest` and `PlayerHandoffTest`
|
||||
exercise state transitions, person isolation, native recovery focus/geometry and the
|
||||
real upstream playback destination with offline fixtures. New native captures and
|
||||
rendered text/font metrics go to `build/wolfskin-captures/recovery/`; Dutch score
|
||||
captures configure the Android resource locale as well as the JVM locale.
|
||||
|
||||
Conductarr transport and identity live outside the state components. A revoked
|
||||
sign-in discards the current person's authenticated projections; an outage keeps
|
||||
last-known-good (LKG) data and its Saved timestamp. No Seerr fallback or offline
|
||||
request queue is used. Title-family screen adoption remains a separate integration.
|
||||
|
||||
## Conductarr production wiring
|
||||
|
||||
The default endpoint is `BuildConfig.CONDUCTARR_BASE_URL`:
|
||||
`https://wolfskin-tv.justinvisser.org`. Override **Conductarr server URL** beside
|
||||
**Wolfskin screens** in Advanced settings; blank restores the build default.
|
||||
HTTPS is required except for loopback fake servers. **Wolfskin preview fixtures**
|
||||
is a debug-only, off-by-default switch; it never sends HTTP mutations.
|
||||
|
||||
`ConductarrSession` borrows the currently selected user's existing Jellyfin access
|
||||
token. It sends only `Authorization: MediaBrowser Token="<token>"`, with no cookie,
|
||||
API key or second credential store. Person/server/token/endpoint changes discard
|
||||
the old client and in-memory providers. LKG files are isolated by person and client
|
||||
identity in app-private, backup-excluded storage. A 401 clears that identity's
|
||||
cache and returns to sign-in states; Try again reconstructs and verifies the client.
|
||||
|
||||
| Screen seam | Production supplier |
|
||||
| --- | --- |
|
||||
| People and nav | Operator, profiles, library audiences; saved Jellyfin users remain the only selectable logins |
|
||||
| Home continuation | Recommendation feed, catalogue options/discovery; Coming soon stays Discover-only |
|
||||
| Discover | Feed/contributions, services, New on, Trending, genres, Coming soon, parameterized service shelves, dismissal reads/writes |
|
||||
| Catalogue paging | Two-shelf read-ahead, distinct title identities, per-parameter disk pages, retry/duplicate-only tails; no page counters |
|
||||
| Request sheet | Capability-limited requesters, season metadata, POST receipt, receipt lookup before any resubmit; actor comes only from the token |
|
||||
| Requests | Household activity, stage precedence, actor/requester evidence and display posters; foreground/30-second refresh |
|
||||
| Ratings | Ratings-only read after 350 ms card dwell; immediate hero/title/Coming-in reads; per-type six-hour/300-entry cache; episode season votes |
|
||||
| Additive title provider | Detail, cast, related, season/votes, performer, filmography, enrichment, display, title activity and uncached title receipts |
|
||||
|
||||
The pinned client exposes exactly the 22 TV operations, including ratings and
|
||||
display. Conditional reads send ETags and reuse the saved body on 304. The fake
|
||||
server tests use representative wire JSON, never a live Conductarr or Jellyfin.
|
||||
`ConductarrSessionTest`, `ConductarrProjectionTest` and `ConductarrSurfaceTest`
|
||||
cover identity/cache isolation, 401/retry, saved offline data, actor-safe requests,
|
||||
ratings timing and a native real-provider Discover surface. The existing fixture
|
||||
screen tests remain in the normal `make test` gate.
|
||||
|
||||
Not done here: adopting the new provider inside the independently reviewed title
|
||||
screen family; deploying the dedicated hostname or widening server authority;
|
||||
hardware installation/playback verification; releases, signing or version changes.
|
||||
The existing title integration destinations remain explicit rather than being
|
||||
silently replaced with invented catalogue/player data.
|
||||
|
||||
### Manual smoke after endpoint deployment (no build command)
|
||||
|
||||
Use an already authorized test build and a sandbox that accepts its selected
|
||||
Jellyfin login. No token needs to be copied, displayed or entered into Wolfskin.
|
||||
|
||||
1. In Advanced settings, set the sandbox URL with fixtures **off**. Select Shared,
|
||||
then another saved person; verify their operator/requester and independent views.
|
||||
2. Open Home, Discover, a service, Hidden picks and Requests. Check real catalogue
|
||||
text, stage/actor labels, card dwell ratings and continuous See all loading.
|
||||
3. Make the sandbox return 503 after a successful read. Reopen: saved content and
|
||||
Saved time remain, requests cannot submit, and Try again performs another read.
|
||||
4. Return 401, then restore authentication. Verify ratings/request actions disappear;
|
||||
Try again restores data without changing Jellyfin login or copying a token.
|
||||
5. Have the sandbox accept a Shared-on-behalf request but lose its POST response.
|
||||
Use Check again: the receipt says Shared, and the sandbox records one POST.
|
||||
6. Restore the blank/default URL when the dedicated TV hostname and server's
|
||||
22-operation authority are deployed. This checklist is manual, not a live gate.
|
||||
|
||||
|
||||
## Toolchain and disk use
|
||||
|
||||
`Dockerfile` pins Temurin JDK `21.0.11+10` by image digest, command-line tools
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue