add: infinitely scrolling timelines
This commit is contained in:
parent
822aaed0c8
commit
2b253c811c
12 changed files with 316 additions and 9 deletions
|
@ -1119,6 +1119,127 @@ ${option.input_element_type === "textarea" ? `${option.value}</textarea>` : ""}
|
|||
document.getElementById("lightbox").classList.add("hidden");
|
||||
}, 250);
|
||||
});
|
||||
|
||||
// intersection observer infinite scrolling
|
||||
self.IO_DATA_OBSERVER = new IntersectionObserver(
|
||||
async (entries) => {
|
||||
for (const entry of entries) {
|
||||
if (!entry.isIntersecting) {
|
||||
continue;
|
||||
}
|
||||
|
||||
await self.io_load_data();
|
||||
break;
|
||||
}
|
||||
},
|
||||
{
|
||||
root: document.body,
|
||||
rootMargin: "0px",
|
||||
threshold: 1,
|
||||
},
|
||||
);
|
||||
|
||||
self.define("io_data_load", (_, tmpl, page) => {
|
||||
self.IO_DATA_MARKER = document.querySelector(
|
||||
"[ui_ident=io_data_marker]",
|
||||
);
|
||||
|
||||
self.IO_DATA_ELEMENT = document.querySelector(
|
||||
"[ui_ident=io_data_load]",
|
||||
);
|
||||
|
||||
if (!self.IO_DATA_ELEMENT || !self.IO_DATA_MARKER) {
|
||||
console.warn(
|
||||
"ui::io_data_load called, but required elements don't exist",
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self.IO_DATA_TMPL = tmpl;
|
||||
self.IO_DATA_PAGE = page;
|
||||
self.IO_DATA_SEEN_IDS = [];
|
||||
|
||||
self.IO_DATA_OBSERVER.observe(self.IO_DATA_MARKER);
|
||||
});
|
||||
|
||||
self.define("io_load_data", async () => {
|
||||
self.IO_DATA_PAGE += 1;
|
||||
console.log("load page", self.IO_DATA_PAGE);
|
||||
|
||||
const text = await (
|
||||
await fetch(`${self.IO_DATA_TMPL}${self.IO_DATA_PAGE}`)
|
||||
).text();
|
||||
|
||||
if (
|
||||
text.includes(
|
||||
`That's a wrap!<!-- observer_disconnect_${window.BUILD_CODE} -->`,
|
||||
)
|
||||
) {
|
||||
console.log("io_data_end; disconnect");
|
||||
self.IO_DATA_OBSERVER.disconnect();
|
||||
self.IO_DATA_ELEMENT.innerHTML += text;
|
||||
return;
|
||||
}
|
||||
|
||||
self.IO_DATA_ELEMENT.innerHTML += text;
|
||||
|
||||
setTimeout(() => {
|
||||
// move marker to bottom of dom hierarchy
|
||||
self.IO_DATA_ELEMENT.children[
|
||||
self.IO_DATA_ELEMENT.children.length - 1
|
||||
].after(self.IO_DATA_MARKER);
|
||||
|
||||
// remove posts we've already seen
|
||||
function remove_elements(id, outer = false) {
|
||||
let idx = 0;
|
||||
for (const element of Array.from(
|
||||
document.querySelectorAll(
|
||||
`.post${outer ? "_outer" : ""}\\:${id}`,
|
||||
),
|
||||
)) {
|
||||
if (idx === 0) {
|
||||
idx += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// everything that isn't the first element should be removed
|
||||
element.remove();
|
||||
console.log("removed duplicate post");
|
||||
}
|
||||
}
|
||||
|
||||
for (const id of self.IO_DATA_SEEN_IDS) {
|
||||
remove_elements(id, false);
|
||||
remove_elements(id, true); // scoop up questions
|
||||
}
|
||||
|
||||
// push ids
|
||||
for (const opt of Array.from(
|
||||
document.querySelectorAll(
|
||||
`[ui_ident=list_posts_${self.IO_DATA_PAGE}] option`,
|
||||
),
|
||||
)) {
|
||||
const v = opt.getAttribute("value");
|
||||
|
||||
if (!self.IO_DATA_SEEN_IDS[v]) {
|
||||
self.IO_DATA_SEEN_IDS.push(v);
|
||||
}
|
||||
}
|
||||
}, 150);
|
||||
|
||||
// run hooks
|
||||
const atto = ns("atto");
|
||||
|
||||
atto.clean_date_codes();
|
||||
atto.clean_poll_date_codes();
|
||||
atto.link_filter();
|
||||
|
||||
atto["hooks::long_text.init"]();
|
||||
atto["hooks::alt"]();
|
||||
atto["hooks::online_indicator"]();
|
||||
atto["hooks::verify_emoji"]();
|
||||
});
|
||||
})();
|
||||
|
||||
(() => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue