Douban User Blocker

Add a draggable blocklist management button on Douban.

目前為 2025-03-08 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Douban User Blocker
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Add a draggable blocklist management button on Douban.
// @author       AAA_aaa
// @match        *://*.douban.com/*
// @grant        none
// @license MIT
// ==/UserScript==

(function () {
    'use strict';

    const BLOCKLIST_KEY = 'doubanBlocklist';

    function loadBlocklist() {
        const stored = localStorage.getItem(BLOCKLIST_KEY);
        return stored ? JSON.parse(stored) : [];
    }

    function saveBlocklist(blocklist) {
        localStorage.setItem(BLOCKLIST_KEY, JSON.stringify(blocklist));
    }

    function addToBlocklist(userId) {
        const blocklist = loadBlocklist();
        if (!blocklist.includes(userId)) {
            blocklist.push(userId);
            saveBlocklist(blocklist);
           //alert(`User ${userId} has been added to the blocklist.`);
        } else {
            alert(`User ${userId} is already in the blocklist.`);
        }
        removeBlockedElements();
        updateBlocklistMenu();
    }

    function removeFromBlocklist(userId) {
        let blocklist = loadBlocklist();
        blocklist = blocklist.filter(id => id !== userId);
        saveBlocklist(blocklist);
        updateBlocklistMenu();
    }

    function removeBlockedElements() {
        const blocklist = loadBlocklist();
        document.querySelectorAll('.comment-item, .lite-comment-item, .review-item, .new-status, .ctsh').forEach(element => {
            const link = element.querySelector('a[href^="https://www.douban.com/people/"]');
            if (link) {
                const userId = link.href.split('/')[4];
                if (blocklist.includes(userId)) {
                    element.remove();
                }
            }
        });
    }

    function addFloatingButton() {
        const button = document.createElement('div');
        button.id = 'drag-button';
        button.textContent = 'Manage Blocklist';
        document.body.appendChild(button);

        let isDragging = false, offsetX, offsetY;

        button.addEventListener('mousedown', (e) => {
            isDragging = true;
            offsetX = e.clientX - button.offsetLeft;
            offsetY = e.clientY - button.offsetTop;
            button.style.cursor = 'grabbing';
        });

        document.addEventListener('mousemove', (e) => {
            if (!isDragging) return;
            button.style.left = `${e.clientX - offsetX}px`;
            button.style.top = `${e.clientY - offsetY}px`;
        });

        document.addEventListener('mouseup', () => {
            isDragging = false;
            button.style.cursor = 'grab';
        });

        button.addEventListener('click', (e) => {
            e.stopPropagation();
            const menu = document.querySelector('.douban-menu');
            menu.style.display = menu.style.display === 'block' ? 'none' : 'block';
        });
    }

    function addBlocklistMenu() {
        const menu = document.createElement('div');
        menu.className = 'douban-menu';
        menu.innerHTML = `
            <div class="popup">
                <h3>Blocked Users</h3>
                <div class="blocklist-container">
                    <ul id="blocklist"></ul>
                </div>
                <input type="text" id="user-url" placeholder="Enter Douban user URL">
                <button id="add-user">Add</button>
                <button id="close-menu">Close</button>
            </div>
        `;
        document.body.appendChild(menu);

        document.getElementById('add-user').addEventListener('click', () => {
            const userUrl = document.getElementById('user-url').value;
            const match = userUrl.match(/https:\/\/www\.douban\.com\/people\/([^/]+)/);
            if (match && match[1]) {
                addToBlocklist(match[1]);
            } else {
                alert('Invalid Douban user URL.');
            }
        });

        document.getElementById('close-menu').addEventListener('click', () => {
            menu.style.display = 'none';
        });

        updateBlocklistMenu();
    }

    function updateBlocklistMenu() {
        const blocklist = loadBlocklist();
        const listElement = document.getElementById('blocklist');
        listElement.innerHTML = '';
        blocklist.forEach(userId => {
            const li = document.createElement('li');
            li.textContent = userId;
            const removeBtn = document.createElement('button');
            removeBtn.textContent = 'Remove';
            removeBtn.className = 'del';
            removeBtn.addEventListener('click', () => removeFromBlocklist(userId));
            li.appendChild(removeBtn);
            listElement.appendChild(li);
        });
    }

    const style = document.createElement('style');
    style.innerHTML = `
        #drag-button {
            position: fixed;
            bottom: 20px;
            right: 20px;
            background: #28a745;
            color: white;
            padding: 10px 15px;
            border-radius: 5px;
            cursor: grab;
            z-index: 1000;
        }
        .douban-menu {
            width: 300px;
            position: fixed;
            top: 50px;
            right: 20px;
            background: white;
            border: 1px solid #ccc;
            padding: 10px;
            border-radius: 5px;
            display: none;
            z-index: 999;
        }
        .blocklist-container {
            max-height: 150px;
            overflow-y: auto;
            border: 1px solid #ccc;
            padding: 5px;
        }
        .del {
            cursor: pointer;
            margin-left: 10px;
            padding: 3px 8px;
            border: none;

            border-radius: 3px;
        }
        .del:hover {
            background: darkred;
        }
    `;
    document.head.appendChild(style);

    function main() {
        addFloatingButton();
        addBlocklistMenu();
        removeBlockedElements();
        const observer = new MutationObserver(removeBlockedElements);
        observer.observe(document.body, { childList: true, subtree: true });
    }

    main();
})();

QingJ © 2025

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