fix(plex): series-page UX fixes from UAT (7 items)

1. Series detail pages now match the movie info page: the customize menu lives in the
   hero panel (top-right), the Cast/Seasons/Related strips sit in glassy panels, and the
   menu is dynamic — Related shows can be toggled (new plexInfoRelated pref).
2. The Plex search box now survives F5 (persisted per-account like the filters).
3. Show + season hero posters get a hover Play/Resume overlay.
4. Card top-right watched toggle can now UN-watch: the watched/in-progress badges were
   intercepting the click (no pointer-events-none), so the toggle underneath never fired.
5. Episode card: the watched check no longer jumps on hover (badge now shares the
   toggle's box); every card's title/meta gets its own glassy translucent background and
   the Add-to-playlist button is always visible (not hover-only).
6. Season-card 'In progress' label is readable again (solid dark badge over the poster).
7. On a season page the show title is clickable → back to the show (history-correct).
This commit is contained in:
npeter83 2026-07-11 01:34:30 +02:00
parent 46d5572e47
commit 186fdbb0e5
7 changed files with 144 additions and 71 deletions

View file

@ -15,9 +15,11 @@ export function useDetailPrefs() {
const prefs = (qc.getQueryData<{ preferences?: Record<string, unknown> }>(["me"])?.preferences ?? {}) as {
plexInfoArtBg?: boolean;
plexInfoCast?: boolean;
plexInfoRelated?: boolean;
};
const [artBg, setArtBg] = useState(prefs.plexInfoArtBg !== false);
const [showCast, setShowCast] = useState(prefs.plexInfoCast !== false);
const [showRelated, setShowRelated] = useState(prefs.plexInfoRelated !== false);
const save = (patch: Record<string, unknown>) => {
api.savePrefs(patch).catch(() => {});
qc.setQueryData<{ preferences?: Record<string, unknown> } | undefined>(["me"], (m) =>
@ -27,6 +29,7 @@ export function useDetailPrefs() {
return {
artBg,
showCast,
showRelated,
toggleArtBg: () => {
const next = !artBg;
setArtBg(next);
@ -37,6 +40,11 @@ export function useDetailPrefs() {
setShowCast(next);
save({ plexInfoCast: next });
},
toggleRelated: () => {
const next = !showRelated;
setShowRelated(next);
save({ plexInfoRelated: next });
},
};
}
@ -75,12 +83,18 @@ export function DetailCustomizeMenu({
showCast,
onToggleCast,
hasCast,
showRelated,
onToggleRelated,
hasRelated,
}: {
artBg: boolean;
onToggleArtBg: () => void;
showCast: boolean;
onToggleCast: () => void;
hasCast: boolean;
showRelated?: boolean;
onToggleRelated?: () => void;
hasRelated?: boolean;
}) {
const { t } = useTranslation();
const [open, setOpen] = useState(false);
@ -105,6 +119,9 @@ export function DetailCustomizeMenu({
>
<PrefToggle label={t("plex.info.prefArtBg")} on={artBg} onClick={onToggleArtBg} />
{hasCast && <PrefToggle label={t("plex.info.prefCast")} on={showCast} onClick={onToggleCast} />}
{hasRelated && onToggleRelated && (
<PrefToggle label={t("plex.info.prefRelated")} on={showRelated ?? true} onClick={onToggleRelated} />
)}
</div>
)}
</div>

View file

@ -27,6 +27,7 @@ export const LS = {
plexShow: "siftlode.plexShow",
plexSort: "siftlode.plexSort",
plexFilters: "siftlode.plexFilters",
plexQ: "siftlode.plexQ",
plexPlaylistLayout: "siftlode.plexPlaylistLayout",
notifHistory: "siftlode.notifications",
notifSettings: "siftlode.notifSettings",