feat(home): SvelteKit snapshot für echte State-Preservation beim Back
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 1m16s
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 1m16s
Vorher (Commit 1055a67): Query in URL gespiegelt, Back triggerte einen
frischen Request — zwar schnell, aber Scroll-Position + Ergebnisreihen-
folge nicht garantiert konstant.
Jetzt: SvelteKit's snapshot-API speichert query + hits + webHits +
searchedFor + webError in der History-Entry. Beim Zurück-Navigieren aus
/preview oder /recipes/[id] stellt restore() den exakten UI-Zustand
wieder her — ohne Fetch. Scroll-Position wird von SvelteKit ohnehin auto-
restored.
Der Debounce-Effekt hat jetzt einen skipNextSearch-Flag, der beim
Restore true gesetzt wird, damit das Setzen von query keinen neuen
Search-Request auslöst. Erstmaliges Tippen nach dem Restore arbeitet
wieder ganz normal mit Debounce.
Die URL-Synchronisation (?q=…) bleibt bestehen — für Bookmarks und
Share-Links. Snapshot überlagert den URL-Load in der Ordnung:
restore → onMount sieht query bereits korrekt gesetzt → kein Double-Work.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { page } from '$app/stores';
|
||||
import { CookingPot, Globe, X } from 'lucide-svelte';
|
||||
import type { Snapshot } from './$types';
|
||||
import type { SearchHit } from '$lib/server/recipes/search-local';
|
||||
import type { WebHit } from '$lib/server/search/searxng';
|
||||
import { randomQuote } from '$lib/quotes';
|
||||
@@ -18,6 +19,27 @@
|
||||
let webSearching = $state(false);
|
||||
let webError = $state<string | null>(null);
|
||||
let searchedFor = $state<string | null>(null);
|
||||
let skipNextSearch = false;
|
||||
|
||||
type SearchSnapshot = {
|
||||
query: string;
|
||||
hits: SearchHit[];
|
||||
webHits: WebHit[];
|
||||
searchedFor: string | null;
|
||||
webError: string | null;
|
||||
};
|
||||
|
||||
export const snapshot: Snapshot<SearchSnapshot> = {
|
||||
capture: () => ({ query, hits, webHits, searchedFor, webError }),
|
||||
restore: (v) => {
|
||||
query = v.query;
|
||||
hits = v.hits;
|
||||
webHits = v.webHits;
|
||||
searchedFor = v.searchedFor;
|
||||
webError = v.webError;
|
||||
skipNextSearch = true;
|
||||
}
|
||||
};
|
||||
|
||||
async function loadRecent() {
|
||||
const res = await fetch('/api/recipes/search');
|
||||
@@ -100,6 +122,12 @@
|
||||
$effect(() => {
|
||||
const q = query.trim();
|
||||
if (debounceTimer) clearTimeout(debounceTimer);
|
||||
if (skipNextSearch) {
|
||||
// Snapshot-Restore hat hits/webHits/searchedFor wiederhergestellt —
|
||||
// nicht erneut fetchen.
|
||||
skipNextSearch = false;
|
||||
return;
|
||||
}
|
||||
if (q.length <= 3) {
|
||||
hits = [];
|
||||
webHits = [];
|
||||
|
||||
Reference in New Issue
Block a user