fix(nav): the address follows the view through overlays, reloads and Back (review round 1)
- A URL mirror names the view again on every entry Back or Forward lands on, so a change made under a dialog, a drawer or a sub-view is not undone by the next reload. - A view pushed from the entry a reload under a dialog started from no longer inherits its overlay mark; a reload under two overlays closes onto the page in one step. - The linked player reopens over a live search, gives itself up when its list moves first, and plays alone over an emptied playlist; a capped Files list keeps the link it cannot resolve. - The Feed press over a channel ends the search; leaving a search ends its asked mark; Files and Playlists searches end with their page; the feed always names its view and debounces its search. - Search-box keys are declared per module and kept out of the client log below TRACE. - Writers outside lib/ go through codecs; the URL contract scans computed keys, overlay writers and two-line reads, and holds every page to a bookmark round trip (Config, Activity, Playlists and the Files sort and viewer added).
This commit is contained in:
@@ -80,13 +80,19 @@ export function filtersToParams(f: FeedFilters): URLSearchParams {
|
||||
}
|
||||
|
||||
/** Build the address-bar delta for the feed filters: each recognized filter key mapped to its emitted
|
||||
* value, or null to delete it (so switching a filter back to its default clears the key). Pass `null`
|
||||
* to clear ALL filter keys — used when leaving the feed, where the localStorage copy still holds them.
|
||||
* Feed the result into urlWithParams(). */
|
||||
* value, or null to delete it (so switching a filter back to its default clears the key) — except the
|
||||
* view and the order, always written (defaults too): a feed address then always names its view, so a
|
||||
* bookmark of the default feed opens the default feed, not whatever view the account stored since
|
||||
* (an address naming none falls back to it). Pass `null` to clear ALL filter keys — used when leaving
|
||||
* the feed, where the localStorage copy still holds them. Feed the result into urlWithParams(). */
|
||||
export function filterParamUpdates(f: FeedFilters | null): Record<string, string | null> {
|
||||
const p = f ? filtersToParams(f) : new URLSearchParams();
|
||||
const out: Record<string, string | null> = {};
|
||||
for (const k of KEYS) out[k] = p.get(k);
|
||||
if (f) {
|
||||
out.show = f.show || "unwatched";
|
||||
out.sort = f.sort || "newest";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -233,13 +239,6 @@ export function urlWithParams(updates: Record<string, string | null>): string {
|
||||
return hrefHere(params);
|
||||
}
|
||||
|
||||
/** Take `keys` off the current entry's address: what a link named and the page could not show (a file
|
||||
* or a video that is gone, said once) must not stay to be said again on every reload, or shared. */
|
||||
export function dropFromAddress(keys: readonly string[]): void {
|
||||
const updates = Object.fromEntries(keys.map((k) => [k, null]));
|
||||
window.history.replaceState(window.history.state, "", urlWithParams(updates));
|
||||
}
|
||||
|
||||
/** The channel page's address, opened over the page on screen: the shell's own keys (the page, an
|
||||
* entry link not yet read) and the channel — none of the page's keys, none of another channel's view
|
||||
* (the channel page writes its own, lib/channelPageUrlState), and no player (opening a channel closes
|
||||
@@ -269,10 +268,11 @@ export function hrefHere(query: URLSearchParams, hash: string = window.location.
|
||||
return url.pathname.startsWith("//") ? url.href : `${url.pathname}${url.search}${url.hash}`;
|
||||
}
|
||||
|
||||
/** Remove specific TRANSIENT params (one-time auth/admin links: ?link, ?oauth, ?admin, ?access, ?verify,
|
||||
* ?reset) from the address bar once they've been read, WITHOUT touching the nav/filter params that now
|
||||
* live there. Preserves history.state. Replaces the old whole-query stripUrlParams, which is unsafe now
|
||||
* that the query is the source of truth for navigation. No-op when none of the keys are present. */
|
||||
/** Take `keys` off the current entry's address, WITHOUT touching the nav/filter params that live
|
||||
* there: TRANSIENT params once read (one-time auth/admin links: ?link, ?oauth, ?admin, ?access, ?verify,
|
||||
* ?reset), and what a link named that the page could not show (a file or a video that is gone, said
|
||||
* once) — left, it would be said again on every reload, or shared. Preserves history.state. No-op when
|
||||
* none of the keys are present. */
|
||||
export function clearParams(...keys: string[]): void {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
let changed = false;
|
||||
|
||||
Reference in New Issue
Block a user