Files
siftlode/frontend/src/lib/history.reloadedOverlay.dom.test.tsx
T
peter 3d26ca0efa feat(player): a bookmark reopens every player as it was, once
The Plex player names the playlist it plays through (v=player:<id>:playlist:<pid>), so a bookmark
rebuilds the queue from the playlist's own order while the item is still in it.

Found in the browser and fixed:
- after a reload the shell's player opened a second one over Home and the feed: it read the catalog
  row the page had fetched (a disabled query still reads the shared cache); it now waits for ready.
- every reload under an open overlay left a dead history step: the first overlay to open takes over
  the entry the document was loaded on.
- the feed's address was implicit, the same as the start-page landing, so a reloaded or bookmarked
  feed opened as Home: the feed now names itself (page=feed) like every page.
- a linked file or video that is gone was said, but stayed in the address and was said again on
  every reload: its keys are taken off.

The overlay address is written in one place (the entry is named once it is current), and the player
keys only the codec reads are no longer exported.
2026-10-27 07:33:55 +01:00

37 lines
1.6 KiB
TypeScript

// @vitest-environment jsdom
//
// A reload under an open overlay (a player the address names) loads the document on that overlay's
// entry, and the page opens the overlay again. It takes that entry over: pushed over it instead, Back
// would close the player onto the same page once more — one dead step for every reload. Its own file:
// the entry is read as the module loads, so it is set up before the import.
import { describe, expect, it } from "vitest";
import { act, renderHook } from "@testing-library/react";
const search = () => new URLSearchParams(window.location.search);
describe("an overlay reopened on the entry a reload started from", () => {
it("takes that entry over, and Back lands on the page under it", async () => {
window.history.replaceState({ sfPage: "feed" }, "", "/?q=music");
window.history.pushState({ sfPage: "feed", _ov: 3 }, "", "/?q=music&watch=v1");
const depth = window.history.length;
const { useBackToClose } = await import("./history");
const holder: { unmount?: () => void } = {};
const r = renderHook(() => useBackToClose(() => holder.unmount?.(), { watch: "v1" }));
holder.unmount = r.unmount;
await act(async () => {
await Promise.resolve();
});
expect(window.history.length).toBe(depth);
expect(search().get("watch")).toBe("v1");
await act(async () => {
const landed = new Promise((res) => window.addEventListener("popstate", res, { once: true }));
window.history.back();
await landed;
await Promise.resolve();
});
expect(window.location.search).toBe("?q=music");
});
});