// Store the last read post for each thread and scroll to it automatically if (location.pathname.indexOf("/res/") >= 0) { let main = function () { let maxThreads = 300; let delay = 500; let storageKey = "lastRead"; let lastRead = JSON.parse(localStorage.getItem(storageKey)) || {}; let highlighted = null; let scrollTimer = null; let scrollContainer = document.getElementById("mainPanel"); function highlight(post) { if (highlighted) highlighted.style.borderBottom = ""; highlighted = post; highlighted.style.borderBottom = "dashed 1px #555"; } function onScroll() { let scrollBottom = scrollContainer.scrollTop + scrollContainer.offsetHeight; let posts = document.getElementsByClassName("postCell"); let lastReadPost = null; for (let post of posts) { if (post.offsetTop + post.offsetHeight > scrollBottom) break; lastReadPost = post; } if (lastReadPost) { delete lastRead[location.pathname]; lastRead[location.pathname] = Number(lastReadPost.id); let keys = Object.keys(lastRead); if (keys.length > maxThreads) delete lastRead[keys[0]]; localStorage.setItem(storageKey, JSON.stringify(lastRead)); } } if (lastRead[location.pathname]) { let lastReadPost = document.getElementById(lastRead[location.pathname]); if (lastReadPost) { highlight(lastReadPost); if (!location.hash) lastReadPost.scrollIntoView(); } } scrollContainer.addEventListener("scroll", () => { if (scrollTimer) clearTimeout(scrollTimer); scrollTimer = setTimeout(onScroll, delay); }); window.addEventListener("storage", (event) => { if (event.key === storageKey) lastRead = JSON.parse(event.newValue) || {}; }); let refreshButton = document.getElementById("refreshButton"); if (refreshButton) refreshButton.addEventListener("click", () => { let posts = document.getElementsByClassName("postCell"); if (posts.length) highlight(posts[posts.length - 1]); }); }; document.readyState === "loading" ? window.addEventListener("DOMContentLoaded", main) : main(); }