LinuxDo快速收藏

在帖子中添加快速收藏的功能

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

// ==UserScript==
// @name         LinuxDo快速收藏
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  在帖子中添加快速收藏的功能
// @author       Yearly
// @match        https://linux.do/*
// @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 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);

            xhr.send();

            xhr.onreadystatechange = function() {
                if (xhr.readyState === 4) {
                    if (xhr.status === 200) { // 请求成功
                        console.log('删除成功:', xhr.responseText);
                        mark_btn.style.color = '#777';
                        mark_btn.title="收藏"
                        mark_btn.onclick = () => addStarMark(mark_btn, mark_id);
                    } else {
                        console.error('DELETE请求失败:', xhr.statusText);
                    }
                }
            };
        }

    }

    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`;

        xhr.send(postData);

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

    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);
        xhr.send();
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4 && xhr.status === 200) {
                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);
                    }
                });

            } else if (xhr.readyState === 4) {
                console.error('GET请求失败:', xhr.statusText);
            }
        };
    }

    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或关注我们的公众号极客氢云获取最新地址