commit ed0ed50b99780b6f2784065b1da385b3230c7c51
parent d49637c636027ffb64cfdf4d24ede9361e2c85d2
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Tue, 29 Sep 2026 21:39:33 -0400
common: a filter-only link no longer releases a stored query — two page-life flags, one job each: ranThisPageLife keeps release 8's hold rule (a commit, a profile load, an active URL query), askedThisPageLife drives the clear screen (a run, or a link that carries a query or a filter); the held-query comment says the clear screen (review M1, L1)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat:
1 file changed, 33 insertions(+), 21 deletions(-)
diff --git a/common/components/SearchSessionContext.tsx b/common/components/SearchSessionContext.tsx
@@ -198,16 +198,23 @@ export type GroundingMode = "search" | "selection";
// export-filter parser.
const SELECTION_KEY = "ytdlp-tb:selection";
-// Whether the visitor has asked in this page life: a commit (Search, Enter, a
-// Filters Apply), a profile load, or a link that carries a query or a filter
-// (`urlAsks`). Module state, so it survives client-side navigation and resets
-// on a reload or a new visit. It decides two things. A stored query is held
-// (see `runHeld`) only on the page life's FIRST load — the hub mounts a fresh
-// provider per route, and `/` → `/ask` must keep grounding in the search the
-// visitor just ran there. And the results area shows nothing until it is set
-// (`searchedThisPageLife`, its reactive copy): until the visitor asks, the page
-// is the bar, the intro and the footer.
+// Two facts about this page life, each with one job. Module state, so both
+// survive client-side navigation and reset on a reload or a new visit.
+//
+// `ranThisPageLife`: a search has run — a commit (Search, Enter, a Filters
+// Apply), a profile load, or an active query arriving on the URL. A stored
+// query is held (see `runHeld`) while it is unset: on the page life's first
+// load, and on any later mount while nothing has run. Once it is set a later
+// mount runs the stored query — the hub mounts a fresh provider per route, and
+// `/` → `/ask` must keep grounding in the search the visitor just ran there. A
+// filter-only link does not set it: it shows its results, but it ran no query.
+//
+// `askedThisPageLife`: the visitor has asked — a search ran, or a link carries
+// a query or a filter (`urlAsks`). The results area shows nothing until it is
+// set (`searchedThisPageLife`, its reactive copy): until the visitor asks, the
+// page is the bar, the intro and the footer.
let ranThisPageLife = false;
+let askedThisPageLife = false;
function loadSelection(): string[] {
if (typeof window === "undefined") return [];
@@ -262,9 +269,9 @@ function urlHasAnyFilterParam(): boolean {
}
// A link that carries a query (`qt`, legacy `q` / `m`) or a filter (`tg`, the
-// share-link keys, the legacy filter keys) is the visitor asking: it runs on
-// load and shows its results, as a Search would. A video (`v`, `t`) or a
-// chart's shape (`view`, `cs`) alone is not a search.
+// share-link keys, the legacy filter keys) is the visitor asking: it shows its
+// results on load, as a Search would (`askedThisPageLife`). A video (`v`, `t`)
+// or a chart's shape (`view`, `cs`) alone is not a search.
const ASKING_URL_KEYS: readonly string[] = [
"qt",
"q",
@@ -477,13 +484,13 @@ function useSearchSessionState() {
const [view, setView] = useState<"results" | "chart">("results");
const [chartShape, setChartShape] = useState<ChartShape | null>(null);
- // The reactive copy of `ranThisPageLife`, which stays the source of truth
+ // The reactive copy of `askedThisPageLife`, which stays the source of truth
// across remounts: a mount later in the page life starts from it, and every
// place that sets it sets this too. False until the visitor asks, and the
// results area renders nothing until then. False on the server, where the
// module variable is never set, so the first client render matches.
const [searchedThisPageLife, setSearchedThisPageLife] = useState(
- () => ranThisPageLife,
+ () => askedThisPageLife,
);
// Defer rendering of the QueryBuilder to the client. The builder's leaf
@@ -825,8 +832,9 @@ function useSearchSessionState() {
[committedTags, postScopeSlugs],
);
- // False while a restored query is held (see `runHeld`): the results area
- // shows the browse listing under the restored filters, and nothing fetches.
+ // False while a restored query is held (see `runHeld`): nothing fetches, and
+ // the results area is empty until the visitor asks — or, when a filter-only
+ // link asked, it lists every video under the link's filters.
const hasActiveQuery = useMemo(
() => !runHeld && isNodeActive(committedRoot),
[committedRoot, runHeld],
@@ -1290,10 +1298,12 @@ function useSearchSessionState() {
setCommittedRoot(resolvedRoot);
if (holdRestored) setRunHeld(true);
}
- // After `holdRestored` is decided, so a query restored beside a
- // filter-only link is still held on this first load.
- if (urlAsks(params)) ranThisPageLife = true;
- setSearchedThisPageLife(ranThisPageLife);
+ // After `holdRestored` is decided. Only an active URL query counts as a
+ // run; a filter-only link asks (its results show) without releasing a
+ // stored query on this mount or a later one.
+ if (rootFromUrl && isNodeActive(rootFromUrl)) ranThisPageLife = true;
+ if (ranThisPageLife || urlAsks(params)) askedThisPageLife = true;
+ setSearchedThisPageLife(askedThisPageLife);
setDraftExcludedChannels(initialExcluded);
setDraftNov(initialNov);
@@ -1408,6 +1418,7 @@ function useSearchSessionState() {
const commitSearch = () => {
setRunHeld(false);
ranThisPageLife = true;
+ askedThisPageLife = true;
setSearchedThisPageLife(true);
setCommittedRoot(draftRoot);
const nextSnapshot = buildDraftSnapshot();
@@ -1473,6 +1484,7 @@ function useSearchSessionState() {
// Loading a profile commits it, which runs it — as it always has.
setRunHeld(false);
ranThisPageLife = true;
+ askedThisPageLife = true;
setSearchedThisPageLife(true);
applyDraftSnapshot(snapshot);
const excluded = snapshotToExcluded(
@@ -2060,7 +2072,7 @@ function useSearchSessionState() {
setHitLimit,
// ── Results ──
// False until the visitor asks in this page life; nothing in the results
- // area renders until then (see `ranThisPageLife`).
+ // area renders until then (see `askedThisPageLife`).
searchedThisPageLife,
hasActiveQuery,
resultGroups,