A YouTube search is `?yt=<term>` (+ `ytn` for a non-default count), so a reload, a link or Back/Forward reopens it. It runs by itself only where it costs no quota: the free page scrape, a search asked for in this document, or results still cached. An API search reopened any other way shows its term and waits for "Search YouTube again". Home's time budget is `hb`; the question's draw stays on the history entry. An e2e spec opens every page's bookmark in a fresh browser context; CLAUDE.md and docs/development.md name the module URL codec as the place for view state.
33 lines
1.6 KiB
TypeScript
33 lines
1.6 KiB
TypeScript
// The feed's live YouTube search in the address bar (`?page=feed&yt=lofi&ytn=40`), so a search is a
|
|
// link and survives a reload. Only the term and how many results to gather: which source answers is
|
|
// the instance's setting at the moment the link opens (an admin may have switched it since), and that
|
|
// decides whether the search runs by itself (the free page scrape) or waits for a press (an API
|
|
// search spends 100 quota units, so nobody's reload or bookmark spends them unasked).
|
|
|
|
const YT_SEARCH_KEY = "yt";
|
|
const YT_COUNT_KEY = "ytn";
|
|
export const YT_SEARCH_KEYS = [YT_SEARCH_KEY, YT_COUNT_KEY] as const;
|
|
|
|
/** How many live-search results one fetch gathers; the first is the default, left out of the URL. */
|
|
export const YT_COUNTS = [20, 40, 60, 100] as const;
|
|
export const DEFAULT_YT_COUNT = YT_COUNTS[0];
|
|
|
|
/** The search a URL names, or null: a blank term names none (the search box never sends one). */
|
|
export function ytSearchFrom(params: URLSearchParams): string | null {
|
|
return params.get(YT_SEARCH_KEY)?.trim() || null;
|
|
}
|
|
|
|
/** The result count a URL names; anything but one of the offered counts is the default. */
|
|
export function ytCountFrom(params: URLSearchParams): number {
|
|
const n = Number(params.get(YT_COUNT_KEY));
|
|
return (YT_COUNTS as readonly number[]).includes(n) ? n : DEFAULT_YT_COUNT;
|
|
}
|
|
|
|
/** The URL updates for a search (null = none): a default count clears its key. */
|
|
export function ytSearchParams(term: string | null, count: number): Record<string, string | null> {
|
|
return {
|
|
[YT_SEARCH_KEY]: term,
|
|
[YT_COUNT_KEY]: term != null && count !== DEFAULT_YT_COUNT ? String(count) : null,
|
|
};
|
|
}
|