9fee07f080
A release below §5.5's floor was rejected with no way through, so a policy wrong about one title left three Rick and Morty S09 packs visible and none grabbable. `allow_below_floor` relaxes the floor for one title into a soft fail, never a pass: the release is waived, so automatic grabbing still skips it and the import records a §5.7 waiver. The deck offers the one click on a rejected row where the rule has an override, which is exactly what §9.3's override is for. Stored verdicts are re-derived when a title's overrides change — the deck and the daemon's grab gate both read that column, so without it the row the operator just acted on would keep reading `rejected`. Closes #210 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
81 lines
5.1 KiB
Markdown
81 lines
5.1 KiB
Markdown
---
|
|
version: 1
|
|
slug: "web-src-main-ts"
|
|
primary_target: "web/src/main.ts"
|
|
related_targets: ["web/index.html","web/src/search.ts","web/src/releases.ts","web/src/library.ts","web/src/style.css"]
|
|
---
|
|
|
|
# Surface: unified search + release deck + library (web/src/main.ts, §9.2 + §9.3 + §4.2)
|
|
|
|
Mode: Operate. The operator finds or adds a title without knowing which of
|
|
the two they are doing, picks a release from decisions, not name dumps, and
|
|
reads the library as derived status, not flags.
|
|
|
|
- Audience: the household operator; desktop mostly, phone sometimes.
|
|
- Task: one rail-mounted command input. Typing swaps the current surface for
|
|
the search deck; clearing or Esc returns to the board. "/" focuses from
|
|
anywhere.
|
|
- Structure (pinned by DESIGN.md §9.2): IN LIBRARY group first, ON TMDB below,
|
|
engraved micro-label headings, machined rows, chips on the right.
|
|
- Add flow: inline panel under a TMDB row of either kind — root radio cards
|
|
(audience name, policy name, path), main pre-selected, one confirm. Never a
|
|
separate page. A series adds the one §4.1 add-time question: an auto-track
|
|
pressed control (default on) with the plain line "future seasons are tracked
|
|
automatically; past seasons are not", echoed in the added confirmation.
|
|
- Release deck (§9.3, issue #31): a library row opens the buckets view.
|
|
ELIGIBLE leads with fixed-width attribute chips in aligned mono columns
|
|
(rem-width `.cw-*` classes shared by chips and the column header, so the
|
|
pseudo-table survives flex wrapping); WAIVED and REJECTED collapse to
|
|
counts behind cyan show/hide toggles. Release name is a secondary
|
|
truncated line, full string plus indexer/date/bytes on row expand. Every
|
|
waived/rejected row carries a verdict chip naming the rule. Grab is its
|
|
own control per row; where the rule that failed has an override it reads
|
|
"waive + grab" and writes the per-title override (rule→override mapping in
|
|
releases.ts — bookkeeping, never policy; verdicts always come from the
|
|
API). A rejected row offers it too — §9.3's one click exists precisely for
|
|
the rule the operator disagrees with, and a size rejection (#210) is only
|
|
ever rejected. What the click produces stays a waiver: the row re-reads as
|
|
a dashed WAIVED, never eligible. When ELIGIBLE is empty and something is
|
|
waivable, its "none" line carries the count, so the way out is not folded
|
|
inside a collapsed bucket. Esc steps back one
|
|
layer: deck → search results → board.
|
|
- Removal (§7.4, issue 104): REMOVE is a quiet control in the deck head,
|
|
never a row affordance — a dense list is the wrong place for a delete.
|
|
It opens one inline confirmation carrying the evidence first (file count,
|
|
total size, the §7.4 folder as reported by `/api/movies/{id}/files`), then
|
|
the decision, then the cost. "delete files from disk" is a separate toggle
|
|
that starts OFF and stays disabled when nothing is on disk or the file list
|
|
cannot be read; armed, the panel, its toggle word, the note and the confirm
|
|
button all turn caution amber, and the confirm reads "remove and delete
|
|
files" instead of "remove from library". The note says what does not happen
|
|
either: the torrent keeps seeding (§7.3). Esc abandons the confirmation
|
|
before it abandons the deck. On success the deck closes and the surface it
|
|
opened over repaints, so a removed title never lingers in a list.
|
|
- Library view (§4.2, issue #32): the LIBRARY rail control opens the library
|
|
deck — SERIES then MOVIES groups. Status is derived and only displayed
|
|
(§4.2 status chips in the channel-violet/neutral family for series, state
|
|
chips for movies); intent is `wanted` at the leaf and no surface offers a
|
|
monitored flag. Default set = airing + incomplete series and
|
|
wanted-and-missing movies; everything satisfied collapses behind ONE cyan
|
|
toggle carrying its count. A waived import reads honestly as a dashed
|
|
amber chip ("english, no dub"). A movie row opens the release deck over
|
|
the library and Esc returns there; series rows are inert until #39. Esc
|
|
layering uses capture + stopImmediatePropagation — three surfaces listen
|
|
for Escape on the same window.
|
|
- Manual intake: magnet / .torrent input routes to a MANUAL GRAB panel showing
|
|
parsed display name and btih; magnet grab wiring is issue #22, and the
|
|
panel says so honestly.
|
|
- Constraints: 250 ms debounce, AbortController cancellation, token-gated CSS,
|
|
cyan for interaction only, dead-air rule (no idle animation), no horizontal
|
|
scroll at any viewport (§9.3 acceptance criterion).
|
|
- Unified search covers both kinds (issue 130): in-library hits read as
|
|
whatever they are — a movie row, a series hit (display-only until the
|
|
detail view of issue 129 exists) and an episode hit rendered as its series,
|
|
an `SxxEyy` chip and the episode title in sans beside it. TMDB rows show TV
|
|
alongside film; the "in library" dedup spans movies and series.
|
|
- Unresolved: releases land in the persisted store only once the daemon
|
|
consumes search commands (#68-adjacent); episode hits have no link target
|
|
until issue 129's series detail view exists — they render display-only for
|
|
now; per-season and per-episode library actions are #39; attention queues
|
|
surface is #33.
|