/* Better readability on wide screens */
.divMessage {
max-width: 80em;
}
/* Compact top bar */
nav span,
nav a {
margin: 0 -0.1em;
font-size: 11px;
display: inline-block;
}
/* Differentiate pdf/epub thumbnails */
.uploadCell > a[href$=".pdf"]:before {
content: "PDF";
display: block;
}
.uploadCell > a[href$="epub+zip"]:before {
content: "EPUB";
display: block;
}
/* Hide ugly green borders in default theme */
#divLatestPosts .latestPostCell,
.innerPost,
.sideCatalogCell,
.markedPost,
.sideCatalogMarkedCell,
.catalogCell {
border: none;
}
hr,
input,
select,
textarea,
#newPostFieldset,
#quick-reply table,
.modalDecorationPanel,
.floatingMenu,
#settingsFieldset,
.reportFieldset,
input[type="button"],
input[type="submit"],
button,
.dropzone,
.selectedCell,
#postingForm th,
.modalTableBody th {
border-color: #444;
}
/* Hide checkbox on posts */
.deletionCheckBox {
display: none;
}
last-read-auto-scroll.js
Raw
// 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();
}