// The YouTube player's address-bar keys. The player opens over any page (the feed, a channel page, Home, // a playlist, a channel's watched videos), so its keys are the shell's: no module owns them, a page // switch clears them, and the page under it keeps its own. The player names them in its own history // entry (lib/history's `useBackToClose`), so Back lands on the page as it was, without the player. // The list it plays from is the page's: the feed's filters, the open playlist (`pl`) — already named. // No position: the player resumes from the server's (`video_states`), which is where it was left. const PLAYER_WATCH_KEY = "watch"; // the item of the list playing now const PLAYER_RELATED_KEY = "wrel"; // a related video played in place over it const PLAYER_PANEL_KEY = "wtab"; // the wide panel's tab, when it is not the description export const PLAYER_KEYS = [PLAYER_WATCH_KEY, PLAYER_RELATED_KEY, PLAYER_PANEL_KEY] as const; export type PlayerPanelTab = "description" | "related"; export type PlayerUrlState = { watch: string; related: string | null; panel: PlayerPanelTab }; /** The player's keys for its entry. The panel's tab is written only when it is not the default: no * browser remembers it, so a link without one opens the description as this one would. */ export function playerParamUpdates(state: PlayerUrlState): Record { return { [PLAYER_WATCH_KEY]: state.watch, [PLAYER_RELATED_KEY]: state.related, [PLAYER_PANEL_KEY]: state.panel === "related" ? "related" : null, }; } /** The player an address names, or null when it names none. */ function playerFrom(params: URLSearchParams): PlayerUrlState | null { const watch = params.get(PLAYER_WATCH_KEY); if (!watch) return null; return { watch, related: params.get(PLAYER_RELATED_KEY) || null, panel: params.get(PLAYER_PANEL_KEY) === "related" ? "related" : "description", }; } /** The player the address names now: read by a host as it mounts (a reload, a bookmark), and by the * player as it opens. No entry but the player's own carries these keys once the history has caught * up, so a host mounted later (a page switch back) finds none. */ export function linkedPlayer(): PlayerUrlState | null { return playerFrom(new URLSearchParams(window.location.search)); }