Greasy Fork is available in English.

Freesmth User Blocker

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

คุณจะต้องติดตั้งส่วนขยาย เช่น Tampermonkey, Greasemonkey หรือ Violentmonkey เพื่อติดตั้งสคริปต์นี้

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

คุณจะต้องติดตั้งส่วนขยาย เช่น Tampermonkey หรือ Violentmonkey เพื่อติดตั้งสคริปต์นี้

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

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

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

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

})();