feat(search): context-scoped search with filter chips and group order
Add a search scope (all/music/shows/movies) resolved from the entry route and adjustable via filter chips, threaded through the library store's search() into includeItemTypes. Results group by type in a user-configurable order, editable from settings. TRACES: UR-049 | DR-063, DR-064, DR-065; UR-050 | DR-066, DR-067
This commit is contained in:
@@ -1,20 +1,36 @@
|
||||
<script lang="ts">
|
||||
import { library } from "$lib/stores/library";
|
||||
import { goto } from "$app/navigation";
|
||||
import { page } from "$app/stores";
|
||||
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 type { MediaItem } from "$lib/api/types";
|
||||
|
||||
let searchQuery = $state("");
|
||||
|
||||
// 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));
|
||||
|
||||
async function handleSearch(query: string) {
|
||||
if (query.trim()) {
|
||||
await library.search(query);
|
||||
await library.search(query, scope);
|
||||
} else {
|
||||
library.clearSearch();
|
||||
}
|
||||
}
|
||||
|
||||
// Changing the chip re-runs the current query; changing the query keeps scope.
|
||||
async function handleScopeChange(next: SearchScope) {
|
||||
scope = next;
|
||||
if (searchQuery.trim()) {
|
||||
await library.search(searchQuery, next);
|
||||
}
|
||||
}
|
||||
|
||||
function handleItemClick(item: MediaItem) {
|
||||
switch (item.type) {
|
||||
case "Audio":
|
||||
@@ -47,12 +63,13 @@
|
||||
<h1 class="text-2xl font-bold mb-6">Search</h1>
|
||||
|
||||
<!-- Search Input -->
|
||||
<div class="mb-6">
|
||||
<div class="mb-6 space-y-3">
|
||||
<Search
|
||||
bind:value={searchQuery}
|
||||
placeholder="Search your library..."
|
||||
onSearch={handleSearch}
|
||||
/>
|
||||
<SearchScopeChips {scope} onChange={handleScopeChange} />
|
||||
</div>
|
||||
|
||||
<!-- Search Results -->
|
||||
@@ -60,6 +77,7 @@
|
||||
<SearchResults
|
||||
results={$library.searchResults}
|
||||
loading={$library.loadingCount > 0}
|
||||
{scope}
|
||||
onItemClick={handleItemClick}
|
||||
/>
|
||||
{:else}
|
||||
|
||||
Reference in New Issue
Block a user