LinuxDo快速收藏

Adds a quick bookmarking feature to posts on the website

目前為 2024-06-27 提交的版本,檢視 最新版本

// ==UserScript==
// @name         LinuxDo快速收藏
// @name:zh-CN   LinuxDo快速收藏
// @namespace    http://tampermonkey.net/
// @version      0.2
// @description  Adds a quick bookmarking feature to posts on the website
// @description:zh-CN   在帖子中添加了快速收藏功能。用户可以通过星形图标快速收藏或取消收藏帖子。
// @author       Yearly
// @match        https://linux.do/*
// @icon         data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjZWVlIiBkPSJNMCAwaDEwMHYxMDBIMHoiLz48cGF0aCBkPSJNNCA0aDkydjMwSDR6Ii8+PHBhdGggZmlsbD0iI0ZBMCIgZD0iTTQgNjZoOTJ2MzBINHoiLz48L3N2Zz4=
// @license      AGPL-v3.0
// @grant        none
// ==/UserScript==

(function() {
    const starSvg = `<svg class="svg-icon" aria-hidden="true" style="text-indent: 1px; transform: scale(1);">
     <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
     <path d="M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z"></path></svg></svg> `;
    let markMap = new Map();

    function handleResponse(xhr, successCallback, errorCallback) {
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    successCallback(xhr);
                } else {
                    errorCallback(xhr);
                }
            }
        };
    }

    function deleteStarMark(mark_btn, data_id) {
        if (markMap.has(data_id)) {
            const mark_id = markMap.get(data_id);
            var xhr = new XMLHttpRequest();
            xhr.open('DELETE', `/bookmarks/${mark_id}`, true);
            xhr.setRequestHeader('Content-Type', 'application/json');
            xhr.setRequestHeader('x-requested-with', 'XMLHttpRequest');
            xhr.setRequestHeader("x-csrf-token", document.head.querySelector("meta[name=csrf-token]")?.content);

            handleResponse(xhr, (xhr) => {
                console.log('删除成功:', xhr.responseText);
                mark_btn.style.color = '#777';
                mark_btn.title = "收藏";
                mark_btn.onclick = () => addStarMark(mark_btn, data_id);
            }, (xhr) => {
                console.error('DELETE请求失败:', xhr.statusText);
            });

            xhr.send();
        }
    }

    function addStarMark(mark_btn, data_id) {
        const xhr = new XMLHttpRequest();
        xhr.open('POST', '/bookmarks', true);
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
        xhr.setRequestHeader('x-requested-with', 'XMLHttpRequest');
        xhr.setRequestHeader('discourse-logged-in', ' true');
        xhr.setRequestHeader('discourse-present', ' true');
        xhr.setRequestHeader("x-csrf-token", document.head.querySelector("meta[name=csrf-token]")?.content);
        const postData = `name=%E6%94%B6%E8%97%8F&auto_delete_preference=3&bookmarkable_id=${data_id}&bookmarkable_type=Post`;

        handleResponse(xhr, (xhr) => {
            console.log('收藏成功!');
            mark_btn.style.color = '#fdd459';
            mark_btn.title = "删除收藏";
            mark_btn.onclick = () => deleteStarMark(mark_btn, data_id);
        }, (xhr) => {
            alert('收藏失败!' + xhr.statusText + "\n" + JSON.stringify(JSON.parse(xhr.responseText), null, "  "));
        });

        xhr.send(postData);
    }

    function getStarMark() {
        let articles = document.querySelectorAll("article[data-post-id]");
        if (articles.length <= 0) {
            return;
        }

        const currentUserElement = document.querySelector('#current-user button');
        const currentUsername = currentUserElement ? currentUserElement.getAttribute('href').replace('/u/', '') : null;

        const xhr = new XMLHttpRequest();
        xhr.open('GET', `/u/${currentUsername}/user-menu-bookmarks`, true);
        xhr.setRequestHeader("x-csrf-token", document.head.querySelector("meta[name=csrf-token]")?.content);

        handleResponse(xhr, (xhr) => {
            var response = JSON.parse(xhr.responseText);
            response.bookmarks.forEach(mark => {
                markMap.set(mark.bookmarkable_id.toString(), mark.id.toString());
            });
            console.log("getmark");
            articles.forEach(article => {
                const target = article.querySelector("div.topic-body.clearfix > div.regular.contents > section > nav > div.actions");
                if (target && !article.querySelector("div.topic-body.clearfix > div.regular.contents > section > nav > span.star-bookmark")) {
                    const dataPostId = article.getAttribute('data-post-id');
                    const starButton = document.createElement('span');

                    starButton.innerHTML = starSvg;
                    starButton.className = "star-bookmark";
                    starButton.style.cursor = 'pointer';
                    starButton.style.margin = '0px 12px';

                    if (markMap.has(dataPostId)) {
                        starButton.style.color = '#fdd459';
                        starButton.title = "删除收藏";
                        starButton.onclick = () => deleteStarMark(starButton, dataPostId);
                    } else {
                        starButton.style.color = '#777';
                        starButton.title = "收藏";
                        starButton.onclick = () => addStarMark(starButton, dataPostId);
                    }
                    target.after(starButton);
                }
            });
        }, (xhr) => {
            console.error('GET请求失败:', xhr.statusText);
        });

        xhr.send();
    }

    let lastChangeTime = 0;
    function mutationCallback() {
        const currentTime = Date.now();
        if (currentTime - lastChangeTime > 3000) {
            getStarMark();
            lastChangeTime = currentTime;
        }
    }

    const mainNode = document.querySelector("#main-outlet");
    if (mainNode) {
        const observer = new MutationObserver(mutationCallback);
        observer.observe(mainNode, { childList: true, subtree: true });
    }

    getStarMark();

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址