feat(loader): SearchLoader mit wackelnder Pfanne und rotierenden Sprüchen
All checks were successful
Build & Publish Docker Image / build-and-push (push) Successful in 54s

Neue Komponente src/lib/components/SearchLoader.svelte ersetzt die
stumpfen "Suche läuft …"-Zeilen an allen vier Stellen:
- Startseite (scope=local und scope=web)
- Header-Dropdown (size=sm, beide Scopes)

Was passiert:
- Ein Pfannen-Emoji (🍳🥘🍲🍜🥣) wechselt alle 900 ms
- Wobble-Animation kippt es im 1.4-s-Takt hin und her
- Drei Dampf-Punkte steigen zeitversetzt auf und fadeen
- Caption unten rotiert alle 1.8 s durch vier passende Sprüche
  (lokal: "Stöbere im Rezeptbuch …", web: "Schnuppere in fremden
  Küchen …" etc.)

Zwei Size-Varianten: md (Homepage) und sm (Header-Dropdown).
This commit is contained in:
hsiegeln
2026-04-17 18:40:38 +02:00
parent 347b1de555
commit cf31e79fb0
3 changed files with 186 additions and 4 deletions

View File

@@ -5,6 +5,7 @@
import { profileStore } from '$lib/client/profile.svelte';
import ProfileSwitcher from '$lib/components/ProfileSwitcher.svelte';
import ConfirmDialog from '$lib/components/ConfirmDialog.svelte';
import SearchLoader from '$lib/components/SearchLoader.svelte';
import type { SearchHit } from '$lib/server/recipes/search-local';
import type { WebHit } from '$lib/server/search/searxng';
@@ -135,7 +136,7 @@
{#if navOpen}
<div class="dropdown" role="listbox">
{#if navSearching && navHits.length === 0}
<p class="dd-status">Suche läuft …</p>
<SearchLoader scope="local" size="sm" />
{:else if navHits.length > 0}
<ul class="dd-list">
{#each navHits as r (r.id)}
@@ -172,7 +173,7 @@
{:else}
<p class="dd-section">Keine lokalen Rezepte aus dem Internet:</p>
{#if navWebSearching}
<p class="dd-status">Suche im Internet läuft …</p>
<SearchLoader scope="web" size="sm" />
{:else if navWebError}
<p class="dd-status dd-error">Internet-Suche zurzeit nicht möglich.</p>
{:else if navWebHits.length > 0}

View File

@@ -3,6 +3,7 @@
import type { SearchHit } from '$lib/server/recipes/search-local';
import type { WebHit } from '$lib/server/search/searxng';
import { randomQuote } from '$lib/quotes';
import SearchLoader from '$lib/components/SearchLoader.svelte';
let query = $state('');
let quote = $state('');
@@ -102,7 +103,7 @@
{#if activeSearch}
<section class="results">
{#if searching && hits.length === 0}
<p class="muted">Suche läuft …</p>
<SearchLoader scope="local" />
{:else if hits.length > 0}
<ul class="cards">
{#each hits as r (r.id)}
@@ -129,7 +130,7 @@
{:else if searchedFor === query.trim()}
<p class="muted no-local-msg">Keine lokalen Rezepte für „{searchedFor}" — Ergebnisse aus dem Internet:</p>
{#if webSearching}
<p class="muted">Suche im Internet läuft …</p>
<SearchLoader scope="web" />
{:else if webError}
<p class="error">Internet-Suche zurzeit nicht möglich: {webError}</p>
{:else if webHits.length > 0}