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:
2026-10-09 22:01:28 +02:00
parent 5572499b56
commit 6df257d7df
26 changed files with 433 additions and 80 deletions
@@ -232,6 +232,20 @@ it("closing the player detaches the <video> it was playing", async () => {
expect(v.getAttribute("src")).toBeNull();
});
it("closing the player refreshes every surface that shows watch state, the Discover rails too", async () => {
const { unmount, qc } = mount({
details: { A: item("A") },
sessions: { A: () => Promise.resolve(direct("A")) },
});
await waitFor(() => expect(video()?.getAttribute("src")).toBe("/media/A"));
const refreshed = vi.spyOn(qc, "invalidateQueries");
unmount();
const keys = refreshed.mock.calls.map(([f]) => f?.queryKey);
expect(keys).toEqual(
expect.arrayContaining([qk.plexLibrary(), qk.plexShow(), qk.plexDiscover()]),
);
});
describe("the subtitle poll and notice", () => {
it("asks about where a resumed session was asked to start, before playback has ticked", async () => {
const { status } = mount({