fix(search): route the library header search to /search
Typing in the desktop header search bar ran library.search() in place and relied on /library rendering the results inline. On every other /library/** route nothing rendered them, so the search bar looked broken: results were fetched and never shown. Make /search the single surface that renders results. The header bar becomes a navigator — it hands the query and route-derived scope to /search via ?q= and ?scope=, which seed the page and run the search on arrival. The inline result block and the header's scope chips are removed; the chips live on /search, which owns the results. The empty `all` scope is omitted from the URL, and typing while already on /search does not push a history entry per keystroke.
This commit is contained in:
@@ -5,15 +5,41 @@
|
||||
import Search from "$lib/components/Search.svelte";
|
||||
import SearchResults from "$lib/components/search/SearchResults.svelte";
|
||||
import SearchScopeChips from "$lib/components/search/SearchScopeChips.svelte";
|
||||
import { resolveSearchScope, type SearchScope } from "$lib/utils/searchScope";
|
||||
import { resolveSearchScope, SEARCH_SCOPES, type SearchScope } from "$lib/utils/searchScope";
|
||||
import type { MediaItem } from "$lib/api/types";
|
||||
|
||||
let searchQuery = $state("");
|
||||
// `?q=` / `?scope=` seed the page so the desktop header search bar can hand
|
||||
// a query over by navigating here — /search is the only surface that renders
|
||||
// results, so every other search affordance routes into it.
|
||||
// TRACES: UR-049 | DR-063
|
||||
const initialQuery = $page.url.searchParams.get("q") ?? "";
|
||||
const initialScope = $page.url.searchParams.get("scope");
|
||||
|
||||
let searchQuery = $state(initialQuery);
|
||||
|
||||
// Route resolves the *initial* scope only. Deriving it reactively would snap
|
||||
// a user who widened to All back to the route's scope on any navigation.
|
||||
// TRACES: UR-049 | DR-064
|
||||
let scope = $state<SearchScope>(resolveSearchScope($page.url.pathname));
|
||||
let scope = $state<SearchScope>(
|
||||
SEARCH_SCOPES.includes(initialScope as SearchScope)
|
||||
? (initialScope as SearchScope)
|
||||
: resolveSearchScope($page.url.pathname)
|
||||
);
|
||||
|
||||
// A query arriving in the URL must actually run — mounting with a seeded
|
||||
// input alone would render the empty state with a filled box.
|
||||
$effect(() => {
|
||||
const q = $page.url.searchParams.get("q") ?? "";
|
||||
if (!q.trim()) return;
|
||||
const urlScope = $page.url.searchParams.get("scope");
|
||||
const nextScope = SEARCH_SCOPES.includes(urlScope as SearchScope)
|
||||
? (urlScope as SearchScope)
|
||||
: "all";
|
||||
if (q === $library.searchQuery && nextScope === scope) return;
|
||||
searchQuery = q;
|
||||
scope = nextScope;
|
||||
library.search(q, nextScope);
|
||||
});
|
||||
|
||||
async function handleSearch(query: string) {
|
||||
if (query.trim()) {
|
||||
|
||||
Reference in New Issue
Block a user