Pure behaviour-preserving code-motion — PlexBrowse 1751 -> 538 lines. The ~11 inlined components are self-contained (every view is invoked with shell callbacks as props; no view reaches back into shell state), so they just move to sibling files. New files: - lib/plexWatch.ts: toggleWatchState (shared by the grid + person page) - components/plexCards.tsx: PlexPosterCard, SeasonCard, CastStrip, RelatedStrip, EpisodeCard - components/plexViews.tsx: PlexInfoView, PlexPersonView, PlexShowView, PlexSeasonView - lib/plexDetailUi.tsx (extended): BackBtn, ActionBtn, WatchedToggle, DetailHero, epLabel (the file's own remit — "shared detail-page UI") PlexBrowse keeps the Sub router + PLEX_SUB_URL + PAGE + PlexBrowse() shell. Repointed the only external importer (PlexPersonView.dom.test) to plexCards/plexViews. Self-E2E (localdev): Plex grid renders (poster cards + episodes); The Expanse show-drill renders the hero + action buttons + season cards; ?v=show URL-mirroring intact; 0 console errors. Gate green: typecheck, knip, eslint (0 err), prettier, 247 vitest.
23 lines
895 B
TypeScript
23 lines
895 B
TypeScript
import type { TFunction } from "i18next";
|
|
import { api, type PlexCard } from "./api";
|
|
import { notifyActionError } from "./actionErrors";
|
|
|
|
// Persist a watch-state toggle from any Plex surface: flip via the caller's `optimistic` cache
|
|
// updater, call the API, surface a failure (the click used to look dead on 403/404/429), then
|
|
// `resync` (invalidate) — which corrects the optimistic flip to truth either way. Shared by the
|
|
// browse grid and the person page, each of which owns a different cache shape.
|
|
export async function toggleWatchState(
|
|
card: PlexCard,
|
|
t: TFunction,
|
|
handlers: { optimistic: (next: string) => void; resync: () => void },
|
|
) {
|
|
const next = card.status === "watched" ? "new" : "watched";
|
|
handlers.optimistic(next);
|
|
try {
|
|
await api.plexSetState(card.id, next);
|
|
} catch (e) {
|
|
notifyActionError(e, t("plex.watchedFailed"));
|
|
}
|
|
handlers.resync();
|
|
}
|