refactor(rail): extract shared FilterRail shell + name the MediaSource seam (E4 S7)
The three filter rails — feed Sidebar, PlexSidebar, PlaylistsRail — each rendered the same SidePanel chrome (title bar, customize `editing` state, edit-toggle, reset-to-layout-default, edit hint) around a PanelGroups body, differing only in identity + filter content. Extracted that shell into components/FilterRail.tsx: each rail now supplies only what differs (title/icon, active-filter count + Clear-all action, its `items`, and optional content above/below the groups — `top` for the feed's scope toggle, `children` for its tag manager). FilterRail owns the `editing` state, so all three drop their duplicated useState + SidePanel wiring. MediaSource facade (lib/mediaSource.ts): a thin `MediaSourceKind = "feed" | "plex"` naming the two browsable, filterable sources (a PanelId minus "playlists", which is a rail but not a source). Already unified in practice — one SortControl, the source-agnostic ActiveFilter[] chips, PanelId layouts, now the shared shell — so this is formalization, not new capability: a single named seam for a future third source or a cross-source feature. The two media-source rails annotate their `kind` with it; PlaylistsRail passes the plain PanelId. Per the recon, the playlist-dialog merge was deliberately NOT forced (it proved forced + low value). UX-3 control-vocab sweep deliberately deferred — the rails already use the canonical primitives. Behaviour-preserving. Gate green (tsc, knip, lint 0-err, 247 vitest). Self-E2E (localdev): all three rails render via FilterRail — feed (scope toggle + panel groups + Customize→editing with reset + 56 reorder affordances, exits clean), Plex (filter groups + customize), Playlists (sections + customize); 0 JS console errors.
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
import type { PanelId } from "./panelLayout";
|
||||
|
||||
// The two browsable media sources the app filters over: the YouTube feed and the Plex library.
|
||||
// (A `PanelId` minus "playlists" — a rail, but not a filterable source.) The pair is already unified
|
||||
// in practice — one shared SortControl, the source-agnostic `ActiveFilter[]` chip row, PanelId-keyed
|
||||
// sidebar layouts, and the shared `FilterRail` shell. This names that abstraction as one narrow
|
||||
// contract, so a future third source (or a feature built across sources) targets `MediaSourceKind`
|
||||
// instead of re-deriving it from the YT/Plex twins. Deliberately thin — just the kind; widen it only
|
||||
// when a concrete cross-source feature needs more than the name.
|
||||
export type MediaSourceKind = Extract<PanelId, "feed" | "plex">;
|
||||
Reference in New Issue
Block a user