YouTube NoLiveChat

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

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Для установки этого скрипта вам необходимо установить расширение, такое как Tampermonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

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

})();