feat(plex): add a "Recently watched" rail to Discover (D)
A new Discover rail listing what the user last FULLY watched, newest first: a movie as its own card, a show as the specific EPISODE watched (carrying its show title via leaf_card). Sits above Recently added. Movies honour the sidebar filters like the other rails; episodes carry no filterable metadata so they don't. Clicking a card plays it (the existing onCard path already routes episodes to the player). Bilingual heading added. Verified live: the rail renders watched movies + episodes with Watched badges. Gate: tsc/lint/knip/prettier clean, 423 vitest; backend ruff clean, 13 discover tests (+ a recently-watched movie+episode assertion).
This commit is contained in:
@@ -77,6 +77,7 @@ const card = (id: string, title: string, type: "movie" | "show" = "movie") => ({
|
||||
const fullPayload = {
|
||||
scope: "both",
|
||||
continue_watching: [card("cw1", "Resume Me")],
|
||||
recently_watched: [card("rw1", "Watched Me")],
|
||||
recently_added: [card("ra1", "Just Added")],
|
||||
genres: [{ value: "Drama", count: 12, art: [] }],
|
||||
because_you_watched: { anchor: { id: "a1", title: "Anchor" }, items: [card("bw1", "Rec One")] },
|
||||
@@ -103,6 +104,7 @@ describe("PlexDiscover", () => {
|
||||
/>,
|
||||
);
|
||||
await screen.findByText("plex.discover.continueWatching");
|
||||
expect(screen.getByText("plex.discover.recentlyWatched")).toBeTruthy();
|
||||
expect(screen.getByText("plex.discover.recentlyAdded")).toBeTruthy();
|
||||
expect(screen.getByText("plex.discover.surprise")).toBeTruthy();
|
||||
expect(screen.getByText("plex.discover.byGenre")).toBeTruthy();
|
||||
@@ -110,6 +112,7 @@ describe("PlexDiscover", () => {
|
||||
expect(screen.getByText("plex.discover.becauseWatched:Anchor")).toBeTruthy();
|
||||
// A card from each rail is present (title rendered in the poster label).
|
||||
expect(screen.getAllByText("Resume Me").length).toBeGreaterThan(0);
|
||||
expect(screen.getAllByText("Watched Me").length).toBeGreaterThan(0);
|
||||
expect(screen.getAllByText("Just Added").length).toBeGreaterThan(0);
|
||||
expect(screen.getAllByText("Random Pick").length).toBeGreaterThan(0);
|
||||
expect(screen.getAllByText("Rec One").length).toBeGreaterThan(0);
|
||||
@@ -215,6 +218,7 @@ describe("PlexDiscover", () => {
|
||||
plexDiscover.mockResolvedValue({
|
||||
scope: "both",
|
||||
continue_watching: [],
|
||||
recently_watched: [],
|
||||
recently_added: [],
|
||||
genres: [],
|
||||
because_you_watched: null,
|
||||
|
||||
@@ -143,6 +143,7 @@ export default function PlexDiscover({
|
||||
const bw = d.because_you_watched;
|
||||
const nothing =
|
||||
d.continue_watching.length === 0 &&
|
||||
d.recently_watched.length === 0 &&
|
||||
d.recently_added.length === 0 &&
|
||||
d.genres.length === 0 &&
|
||||
surprise.length === 0 &&
|
||||
@@ -165,6 +166,15 @@ export default function PlexDiscover({
|
||||
/>
|
||||
)}
|
||||
|
||||
{d.recently_watched.length > 0 && (
|
||||
<CardRail
|
||||
title={t("plex.discover.recentlyWatched")}
|
||||
ariaLabel={t("plex.discover.recentlyWatched")}
|
||||
cards={d.recently_watched}
|
||||
{...railProps}
|
||||
/>
|
||||
)}
|
||||
|
||||
{d.recently_added.length > 0 && (
|
||||
<CardRail
|
||||
title={t("plex.discover.recentlyAdded")}
|
||||
|
||||
@@ -292,6 +292,7 @@
|
||||
"discover": {
|
||||
"tab": "Discover",
|
||||
"continueWatching": "Continue watching",
|
||||
"recentlyWatched": "Recently watched",
|
||||
"recentlyAdded": "Recently added",
|
||||
"surprise": "Surprise me",
|
||||
"reshuffle": "Reshuffle",
|
||||
|
||||
@@ -292,6 +292,7 @@
|
||||
"discover": {
|
||||
"tab": "Felfedezés",
|
||||
"continueWatching": "Folytatás",
|
||||
"recentlyWatched": "Nemrég megnézve",
|
||||
"recentlyAdded": "Nemrég hozzáadva",
|
||||
"surprise": "Lepj meg",
|
||||
"reshuffle": "Újrakeverés",
|
||||
|
||||
@@ -343,6 +343,7 @@ export interface PlexPlaySession {
|
||||
export interface PlexDiscover {
|
||||
scope: string;
|
||||
continue_watching: PlexCard[];
|
||||
recently_watched: PlexCard[]; // last fully-watched movies + episodes, newest first
|
||||
recently_added: PlexCard[];
|
||||
// top genres → tap a tile to filter the grid; `art` = up to 4 poster rating_keys for the collage
|
||||
genres: { value: string; count: number; art: string[] }[];
|
||||
|
||||
Reference in New Issue
Block a user