Freesmth User Blocker

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

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==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 });

})();