diff --git a/web/src/toast.ts b/web/src/toast.ts index 9329a9c..3d51f38 100644 --- a/web/src/toast.ts +++ b/web/src/toast.ts @@ -123,18 +123,29 @@ const parseFetchError = async (response: Response): Promise => { // Setup HTMX error listeners const setupHTMXListeners = (): void => { - // Listen for HTMX beforeSwap event - document.body.addEventListener('htmx:beforeSwap', (evt: Event) => { - const customEvent = evt as CustomEvent<{ xhr: XMLHttpRequest }>; - if (customEvent.detail.xhr && customEvent.detail.xhr.status >= 400) { + // Listen for HTMX afterSwap event to detect errors in swapped content + document.body.addEventListener('htmx:afterSwap', (evt: Event) => { + interface HTMXEventDetail { + xhr: XMLHttpRequest; + succeeded: boolean; + target: Element; + } + + const customEvent = evt as CustomEvent; + + // Check if request failed + if (customEvent.detail.succeeded === false && customEvent.detail.xhr) { const xhr = customEvent.detail.xhr; - const errorMessage = parseXHRError(xhr); - showToast(errorMessage, 'error'); - evt.preventDefault(); + + // Show toast for HTTP errors + if (xhr.status >= 400 && xhr.status < 600) { + const errorMessage = parseXHRError(xhr); + showToast(errorMessage, 'error'); + } } }); - // Listen for HTMX responseError event + // Also listen for response errors (network issues, invalid responses) document.body.addEventListener('htmx:responseError', (evt: Event) => { const customEvent = evt as CustomEvent<{ xhr: XMLHttpRequest }>; const xhr = customEvent.detail.xhr; @@ -179,20 +190,8 @@ if (typeof document !== 'undefined') { } // Export toast API for manual use -declare global { - interface Window { - showToast: { - error: (message: string, duration?: number) => void; - success: (message: string, duration?: number) => void; - info: (message: string, duration?: number) => void; - }; - } -} - -window.showToast = { +(window as any).showToast = { error: (message: string, duration?: number) => showToast(message, 'error', duration), success: (message: string, duration?: number) => showToast(message, 'success', duration), info: (message: string, duration?: number) => showToast(message, 'info', duration) }; - -export {};