feat(plex): sort direction, genre any/all, multi-person filters; fix back-nav + player stop

UAT follow-ups on the Plex filter epic:
- Sort now has an asc/desc toggle (sort_dir), applied to any sort field.
- Genre multi-select gains an Any/All mode (genre_mode: OR vs AND containment).
- Director/actor/studio become multi-value: people AND (titles featuring all selected),
  studios OR; clicking them on the info page stacks (unions) instead of replacing, and
  the sidebar shows each as a removable 'Active' chip.
- fix(history): clicking a metadata filter on the info page now pushes a fresh grid
  entry instead of history.back(), so browser Back returns to the info page rather than
  leaving the Plex module.
- fix(player): fully tear down the <video> + hls on unmount and guard late play() calls,
  so backing out of a just-started video no longer leaves audio playing in the background.
i18n en/hu/de (match any/all, sort direction).
This commit is contained in:
npeter83 2026-07-06 00:15:31 +02:00
parent eefd7e3abd
commit 1982cfa7b9
10 changed files with 160 additions and 60 deletions

View file

@ -127,9 +127,21 @@ export default function PlexBrowse({ q, library, show, sort, filters, setFilters
onBack={sub.back}
onPlay={() => sub.open({ kind: "player", id: infoId })}
onFilter={(patch) => {
// Clicking a metadata chip sets that filter and returns to the (now filtered) grid.
setFilters({ ...filters, ...patch });
sub.back();
// Clicking a metadata chip sets that filter and shows the filtered grid. Array filters
// (genres/people/studios) UNION with what's already set (so you can stack people); scalars
// replace. We push a fresh grid entry (not history.back) so browser Back returns to this
// info page instead of leaving the Plex module.
const merged = { ...filters } as unknown as Record<string, unknown>;
for (const [k, v] of Object.entries(patch)) {
const cur = merged[k];
if (Array.isArray(v) && Array.isArray(cur)) {
merged[k] = Array.from(new Set([...(cur as unknown[]), ...(v as unknown[])]));
} else {
merged[k] = v;
}
}
setFilters(merged as unknown as PlexFilters);
sub.open({ kind: "grid" });
}}
/>
);