/** * Terminal-style toast notification system with queuing */ // Toast queue management let toastQueue = []; let currentToast = null; function showToast(message, type = 'info', duration = 3000) { // Queue if a toast is already showing if (currentToast) { toastQueue.push({ message, type, duration }); return; } displayToast(message, type, duration); } function displayToast(message, type, duration) { // Create toast element const toast = document.createElement('div'); toast.className = `terminal-toast toast-${type}`; currentToast = toast; // Icon based on type const icons = { success: '✓', error: '✗', info: 'ℹ', warning: '⚠' }; toast.innerHTML = ` [${icons[type] || 'ℹ'}] ${message} [×] `; // Add to document document.body.appendChild(toast); // Trigger animation setTimeout(() => toast.classList.add('show'), 10); // Manual dismiss handler const closeBtn = toast.querySelector('.toast-close'); closeBtn.addEventListener('click', () => dismissToast(toast)); // Auto-remove after duration const timeoutId = setTimeout(() => { dismissToast(toast); }, duration); // Store timeout ID for manual dismiss toast.timeoutId = timeoutId; } function dismissToast(toast) { // Clear auto-dismiss timeout if (toast.timeoutId) { clearTimeout(toast.timeoutId); } toast.classList.remove('show'); setTimeout(() => { toast.remove(); currentToast = null; // Show next toast in queue if (toastQueue.length > 0) { const next = toastQueue.shift(); displayToast(next.message, next.type, next.duration); } }, 300); } // Convenience functions window.toast = { success: (msg, duration) => showToast(msg, 'success', duration), error: (msg, duration) => showToast(msg, 'error', duration), info: (msg, duration) => showToast(msg, 'info', duration), warning: (msg, duration) => showToast(msg, 'warning', duration) };