Adds a secondary hide button to chat windows allowing you to hide them in individual tabs/windows without syncing to others.
// ==UserScript==
// @name Torn Chat Hider
// @description Adds a secondary hide button to chat windows allowing you to hide them in individual tabs/windows without syncing to others.
// @namespace http://tampermonkey.net/
// @version 5.3
// @author Deviyl[3722358]
// @icon https://raw.githubusercontent.com/deviyl/media/refs/heads/main/icons/devicon.png
// @license MIT
// @match https://www.torn.com/*
// @grant GM_addStyle
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
GM_addStyle(`
.lch { display: none !important; }
.local-min-btn { cursor: pointer; transition: opacity 0.2s; display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; }
.local-min-btn:hover { opacity: 0.6; }
`);
function setup() {
const btns = document.querySelectorAll('svg[aria-label="Minimize"]');
btns.forEach(btn => {
if (btn.dataset.lmin || btn.classList.contains('local-min-btn')) return;
btn.dataset.lmin = "1";
const chatBox = btn.closest('div[id*="-"]');
if (!chatBox) return;
const chatId = chatBox.id;
const wrap = chatBox.parentElement.parentElement;
if (!wrap) return;
if (sessionStorage.getItem(`lch-${chatId}`) === 'true') wrap.classList.add('lch');
const nativeGrad = btn.querySelector('linearGradient, defs linearGradient');
let gradUrl = 'currentColor';
if (nativeGrad && nativeGrad.id) gradUrl = `url(#${nativeGrad.id})`;
else {
const parentGrad = btn.parentNode.querySelector('linearGradient');
if (parentGrad && parentGrad.id) gradUrl = `url(#${parentGrad.id})`;
}
const localBtn = document.createElementNS("http://www.w3.org/2000/svg", "svg");
localBtn.setAttribute("viewBox", "0 0 24 24");
localBtn.setAttribute("width", "24");
localBtn.setAttribute("height", "24");
localBtn.setAttribute("aria-label", "Local Hide");
localBtn.classList.add("local-min-btn");
localBtn.innerHTML = `
<g fill="${gradUrl}">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8 0-1.85.63-3.55 1.69-4.9L16.9 18.31C15.55 19.37 13.85 20 12 20zm6.31-4.9L7.1 5.69C8.45 4.63 10.15 4 12 4c4.42 0 8 3.58 8 8 0 1.85-.63 3.55-1.69 4.9z"/>
</g>
`;
localBtn.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
wrap.classList.add('lch');
sessionStorage.setItem(`lch-${chatId}`, 'true');
}, true);
btn.parentNode.insertBefore(localBtn, btn.nextSibling);
});
const panelBtns = document.querySelectorAll('button[id*="channel_panel_button:"]');
panelBtns.forEach(pBtn => {
if (pBtn.dataset.lhook) return;
pBtn.dataset.lhook = "1";
const targetId = pBtn.id.split('channel_panel_button:')[1];
if (!targetId) return;
pBtn.addEventListener('click', function(e) {
if (sessionStorage.getItem(`lch-${targetId}`) === 'true') {
const chatTarget = document.getElementById(targetId);
if (chatTarget) {
const targetWrap = chatTarget.parentElement.parentElement;
if (targetWrap && targetWrap.classList.contains('lch')) {
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
targetWrap.classList.remove('lch');
sessionStorage.removeItem(`lch-${targetId}`);
}
}
}
}, true);
});
}
const observer = new MutationObserver(setup);
observer.observe(document.body, { childList: true, subtree: true });
setup();
})();