/** * @copyright 2026 NHCarrigan * @license Naomi's Public License * @author Naomi Carrigan */ import { Injectable, signal } from '@angular/core'; export interface Toast { id: number; message: string; type: 'error' | 'success' | 'info' | 'warning'; duration: number; } @Injectable({ providedIn: 'root' }) export class ToastService { private toasts = signal([]); public readonly toastList = this.toasts.asReadonly(); private nextId = 0; /** * Show an error toast notification. */ error(message: string, duration = 5000): void { this.addToast(message, 'error', duration); } /** * Show a success toast notification. */ success(message: string, duration = 3000): void { this.addToast(message, 'success', duration); } /** * Show an info toast notification. */ info(message: string, duration = 3000): void { this.addToast(message, 'info', duration); } /** * Show a warning toast notification. */ warning(message: string, duration = 4000): void { this.addToast(message, 'warning', duration); } /** * Remove a toast by ID. */ remove(id: number): void { this.toasts.update(toasts => toasts.filter(t => t.id !== id)); } private addToast(message: string, type: Toast['type'], duration: number): void { const id = this.nextId++; const toast: Toast = { id, message, type, duration }; this.toasts.update(toasts => [...toasts, toast]); // Auto-remove after duration setTimeout(() => { this.remove(id); }, duration); } }