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:
@@ -0,0 +1,42 @@
|
||||
// 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.
|
||||
export const PLAYER_WATCH_KEY = "watch"; // the item of the list playing now
|
||||
export const PLAYER_RELATED_KEY = "wrel"; // a related video played in place over it
|
||||
export 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<string, string | null> {
|
||||
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. */
|
||||
export 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));
|
||||
}
|
||||
Reference in New Issue
Block a user