import { writable } from 'svelte/store'; import { ApiError } from './api'; export type ToastTone = 'info' | 'success' | 'warning' | 'error'; export interface Toast { id: number; message: string; tone: ToastTone; ttl: number; } let nextId = 0; const timers = new Map>(); export const toasts = writable([]); export function toast(message: string, tone: ToastTone = 'info', ttl = 4000): number { const id = ++nextId; const entry: Toast = { id, message, tone, ttl }; toasts.update((list) => [...list, entry]); if (ttl > 0 && typeof window !== 'undefined') { timers.set(id, setTimeout(() => dismissToast(id), ttl)); } return id; } export function dismissToast(id: number): void { const t = timers.get(id); if (t) { clearTimeout(t); timers.delete(id); } toasts.update((list) => list.filter((x) => x.id !== id)); } // User-action error surface. Pulls the German message off ApiError; for // anything else, falls back to a generic line so the user sees *something*. export function toastError(err: unknown, fallback = 'Etwas ist schiefgelaufen.'): number { if (err instanceof ApiError) return toast(err.message || fallback, 'error', 5000); if (err instanceof Error && err.message) return toast(err.message, 'error', 5000); return toast(fallback, 'error', 5000); }