diff --git a/assets/loading.js b/assets/loading.js index 62e5650..40ee364 100644 --- a/assets/loading.js +++ b/assets/loading.js @@ -6,6 +6,7 @@ const DEBOUNCE_MS = 200 let debounceTimeout = null let historyRestoreGracePeriod = false let savedScrollPosition = null +let activeRequests = 0 function getIndicator() { return document.getElementById(INDICATOR_ID) @@ -35,6 +36,8 @@ function handleBeforeRequest(event) { return } + activeRequests++ + // Save scroll position of the target container before HTMX request const target = event.detail?.target || document.getElementById('main-content') if (target && typeof target.scrollTop === 'number') { @@ -52,6 +55,19 @@ function handleBeforeRequest(event) { }, DEBOUNCE_MS) } +function handleRequestEnd() { + // Counter may already be 0 if a force-reset (history save, page show) fired + // before this afterRequest — ignore the stale completion in that case + if (0 === activeRequests) { + return + } + + activeRequests-- + if (0 === activeRequests) { + hide() + } +} + function handleAfterSwap() { // Restore scroll position after HTMX swaps content if (savedScrollPosition !== null && savedScrollPosition.element) { @@ -61,6 +77,7 @@ function handleAfterSwap() { } function handleHistoryRestore() { + activeRequests = 0 hide() // Set grace period to ignore change events triggered by history restore @@ -71,24 +88,29 @@ function handleHistoryRestore() { } function handleTimeout() { - hide() + // Don't decrement here — htmx:afterRequest always fires alongside htmx:timeout + // and handles the counter. This handler only shows the alert. alert('Die Anfrage hat zu lange gedauert. Bitte versuchen Sie es erneut. Falls das Problem weiterhin besteht, kontaktieren Sie bitte unseren Support.') } function handleBeforeHistorySave() { // Hide indicator before HTMX saves the page to history cache + activeRequests = 0 + hide() +} + +function handlePageShow() { + activeRequests = 0 hide() } // Initialize event listeners document.body.addEventListener('htmx:beforeRequest', handleBeforeRequest) -document.body.addEventListener('htmx:afterRequest', hide) +document.body.addEventListener('htmx:afterRequest', handleRequestEnd) document.body.addEventListener('htmx:afterSwap', handleAfterSwap) document.body.addEventListener('htmx:timeout', handleTimeout) document.body.addEventListener('htmx:historyRestore', handleHistoryRestore) -document.body.addEventListener('htmx:sendError', hide) -document.body.addEventListener('htmx:responseError', hide) document.body.addEventListener('htmx:beforeHistorySave', handleBeforeHistorySave) -window.addEventListener('pageshow', hide) -window.addEventListener('popstate', handleHistoryRestore) \ No newline at end of file +window.addEventListener('pageshow', handlePageShow) +window.addEventListener('popstate', handleHistoryRestore)