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:
@@ -503,6 +503,10 @@ export default function Feed({
|
||||
const saved = savedOverrides[v.id];
|
||||
return saved && !(live && saved.answered) ? { ...v, saved: saved.value } : v;
|
||||
});
|
||||
// The live search's cards, in the order picked for them, and the player's queue over them.
|
||||
const ytShown = (rows: Video[]): Video[] =>
|
||||
sortYtResults(withOverrides(rows, true), ytSort.key as SortKey, ytSort.dir, lang);
|
||||
const ytQueue = (rows: Video[]): Video[] => ytShown(rows).filter((v) => v.status !== "hidden");
|
||||
const merged: Video[] = withOverrides(loaded);
|
||||
const items: Video[] = merged.filter((v) => matchesView(v.status, filters.show));
|
||||
// The in-app player's queue (auto-advance / loop / prev-next). It's the filtered feed, but the
|
||||
@@ -511,16 +515,18 @@ export default function Feed({
|
||||
// goes hidden still drops out ("visible affects").
|
||||
const playerQueue: Video[] = merged.filter((v) => v.status !== "hidden");
|
||||
// A reload or a bookmark of the player reopens it once this list is in, the list as its queue again
|
||||
// (the feed's filters are in the address under it). Not over a live search: that is not in the
|
||||
// address, and a reload leaves it.
|
||||
// (the feed's filters are in the address under it) — over a live search too, its results the
|
||||
// queue, once they are in (or the search waits for its press, and it plays alone). Scoped to the
|
||||
// list it was linked over: leaving the search first gives it up.
|
||||
useOpenLinkedPlayer(
|
||||
!ytActive && !query.isLoading,
|
||||
(id) => playerQueue.find((v) => v.id === id),
|
||||
ytActive ? ytQuery.data !== undefined || ytQuery.isError || !ytRuns : !query.isLoading,
|
||||
(id) => (ytActive ? ytQueue(ytLoaded) : playerQueue).find((v) => v.id === id),
|
||||
(video, inList) => {
|
||||
openVideo(video);
|
||||
// Not in what this list has loaded (further down it, or no longer in it): it plays alone.
|
||||
if (!inList) setActiveVideo((a) => a && { ...a, alone: true });
|
||||
},
|
||||
ytActive ? `yt:${ytSearch}` : "feed",
|
||||
);
|
||||
|
||||
// A live search ingests new catalog videos, so the disabled feed queries still hold their stale
|
||||
@@ -534,12 +540,7 @@ export default function Feed({
|
||||
// A separate data source rendered in the same cards/player. No watch-state view filter (the
|
||||
// user explicitly searched, so show everything) and no auto-pagination (each page costs quota).
|
||||
if (ytActive) {
|
||||
const ytItems: Video[] = sortYtResults(
|
||||
withOverrides(ytLoaded, true),
|
||||
ytSort.key as SortKey,
|
||||
ytSort.dir,
|
||||
lang,
|
||||
);
|
||||
const ytItems: Video[] = ytShown(ytLoaded);
|
||||
const ytPlayerQueue: Video[] = ytItems.filter((v) => v.status !== "hidden");
|
||||
const ytError =
|
||||
ytQuery.error instanceof HttpError
|
||||
@@ -704,7 +705,7 @@ export default function Feed({
|
||||
<PlayerModal
|
||||
video={activeVideo.video}
|
||||
startAt={activeVideo.startAt}
|
||||
queue={ytPlayerQueue}
|
||||
queue={activeVideo.alone ? undefined : ytPlayerQueue}
|
||||
onClose={closePlayer}
|
||||
onState={onState}
|
||||
onWrite={trackSessionWrite}
|
||||
|
||||
Reference in New Issue
Block a user