Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/improsocial/impro
An extensible Bluesky client for web impro.social
Something went wrong. Try again.
3.0 kB · 110 lines
JavaScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111import { Component, getChildrenFragment } from "/js/components/component.js";
class InfiniteScrollContainer extends Component { static get observedAttributes() { return ["disabled"]; }
connectedCallback() { if (this._initialized) { return; } this.label = this.getAttribute("label"); this.expanded = false; this._children = getChildrenFragment(this); this.lookahead = this.getAttribute("lookahead") ?? "2000px"; this.inverted = this.hasAttribute("inverted"); this.innerHTML = ""; this.render(); this._initialized = true; }
attributeChangedCallback(name, oldValue, newValue) { if (name === "disabled" && this.observer && this.sentinel) { if (this.hasAttribute("disabled")) { this.observer.unobserve(this.sentinel); } else { this.observer.observe(this.sentinel); } } }
disconnectedCallback() { if (this.observer) { this.observer.disconnect(); } }
render() { const container = document.createElement("div"); container.classList.add("infinite-scroll-container"); container.style.cssText = ` position: relative; `; this.appendChild(container); container.appendChild(this._children);
const sentinel = document.createElement("div"); sentinel.classList.add("infinite-scroll-sentinel"); const sentinelPosition = this.inverted ? "top: 0;" : "bottom: 0;"; sentinel.style.cssText = ` position: absolute; ${sentinelPosition} width: 1px; height: ${this.lookahead}; max-height: 100%; background-color: transparent; pointer-events: none; `;
if (this.inverted) { container.insertBefore(sentinel, container.firstChild); } else { container.appendChild(sentinel); }
this.sentinel = sentinel; this.observer = this.initializeObserver(sentinel); }
initializeObserver(sentinel) { const options = { threshold: 0, };
const observer = new IntersectionObserver((entries) => { const entry = entries[0]; if (!entry) return;
if (entry.isIntersecting && !this.hasAttribute("disabled")) { // Pause observing during load this.observer.unobserve(sentinel);
this.dispatchEvent( new CustomEvent("load-more", { detail: { resume: () => { // Re-observe after the DOM/layout settles if (!this.hasAttribute("disabled")) { requestAnimationFrame(() => { // Force a reflow guard (GPT says this could help with iOS Safari) sentinel.offsetTop; this.observer.observe(sentinel); }); } }, }, }), ); } }, options);
if (!this.hasAttribute("disabled")) { requestAnimationFrame(() => observer.observe(sentinel)); }
return observer; }}
InfiniteScrollContainer.register();