// Global toast queue (design: State Management). Toasts outlive route // changes because AppShell mounts the renderer, so "Zapisz i zamknij" can // show its toast on the list it returns to. import { readonly, ref } from 'vue' export type ToastTone = 'success' | 'danger' export interface ToastItem { id: number text: string tone: ToastTone } /** Auto-dismiss delay in milliseconds (design: about 4 s). */ export const TOAST_TIMEOUT = 4000 const items = ref([]) const timers = new Map>() let nextId = 1 export const toasts = readonly(items) export function showToast(text: string, tone: ToastTone = 'success'): number { const id = nextId++ items.value = [...items.value, { id, text, tone }] timers.set( id, setTimeout(() => dismissToast(id), TOAST_TIMEOUT), ) return id } export function dismissToast(id: number): void { const timer = timers.get(id) if (timer !== undefined) { clearTimeout(timer) timers.delete(id) } items.value = items.value.filter((item) => item.id !== id) } export function clearToasts(): void { for (const timer of timers.values()) { clearTimeout(timer) } timers.clear() items.value = [] } export function useToasts() { return { toasts, showToast, dismissToast, clearToasts } }