Automatically closes the YouTube Live Chat (Theater Mode or Full Screen).
// ==UserScript==
// @name YouTube NoLiveChat
// @namespace http://tampermonkey.net/
// @version 7.3
// @description Automatically closes the YouTube Live Chat (Theater Mode or Full Screen).
// @author Narc (Fixed by Gemini)
// @license MIT
// @match https://www.youtube.com/*
// @match https://www.youtube.com/live_chat*
// @icon https://i.ibb.co/yDP9ZXg/E3610-DA9-5898-49-DA-8-EBF-DB78-F039-EAAE-removebg-preview.png
// @grant none
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
const CONFIG = {
DELAY_MS: 10000, // 10 Segundos de delay
DEBUG: true,
CMD_CLOSE: 'SENTINEL_CMD_CLOSE'
};
function log(msg, context = 'Main') {
if (CONFIG.DEBUG) console.log(`%c[Sentinel:${context}] ${msg}`, 'color: #00ff00; font-weight: bold;');
}
// =================================================================
// LADO A: O SOLDADO (Roda dentro do Iframe do Chat)
// =================================================================
if (window.location.pathname.startsWith('/live_chat')) {
log('Soldado iniciado no iframe do chat.', 'Iframe');
// Definimos a função como const antes de usar para evitar o aviso do linter
const closeChatInsideIframe = () => {
// Seletores específicos do ambiente do chat
const selectors = [
'#close-button button',
'#chat-header #close-button button',
'button[aria-label="Fechar"]',
'button[aria-label="Close"]'
];
let btn = null;
for (let sel of selectors) {
btn = document.querySelector(sel);
if (btn) break;
}
if (btn) {
// Clique Nuclear
const opts = { bubbles: true, cancelable: true, view: window };
btn.dispatchEvent(new MouseEvent('mousedown', opts));
btn.dispatchEvent(new MouseEvent('mouseup', opts));
btn.click();
log('Botão clicado com sucesso.', 'Iframe');
} else {
log('ERRO: Botão de fechar não encontrado no iframe.', 'Iframe');
}
};
// Escuta ordens vindas da página principal
window.addEventListener('message', (event) => {
if (event.data === CONFIG.CMD_CLOSE) {
log('Ordem de fechamento recebida! Executando...', 'Iframe');
closeChatInsideIframe();
}
});
return; // Encerra execução aqui se for iframe
}
// =================================================================
// LADO B: O COMANDANTE (Roda na Página do Vídeo)
// =================================================================
let timer = null;
function isExpandedMode() {
const isFullscreen = !!document.fullscreenElement;
const watchFlexy = document.querySelector('ytd-watch-flexy');
const isTheater = watchFlexy && watchFlexy.hasAttribute('theater');
return isFullscreen || isTheater;
}
function sendCloseOrder() {
// Verifica se ainda devemos fechar
if (!isExpandedMode()) {
log('Cancelando ordem: Modo expandido encerrado.', 'Commander');
return;
}
const iframe = document.getElementById('chatframe');
if (iframe && iframe.contentWindow) {
log('Enviando ordem de fechamento para o iframe...', 'Commander');
// Envia a mensagem para o iframe
iframe.contentWindow.postMessage(CONFIG.CMD_CLOSE, '*');
} else {
log('Iframe do chat não encontrado. Tentando novamente em 2s...', 'Commander');
setTimeout(sendCloseOrder, 2000);
}
}
function scheduleOrder() {
if (!isExpandedMode()) return;
log(`Modo Expandido detectado. Timer iniciado: ${CONFIG.DELAY_MS/1000}s`, 'Commander');
if (timer) clearTimeout(timer);
timer = setTimeout(sendCloseOrder, CONFIG.DELAY_MS);
}
// --- Gatilhos do Comandante ---
// 1. Tela Cheia
document.addEventListener('fullscreenchange', () => {
if (document.fullscreenElement) scheduleOrder();
else if (timer) clearTimeout(timer);
});
// 2. Modo Teatro
const observer = new MutationObserver((mutations) => {
for (const m of mutations) {
if (m.type === 'attributes' && m.attributeName === 'theater') {
setTimeout(scheduleOrder, 500);
}
}
});
// 3. Atalho de Teste (ALT + K)
document.addEventListener('keydown', (e) => {
if (e.altKey && (e.key === 'k' || e.key === 'K')) {
log('TESTE MANUAL: Enviando ordem imediata.', 'Commander');
const iframe = document.getElementById('chatframe');
if(iframe) iframe.contentWindow.postMessage(CONFIG.CMD_CLOSE, '*');
else log('Iframe não achado para teste.', 'Commander');
}
});
// Inicialização
const initInt = setInterval(() => {
const watchFlexy = document.querySelector('ytd-watch-flexy');
if (watchFlexy) {
observer.observe(watchFlexy, { attributes: true });
clearInterval(initInt);
// Verifica estado inicial
if (isExpandedMode()) scheduleOrder();
}
}, 1000);
})();