YouTube Auto Cinema Mode

Switches YouTube player to Default view or Theater view depending on viewport size.

// ==UserScript==
// @name         YouTube Auto Cinema Mode
// @namespace    https://github.com/nullstreak
// @version      1.6.2
// @description  Switches YouTube player to Default view or Theater view depending on viewport size.
// @author       Gemini 2.5 Pro, nullstreak
// @match        https://www.youtube.com/watch*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=youtube.com
// @license      MIT
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function() {
    'use strict';

    const SCREEN_WIDTH_THRESHOLD_PERCENT = 84;
    const DEBOUNCE_DELAY_MS = 250;
    const ENABLE_LOGGING = false;

    function log(message) {
        if (ENABLE_LOGGING) {
            console.log(`YT Smart Player Size: ${message}`);
        }
    }

    function debounce(func, wait) {
        let timeout;
        return function executedFunction(...args) {
            const later = () => {
                clearTimeout(timeout);
                func(...args);
            };
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
        };
    }

    function checkAndToggleViewMode() {
        const watchFlexy = document.querySelector('ytd-watch-flexy.watch-root-element');
        const sizeButton = document.querySelector('.ytp-size-button');

        if (!watchFlexy || !sizeButton) {
            log('Required elements not found yet.');
            return;
        }

        const isInFullscreen = watchFlexy.hasAttribute('fullscreen');
        if (isInFullscreen) {
            log('In Fullscreen mode, skipping view mode toggle.');
            return;
        }

        const viewportWidth = window.innerWidth;
        const screenWidth = window.screen.width;
        const thresholdWidth = screenWidth * (SCREEN_WIDTH_THRESHOLD_PERCENT / 100);
        const isInTheaterMode = watchFlexy.hasAttribute('theater');

        log(`Check. Viewport: ${viewportWidth}, Threshold (${SCREEN_WIDTH_THRESHOLD_PERCENT}%): ${thresholdWidth.toFixed(0)}, InTheater: ${isInTheaterMode}, InFullscreen: ${isInFullscreen}`);

        if (viewportWidth > thresholdWidth) { // Should be Default
            if (isInTheaterMode) {
                log(`ACTION: Switching TO Default Mode.`);
                sizeButton.click();
            } else {
                log(`STATUS: Already IN Default Mode.`);
            }
        } else { // Should be Theater
            if (!isInTheaterMode) {
                log(`ACTION: Switching TO Theater Mode.`);
                sizeButton.click();
            } else {
                log(`STATUS: Already IN Theater Mode.`);
            }
        }
    }

    const debouncedCheck = debounce(checkAndToggleViewMode, DEBOUNCE_DELAY_MS);

    function initialize() {
        let checkInterval = null;
        let initTimeout = null;

        const tryInit = () => {
            const watchFlexy = document.querySelector('ytd-watch-flexy.watch-root-element');
            const sizeButton = document.querySelector('.ytp-size-button');

            if (watchFlexy && sizeButton) {
                if (checkInterval) clearInterval(checkInterval);
                if (initTimeout) clearTimeout(initTimeout);
                checkInterval = null;
                initTimeout = null;

                log('Initializing...');
                setTimeout(checkAndToggleViewMode, 200); // Initial check
                window.addEventListener('resize', debouncedCheck);
                log('Ready and listening for resize.');
                return true;
            }
            return false;
        };

        if (!tryInit()) {
             log('Elements not found immediately. Waiting...');
             checkInterval = setInterval(() => {
                 if (tryInit()) {
                     /* handled in tryInit */
                 } else {
                      log('Still waiting for elements...');
                 }
             }, 500);

             initTimeout = setTimeout(() => {
                 if (checkInterval) {
                     clearInterval(checkInterval);
                     checkInterval = null;
                     log('Initialization timed out.');
                 }
                 initTimeout = null;
             }, 20000);
        }
    }

    log("Script loaded. Starting initialization.");
    setTimeout(initialize, 100);

})();