YouTube NoLiveChat

Automatically closes the YouTube Live Chat (Theater Mode or Full Screen).

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

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

})();