Rumble Live Chat Blocker

Hide messages from specific users in Rumble live chat with a block user menu

// ==UserScript==
// @name         Rumble Live Chat Blocker
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Hide messages from specific users in Rumble live chat with a block user menu
// @author       CynicalPhantom
// @match        https://rumble.com/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // Function to load blocked users from localStorage
    function loadBlockedUsers() {
        const storedBlockedUsers = localStorage.getItem('blockedUsers');
        return storedBlockedUsers ? JSON.parse(storedBlockedUsers) : [];
    }

    // Function to save blocked users to localStorage
    function saveBlockedUsers(blockedUsers) {
        localStorage.setItem('blockedUsers', JSON.stringify(blockedUsers));
    }

    // Load blocked users from localStorage
    const blockedUsers = loadBlockedUsers();

    // Function to hide messages from blocked users
    function hideBlockedMessages() {
        const chatMessages = document.querySelectorAll('.chat-history--row');
        const usernameSelector = '.chat-history--username';

        chatMessages.forEach(message => {
            const usernameElement = message.querySelector(usernameSelector);
            if (usernameElement) {
                const username = usernameElement.textContent.trim();
                if (blockedUsers.includes(username)) {
                    message.style.display = 'none';
                }
            }
        });
    }

    // Function to add the menu button and dropdown
    function addBlockUserMenu() {
        // Create the icon button
        const menuButton = document.createElement('button');
        menuButton.textContent = '⚙️';
        menuButton.style.position = 'fixed';
        menuButton.style.bottom = '10px';
        menuButton.style.left = '10px';
        menuButton.style.zIndex = '999999';
        menuButton.style.padding = '8px';
        menuButton.style.width = '32px';
        menuButton.style.height = '32px';
        menuButton.style.backgroundColor = '#333';
        menuButton.style.color = '#fff';
        menuButton.style.border = 'none';
        menuButton.style.borderRadius = '5px';
        menuButton.style.cursor = 'pointer';
        menuButton.style.fontSize = '16px';
        menuButton.style.display = 'flex';
        menuButton.style.alignItems = 'center';
        menuButton.style.justifyContent = 'center';

        // Create the dropdown menu (initially hidden)
        const menu = document.createElement('div');
        menu.style.position = 'fixed';
        menu.style.bottom = '50px';
        menu.style.left = '10px';
        menu.style.zIndex = '999999';
        menu.style.backgroundColor = '#333';
        menu.style.color = '#fff';
        menu.style.borderRadius = '5px';
        menu.style.boxShadow = '0 2px 5px rgba(0,0,0,0.3)';
        menu.style.display = 'none';
        menu.style.flexDirection = 'column';
        menu.style.padding = '5px 0';

        // Block User menu item
        const blockItem = document.createElement('div');
        blockItem.textContent = 'Block User';
        blockItem.style.padding = '8px 15px';
        blockItem.style.cursor = 'pointer';
        blockItem.style.whiteSpace = 'nowrap';
        blockItem.style.fontSize = '14px';
        blockItem.addEventListener('click', () => {
            menu.style.display = 'none';
            const input = prompt('Enter the username to block:');
            if (input) {
                const trimmedInput = input.trim();
                if (!blockedUsers.includes(trimmedInput)) {
                    blockedUsers.push(trimmedInput);
                    saveBlockedUsers(blockedUsers);
                    hideBlockedMessages();
                } else {
                    alert('User is already blocked.');
                }
            }
        });

        // Unblock User menu item
        const unblockItem = document.createElement('div');
        unblockItem.textContent = 'Unblock User';
        unblockItem.style.padding = '8px 15px';
        unblockItem.style.cursor = 'pointer';
        unblockItem.style.whiteSpace = 'nowrap';
        unblockItem.style.fontSize = '14px';
        unblockItem.addEventListener('click', () => {
            menu.style.display = 'none';
            if (blockedUsers.length === 0) {
                alert('No users are blocked.');
                return;
            }
            const options = blockedUsers.map((user, index) => `${index}: ${user}`).join('\n');
            const selection = prompt('Select a user to unblock:\n' + options);
            if (selection !== null) {
                const index = parseInt(selection, 10);
                if (!isNaN(index) && index >= 0 && index < blockedUsers.length) {
                    const unblockedUser = blockedUsers.splice(index, 1)[0];
                    saveBlockedUsers(blockedUsers);
                    alert(`User ${unblockedUser} has been unblocked.`);
                    hideBlockedMessages();
                } else {
                    alert('Invalid selection.');
                }
            }
        });

        // Add menu items to menu
        menu.appendChild(blockItem);
        menu.appendChild(unblockItem);

        // Toggle menu visibility on button click
        menuButton.addEventListener('click', () => {
            menu.style.display = menu.style.display === 'none' ? 'flex' : 'none';
        });

        // Close menu when clicking outside
        document.addEventListener('click', (event) => {
            if (!menuButton.contains(event.target) && !menu.contains(event.target)) {
                menu.style.display = 'none';
            }
        });

        // Append button and menu to the page
        document.body.appendChild(menuButton);
        document.body.appendChild(menu);
    }

    // Run the function initially
    hideBlockedMessages();

    // Set up a MutationObserver to handle new messages
    const observer = new MutationObserver((mutations) => {
        mutations.forEach(mutation => {
            if (mutation.addedNodes.length > 0) {
                hideBlockedMessages();
            }
        });
    });

    // Start observing the chat container
    const chatContainer = document.querySelector('.chat-history');
    if (chatContainer) {
        observer.observe(chatContainer, { childList: true, subtree: true });
    }

    // Add the menu button and dropdown
    addBlockUserMenu();
})();