feat(player): the YouTube player and the file viewer are named in the address

The player names what it plays in its own history entry (watch, wrel, wtab): a reload or a
bookmark reopens it on the page that hosts it, with that page's list as the queue, or alone
from the catalog (GET /api/videos/{id}/row); a page that hosts none gets the shell's. Back
lands on the page's address without it (useBackToClose's url; ui/Modal passes it on). The
Files viewer and player do the same (fview, fplay). The Plex and channel-manager views are
always written in full, as their fallback is remembered state.
This commit is contained in:
2026-10-27 05:29:49 +01:00
parent d4f24de4ba
commit fa893c73a3
45 changed files with 1005 additions and 89 deletions
@@ -20,6 +20,7 @@ import {
} from "../../lib/history";
import { foreignUrlKeys, moduleUrlKeys, pageTitleKey, reachablePage } from "./moduleRegistry";
import { CHANNEL_PAGE_KEYS } from "../../lib/channelPageUrlState";
import { PLAYER_KEYS } from "../../lib/playerUrlState";
import {
channelViewFrom,
loadInitialPage,
@@ -43,12 +44,14 @@ import {
//
// The contexts, their value types and the hooks live in navigationContext.ts.
/** The address bar of `page`'s root: the page (feed implicit) with every module's own keys cleared — a
* page switch resets to that module's root, and its store mirrors what it holds back in. */
/** The address bar of `page`'s root: the page (feed implicit), no channel or player over it, and every
* module's own keys cleared — a page switch resets to that module's root, and its store mirrors what
* it holds back in. */
function pageRootParams(page: Page): Record<string, string | null> {
return {
page: page === "feed" ? null : page,
...closedChannelParams(),
...nulls(PLAYER_KEYS),
...nulls(moduleUrlKeys()),
};
}