GameBanana Toggle Categories

Menu to hide/show Mods, Tutorials, Tools, Sounds, Concepts, WIPs, Sprays, Polls, Threads, Requests, Questions everywhere in gamebanana.com.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

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

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

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         GameBanana Toggle Categories
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Menu to hide/show Mods, Tutorials, Tools, Sounds, Concepts, WIPs, Sprays, Polls, Threads, Requests, Questions everywhere in gamebanana.com.
// @author       ChatGPT
// @match        https://gamebanana.com/*
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    const STORAGE_KEY = 'gbToggleCategoriesOptions';

    const categories = [
        { label: 'Mods', className: 'ModRecord', keyword: 'mods', hidden: false },
        { label: 'Tutorials', className: 'TutorialRecord', keyword: 'tutorials', hidden: false },
        { label: 'Tools', className: 'ToolRecord', keyword: 'tools', hidden: false },
        { label: 'Sounds', className: 'SoundRecord', keyword: 'sounds', hidden: false },
        { label: 'Concepts', className: 'ConceptRecord', keyword: 'concepts', hidden: false },
        { label: 'WIPs', className: 'WipRecord', keyword: 'wips', hidden: false },
        { label: 'Sprays', className: 'SprayRecord', keyword: 'sprays', hidden: false },
        { label: 'Polls', className: 'PollRecord', keyword: 'polls', hidden: false },
        { label: 'Threads', className: 'ThreadRecord', keyword: 'threads', hidden: false },
        { label: 'Requests', className: 'RequestRecord', keyword: 'requests', hidden: false },
        { label: 'Questions', className: 'QuestionRecord', keyword: 'questions', hidden: false }
    ];

    // Load preferences
    function loadOptions() {
        const saved = localStorage.getItem(STORAGE_KEY);
        if (saved) {
            try {
                const parsed = JSON.parse(saved);
                categories.forEach(cat => {
                    const savedCat = parsed.find(c => c.className === cat.className);
                    if (savedCat && typeof savedCat.hidden === 'boolean') {
                        cat.hidden = savedCat.hidden;
                    }
                });
            } catch(e) {
                console.warn('Error loading options:', e);
            }
        }
    }

    // Save preferences
    function saveOptions() {
        localStorage.setItem(STORAGE_KEY, JSON.stringify(categories));
    }

    loadOptions();

    // Create foldable menu
    const container = document.createElement('div');
    Object.assign(container.style, {
        position: 'fixed',
        top: '70px',
        left: '8px',
        width: '260px',
        backgroundColor: '#1b1b1b',
        border: '1px solid #444',
        borderRadius: '5px',
        boxShadow: '0 0 12px rgba(0,0,0,0.8)',
        fontFamily: "'Segoe UI', Tahoma, Geneva, Verdana, sans-serif",
        color: '#ccc',
        zIndex: 99999,
        userSelect: 'none',
        overflow: 'hidden',
        transition: 'height 0.25s ease',
    });

    // Foldable button
    const toggleBtn = document.createElement('button');
    toggleBtn.textContent = 'Show / Hide categories';
    Object.assign(toggleBtn.style, {
        width: '100%',
        backgroundColor: '#222',
        border: 'none',
        color: '#ccc',
        fontWeight: '600',
        padding: '10px 0',
        cursor: 'pointer',
        fontSize: '14px',
        outline: 'none',
        userSelect: 'none',
        borderRadius: '5px 5px 0 0',
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center',
        textAlign: 'center',
    });
    toggleBtn.addEventListener('mouseenter', () => toggleBtn.style.backgroundColor = '#333');
    toggleBtn.addEventListener('mouseleave', () => toggleBtn.style.backgroundColor = '#222');

    container.appendChild(toggleBtn);

    // Option container
    const optionsContainer = document.createElement('div');
    Object.assign(optionsContainer.style, {
        backgroundColor: '#181818',
        padding: '12px 16px',
        display: 'none', // folded by default
        maxHeight: '300px',
        overflowY: 'auto',
    });

    // Create checkboxes
    categories.forEach(cat => {
        const label = document.createElement('label');
        Object.assign(label.style, {
            display: 'flex',
            alignItems: 'center',
            marginBottom: '8px',
            fontSize: '13px',
            cursor: 'pointer',
            userSelect: 'none',
            color: '#ccc',
        });

        const checkbox = document.createElement('input');
        checkbox.type = 'checkbox';
        checkbox.checked = !cat.hidden;
        checkbox.style.marginRight = '10px';
        checkbox.style.cursor = 'pointer';

        checkbox.addEventListener('change', () => {
            cat.hidden = !checkbox.checked;
            saveOptions();
            applyDisplay();
        });

        label.appendChild(checkbox);
        label.appendChild(document.createTextNode(cat.label));
        optionsContainer.appendChild(label);
    });

    container.appendChild(optionsContainer);
    document.body.appendChild(container);

    // Manage folding/unfolding
    let isOpen = false;
    function updateContainer() {
        if (isOpen) {
            optionsContainer.style.display = 'block';
            container.style.height = 'auto';
        } else {
            optionsContainer.style.display = 'none';
            container.style.height = toggleBtn.offsetHeight + 'px';
        }
    }

    toggleBtn.addEventListener('click', () => {
        isOpen = !isOpen;
        updateContainer();
    });

    updateContainer();

    // Display / hide function
    function applyDisplay() {
        categories.forEach(cat => {
            // Per class
            document.querySelectorAll(`.${cat.className}`).forEach(el => {
                el.style.display = cat.hidden ? 'none' : '';
            });

            // By data-cat-url for elements close parent (for game section)
            document.querySelectorAll(`[data-cat-url*="${cat.keyword}"]`).forEach(el => {
                el.style.display = cat.hidden ? 'none' : '';
            });

            // For elements and sections where we identify by href links (ex: game section)
            document.querySelectorAll('a[href*="' + cat.keyword + '"]').forEach(a => {
                let el = a.closest('div.Record');
                if (el) {
                    el.style.display = cat.hidden ? 'none' : '';
                }
            });
        });
    }

    applyDisplay();

    // MutationObserver to detect and add dynamically
    const observer = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
            mutation.addedNodes.forEach(node => {
                if (!(node instanceof HTMLElement)) return;
                categories.forEach(cat => {
                    // By class
                    if (node.classList && node.classList.contains(cat.className)) {
                        node.style.display = cat.hidden ? 'none' : '';
                    }
                    // By data-cat-url
                    if (node.hasAttribute && node.hasAttribute('data-cat-url') && node.getAttribute('data-cat-url').includes(cat.keyword)) {
                        node.style.display = cat.hidden ? 'none' : '';
                    }
                    // By href link
                    node.querySelectorAll && node.querySelectorAll('a[href*="' + cat.keyword + '"]').forEach(a => {
                        let el = a.closest('div.Record');
                        if (el) {
                            el.style.display = cat.hidden ? 'none' : '';
                        }
                    });
                    // Search per class
                    node.querySelectorAll && node.querySelectorAll(`.${cat.className}`).forEach(el => {
                        el.style.display = cat.hidden ? 'none' : '';
                    });
                    // Search per data-cat-url
                    node.querySelectorAll && node.querySelectorAll(`[data-cat-url*="${cat.keyword}"]`).forEach(el => {
                        el.style.display = cat.hidden ? 'none' : '';
                    });
                });
            });
        });
    });

    observer.observe(document.body, { childList: true, subtree: true });

})();