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