Meguca Last Read

Meguca/Shamiko imageboard mark last read

当前为 2022-04-29 提交的版本,查看 最新版本

// ==UserScript==
// @name         Meguca Last Read
// @namespace    meguca.shamiko.ext
// @version      1.0
// @description  Meguca/Shamiko imageboard mark last read
// @author       SaddestPanda
// @license      GNU GPLv3
// @match        https://2chen.moe/*
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function () {
    'use strict';

    addMyStyle("meguca-extended-css", `
    .lastRead {
        border-top: 8px solid #1cb9d2;
    }
    `);

    let db;
    let retries = 0;
    dbStart();

    function dbStart() {
        let indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
        let DBOpenRequest = indexedDB.open('meguca');
        DBOpenRequest.onsuccess = (event) => {
            db = event.target.result;
            dbContinue();
        }
        DBOpenRequest.onerror = (event) => {
            //Retry. Not sure if this is needed.
            if (retries < 5) {
                retries++;
                setTimeout(() => {
                    dbStart();
                }, 150);
            }
        }
    }

    async function dbContinue() {
        let transaction = db.transaction("seenPost", "readonly");
        let objectStore = transaction.objectStore("seenPost");
        let getAll = objectStore.getAll();
        getAll.onsuccess = (event) => {
            //Close db early
            db.close();

            let allData = event.target.result;
            let threadID = document.querySelector("#thread-container").dataset.id;
            let filteredData = allData.filter(obj => obj.op == threadID);
            let lastObj = filteredData[filteredData.length - 1];
            let lastReadElem = document.querySelector(`article[id="p${lastObj.id}"]`);
            //Mark as read (add styling)
            lastReadElem.classList.add("lastRead");
            //Scroll one screen height above last read (don't show last read)
            let lastReadPos = findPos(lastReadElem);
            window.scroll(0, lastReadPos.top - window.innerHeight + 150); //+N is to show last read post and part of the next post 
        };
        getAll.onerror = event => {
            console.log("🚀 ~ start ~ onerror", event);
            db.close();
        };
    }

    function addMyStyle(newID, newStyle) {
        let myStyle = document.createElement('style');
        //myStyle.type = 'text/css';
        myStyle.id = newID;
        myStyle.textContent = newStyle;
        document.querySelector("head").appendChild(myStyle);
    }

    function findPos(obj) {
        const rect = obj.getBoundingClientRect();
        return {
            left: rect.left + window.scrollX,
            top: rect.top + window.scrollY
        }
    }
})();