fix(plex): a collection sibling is a full Plex card, and the player's info overlay plays it

- PlexInfo's collection strip gives each card the related strip's action set: the "…" menu (with
  Restart for a touch reader), the watched toggle and the playlist add.
- `onPlayItem` is required, so no variant draws a Play that does nothing; the player's info overlay
  plays the sibling in the running player (`go(id, _, fromZero)` for its Restart).
This commit is contained in:
2026-09-27 14:44:38 +02:00
parent efa4aeeeda
commit 70f98b352f
4 changed files with 180 additions and 20 deletions
@@ -312,6 +312,47 @@ describe("a double-tap on a side third skips 10 s (C5)", () => {
});
});
// E28 review D1: the info overlay drew its collection siblings with a Play that did nothing — the
// overlay had no way to play one. It plays it in this player, at its resume point or from the start.
describe("a collection sibling in the info overlay", () => {
const withSibling = (id: string): PlexItemDetail => ({
...item(id),
cast: [],
genres: [],
directors: [],
collections: [
{
id: "c1",
title: "Saga",
source: "plex",
items: [
{
id: "B",
type: "movie",
title: "Title B",
thumb: "",
status: "in_progress",
position_seconds: 300,
duration_seconds: 3000,
},
],
},
],
});
it("plays its Restart in this player, from the start", { timeout: 10000 }, async () => {
const { session } = mount({ details: { A: withSibling("A"), B: item("B", 300) } });
await playingAt("/media/A", 100);
fireEvent.click(screen.getByLabelText("plex.player.more"));
fireEvent.click(await menuItem("plex.player.infoBtn"));
// The overlay is a lazy chunk: its first import takes a while under the test runner.
const restart = await screen.findByRole("button", { name: "card.restart" }, { timeout: 5000 });
fireEvent.click(restart);
await waitFor(() => expect(lastStart(session)).toEqual(["B", 0]));
expect(screen.queryByRole("heading", { name: "Saga" })).toBeNull(); // the overlay closed
});
});
describe("the C5 row", () => {
it("has no Stop, Restart or ±10 s buttons, and keeps the rare tools behind the ⋯", async () => {
mount({ details: { A: item("A") } });