fix(plex): Restart only where an episode has a resume point; the Surprise draw is re-read, not redrawn
Show cards carry resumable (ShowState, from the same rollup) so a part-watched show whose next episode is untouched offers Play, not a Continue and a Restart that do the same thing; plexStarted is the one rule for cards and menus. The Surprise rail's key sits under the discover root: whatever refreshes the rails re-reads the draw (keep=) with its watch state now, kept past the 5-minute gc, and only the reshuffle deals. Closing the player refreshes the Discover rails. A show card's play acts on the last click only, and only where it was made.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { type ReactNode } from "react";
|
||||
import { useRef, type ReactNode } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { RotateCcw } from "lucide-react";
|
||||
@@ -120,25 +120,36 @@ export default function PlexDiscover({
|
||||
queryFn: () => api.plexDiscover(scope, lang, filters),
|
||||
});
|
||||
// Surprise-me is its own query so the ↻ button can redraw it without refetching the whole surface.
|
||||
// A redraw hands over the draw on screen, so a small filtered pool deals its other titles first.
|
||||
// A draw stands until the ↻ (or another scope, language or filter) asks for a new one: redrawn on
|
||||
// every refetch, the card just looked at was gone from its rail on Back from the player or a show
|
||||
// page. So a refetch reads the draw on screen again (`keep`: fresh watch state, same titles), and
|
||||
// only the ↻ deals — handing over that draw, so a small filtered pool deals its other titles first.
|
||||
const surpriseKey = qk.plexSurprise(scope, lang, filters);
|
||||
const redraw = useRef(false);
|
||||
const surpriseQ = useQuery({
|
||||
queryKey: surpriseKey,
|
||||
queryFn: () => {
|
||||
const shown = qc.getQueryData<{ items: PlexCard[] }>(surpriseKey)?.items ?? [];
|
||||
const shown = (qc.getQueryData<{ items: PlexCard[] }>(surpriseKey)?.items ?? []).map(
|
||||
(c) => c.id,
|
||||
);
|
||||
const deal = redraw.current || shown.length === 0;
|
||||
redraw.current = false;
|
||||
return api.plexSurprise(
|
||||
scope,
|
||||
undefined,
|
||||
filters,
|
||||
lang,
|
||||
shown.map((c) => c.id),
|
||||
deal ? { exclude: shown } : { keep: shown },
|
||||
);
|
||||
},
|
||||
// A draw stands until ↻ (or another scope, language or filter) asks for a new one. A stale one was
|
||||
// redrawn on every remount — Back from the player or a show page — and on a return to the window,
|
||||
// so the card just looked at was gone from the rail it came from.
|
||||
staleTime: Infinity,
|
||||
// Kept past the default five minutes unobserved: a film watched from the rail outlasts that, and
|
||||
// a collected draw is a new one.
|
||||
gcTime: Infinity,
|
||||
});
|
||||
const reshuffle = () => {
|
||||
redraw.current = true;
|
||||
void surpriseQ.refetch();
|
||||
};
|
||||
|
||||
// Watched toggle over BOTH this surface's cache (so a rail card flips instantly) and the surprise
|
||||
// list, then persist + resync via the shared helper — invalidating the grid too so it agrees.
|
||||
@@ -243,7 +254,7 @@ export default function PlexDiscover({
|
||||
cards={surprise}
|
||||
action={
|
||||
<IconButton
|
||||
onClick={() => surpriseQ.refetch()}
|
||||
onClick={reshuffle}
|
||||
loading={surpriseQ.isFetching}
|
||||
label={t("plex.discover.reshuffle")}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user