Files
arr/.impeccable/surfaces/web-src-main-ts.md
T
naps62-yolo f38fb1277b
ci / web (push) Successful in 33s
ci / rust (push) Successful in 1m29s
e2e / e2e (push) Successful in 1m12s
Library views with derived status (#83)
2026-08-22 23:33:05 +01:00

3.1 KiB

version, slug, primary_target, related_targets
version slug primary_target related_targets
1 web-src-main-ts web/src/main.ts
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 — root radio cards (audience name, policy name, path), main pre-selected, one confirm. Never a separate page.
  • 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; on a waived row it is "waive + grab" and writes the per-title override (rule→override mapping in releases.ts — bookkeeping, never policy; verdicts always come from the API). Esc steps back one layer: deck → search results → board.
  • 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).
  • Unresolved: releases land in the persisted store only once the daemon consumes search commands (#68-adjacent); TMDB search is movie-only until series land (#39); per-season and per-episode library actions are #39; attention queues surface is #33.