diff --git a/frontend/src/components/plexCards.dom.test.tsx b/frontend/src/components/plexCards.dom.test.tsx index 4f751674..90c2c98a 100644 --- a/frontend/src/components/plexCards.dom.test.tsx +++ b/frontend/src/components/plexCards.dom.test.tsx @@ -208,6 +208,19 @@ describe("a started Plex card", () => { expect(container.querySelector(".flex-col.reveal-hover")).toBeNull(); }); + // E28 review D4: the card read "started" off the rounded progress %, the menu off the position — + // 20 s into a 3 h film is 0 % here and started there, so the card offered no Restart the menu had. + it("a resume point under 1 % still offers the Restart, as the card's menu does", () => { + render( + , + ); + expect(screen.getByRole("button", { name: "card.restart" })).toBeTruthy(); + }); + it("a not-started or watched card keeps the one Play", () => { render(); expect(screen.queryByRole("button", { name: "card.restart" })).toBeNull(); diff --git a/frontend/src/components/plexCards.tsx b/frontend/src/components/plexCards.tsx index 6df9b1e7..2e86f879 100644 --- a/frontend/src/components/plexCards.tsx +++ b/frontend/src/components/plexCards.tsx @@ -7,7 +7,7 @@ import { Carousel } from "./ui/Carousel"; import type { PlexCard, PlexCastMember, PlexFilters, PlexSeasonDetail } from "../lib/api"; import { navItemAttrs } from "../lib/listNav"; import { endsTextSelection, movedPastSlop } from "../lib/textSelection"; -import { plexAddLabelKey } from "./usePlexCardActions"; +import { plexAddLabelKey, plexStarted } from "./usePlexCardActions"; import { IconButton } from "./ui/IconButton"; import { MoreButton } from "./ui/MoreButton"; import { Pressable } from "./ui/Pressable"; @@ -186,6 +186,7 @@ function PlexPicture({ plays, small = false, pct = 0, + started = false, bar, children, }: { @@ -201,23 +202,26 @@ function PlexPicture({ /** A shelf's short landscape picture: the smaller Play, clear of the hover row under it. */ small?: boolean; pct?: number; + /** Has a resume point (`plexStarted`, the card menu's own rule): Continue + Restart, not Play. */ + started?: boolean; bar: ReactNode; /** The badges printed on the picture. */ children?: ReactNode; }) { - // The pct is the resume point's: a watched or untouched item has none, and plays from its start. - const started = plays && pct > 0 && !!onRestart; + // Not read off `pct`: that is rounded, so 20 s into a 3 h film was 0 % and "not started" here while + // the menu offered "from the start" (E28 review D4). One rule, `plexStarted`, for both. + const resumable = plays && started && !!onRestart; return (
{children}
- {plays && !started && } + {plays && !resumable && }
- {started && ( + {resumable && (