/* Lists that continue themselves (#5211, pref 172). * * A [data-scroll-more] sentinel (the scroll_more macro) fetches the next page * when it comes within MARGIN of the viewport, so the rows arrive before the * reader reaches the end, and is replaced by them. While a page is in flight * the sentinel says "Loading more…"; a failed page says so with a Retry button * and is not re-fetched by scrolling (a dead endpoint must not become a request * loop). The last page ends with scroll_end's "End of the list." instead of a sentinel. */ (function () { var MARGIN = "600px 0px"; function load(el) { el.setAttribute("data-scroll-state", "loading"); htmx.trigger(el, "scroll-more"); } var observer = "IntersectionObserver" in window ? new IntersectionObserver(function (entries) { entries.forEach(function (entry) { var el = entry.target; if (!entry.isIntersecting || el.hasAttribute("data-scroll-state")) return; observer.unobserve(el); load(el); }); }, { rootMargin: MARGIN }) : null; function watch(root) { if (!root || !root.querySelectorAll) return; var found = Array.prototype.slice.call(root.querySelectorAll("[data-scroll-more]")); if (root.matches && root.matches("[data-scroll-more]")) found.push(root); found.forEach(function (el) { if (el.hasAttribute("data-scroll-state")) return; if (observer) observer.observe(el); else load(el); }); } function failed(evt) { var el = evt.detail && evt.detail.elt; if (!el || !el.hasAttribute || !el.hasAttribute("data-scroll-more")) return; el.setAttribute("data-scroll-state", "failed"); var status = el.querySelector("[data-scroll-status]"); if (!status) return; status.textContent = "Couldn't load more. "; var retry = document.createElement("button"); retry.type = "button"; retry.className = "btn btn-sm btn-ghost"; retry.textContent = "Retry"; retry.addEventListener("click", function () { status.textContent = "Loading more…"; load(el); }); status.appendChild(retry); } document.addEventListener("htmx:load", function (evt) { watch(evt.detail.elt); }); document.addEventListener("htmx:responseError", failed); document.addEventListener("htmx:sendError", failed); document.addEventListener("htmx:timeout", failed); })();