Freesmth User Blocker

在 freesmth.net 上屏蔽指定用户的帖子

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

You will need to install an extension such as Tampermonkey to install this script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Necesitará instalar una extensión como Tampermonkey para instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name         Freesmth User Blocker
// @namespace    http://tampermonkey.net/
// @version      1.2
// @description  在 freesmth.net 上屏蔽指定用户的帖子
// @author
// @match        https://freesmth.net/*
// @match        https://freesmth.uk/*
// @grant        GM_getValue
// @grant        GM_setValue
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // 从存储中加载屏蔽的用户列表
    let blockedUsers = GM_getValue('blockedUsers', []);

    // 处理并修改帖子
    function processPost(postElement) {
        // 避免重复处理同一帖子
        if (postElement.getAttribute('data-processed')) {
            return;
        }
        postElement.setAttribute('data-processed', 'true');

        // 查找用户名元素
        let usernameElement = postElement.querySelector('.PostUser-name .username');
        if (!usernameElement) return; // 如果找不到用户名,则跳过此帖子
        let username = usernameElement.textContent.trim();

        // 在用户名后添加或更新“隐藏/显示”按钮
        addToggleButton(usernameElement, username);

        // 检查用户是否被屏蔽
        if (blockedUsers.includes(username)) {
            // 隐藏帖子内容
            hidePostContent(postElement);
            // 将按钮文字设置为“显示”
            setToggleButtonCaption(usernameElement, '显示');
        } else {
            // 显示帖子内容
            showPostContent(postElement);
            // 将按钮文字设置为“隐藏”
            setToggleButtonCaption(usernameElement, '隐藏');
        }
    }

    // 隐藏帖子内容
    function hidePostContent(postElement) {
        // 隐藏帖子正文和操作
        let postBody = postElement.querySelector('.Post-body');
        if (postBody) postBody.style.display = 'none';
        let postActions = postElement.querySelector('.Post-actions');
        if (postActions) postActions.style.display = 'none';
    }

    // 显示帖子内容
    function showPostContent(postElement) {
        // 显示帖子正文和操作
        let postBody = postElement.querySelector('.Post-body');
        if (postBody) postBody.style.display = '';
        let postActions = postElement.querySelector('.Post-actions');
        if (postActions) postActions.style.display = '';
    }

    // 在用户名后添加或更新“隐藏/显示”按钮
    function addToggleButton(usernameElement, username) {
        // 检查按钮是否已存在
        let h3Element = usernameElement.closest('.PostUser-name');
        if (!h3Element) return;

        let existingButton = h3Element.querySelector('.toggleUserButton');
        if (existingButton) {
            // 更新事件处理器以确保使用正确的用户名
            existingButton.removeEventListener('click', existingButton.handlerReference);
            existingButton.handlerReference = function(e) {
                e.stopPropagation();
                e.preventDefault();
                toggleUser(username);
            };
            existingButton.addEventListener('click', existingButton.handlerReference);
        } else {
            // 创建按钮
            let toggleButton = document.createElement('button');
            toggleButton.className = 'toggleUserButton';
            toggleButton.style.marginLeft = '5px';

            toggleButton.handlerReference = function(e) {
                e.stopPropagation(); // 阻止事件冒泡
                e.preventDefault(); // 阻止默认行为
                toggleUser(username);
            };
            toggleButton.addEventListener('click', toggleButton.handlerReference);

            // 在用户名后添加按钮
            h3Element.appendChild(toggleButton);
        }
    }

    // 设置按钮文字
    function setToggleButtonCaption(usernameElement, caption) {
        let h3Element = usernameElement.closest('.PostUser-name');
        if (!h3Element) return;
        let toggleButton = h3Element.querySelector('.toggleUserButton');
        if (toggleButton) {
            toggleButton.textContent = caption;
        }
    }

    // 切换用户的屏蔽状态
    function toggleUser(username) {
        if (blockedUsers.includes(username)) {
            // 用户当前被屏蔽,解除屏蔽
            blockedUsers = blockedUsers.filter(u => u !== username);
        } else {
            // 用户未被屏蔽,添加到屏蔽列表
            blockedUsers.push(username);
        }
        GM_setValue('blockedUsers', blockedUsers);
        // 重新处理所有帖子以更新显示
        processAllPosts();
    }

    // 处理页面上的所有帖子
    function processAllPosts() {
        let posts = document.querySelectorAll('.PostStream-item .Post');
        posts.forEach(function(postElement) {
            // 移除处理标记
            postElement.removeAttribute('data-processed');
        });
        // 处理每个帖子
        posts.forEach(function(postElement) {
            processPost(postElement);
        });
    }

    // 初始处理帖子
    processAllPosts();

    // 观察 DOM,处理动态加载的帖子(无限滚动)
    const observer = new MutationObserver(function(mutationsList) {
        mutationsList.forEach(function(mutation) {
            mutation.addedNodes.forEach(function(node) {
                if (node.nodeType !== Node.ELEMENT_NODE) return;
                let posts = [];
                if (node.matches('.PostStream-item .Post')) {
                    posts.push(node);
                } else {
                    posts = node.querySelectorAll('.PostStream-item .Post');
                }
                posts.forEach(function(postElement) {
                    processPost(postElement);
                });
            });
        });
    });
    observer.observe(document.body, { childList: true, subtree: true });

})();