YouTube Split Control Panel with Trusted Overlay

Устанавливает сплит по времени, выводит панель управления в clarify-box и, при достижении порога, показывает оверлей "СПЛИТ НЕ ОПЛАЧЕН" с кнопкой продления (+ 1 минута)

目前為 2025-02-09 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         YouTube Split Control Panel with Trusted Overlay
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Устанавливает сплит по времени, выводит панель управления в clarify-box и, при достижении порога, показывает оверлей "СПЛИТ НЕ ОПЛАЧЕН" с кнопкой продления (+ 1 минута)
// @author       ChatGPT
// @match        *://www.youtube.com/watch*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Глобальные переменные
    let splitMinutes = null;    // Значение сплита в минутах
    let video = null;           // Элемент видео
    let overlay = null;         // Элемент оверлея
    let splitTriggered = false; // Флаг, что сплит активирован

    // Обновление отображения значения сплита в спинере
    function updateSplitDisplay() {
        const inputField = document.getElementById("split-input");
        if (inputField && splitMinutes !== null) {
            inputField.value = splitMinutes;
        }
    }

    // Создание панели управления сплитом внутри элемента "clarify-box"
    function addControlPanel() {
        const clarifyBox = document.getElementById("clarify-box");
        if (!clarifyBox) return;
        if (document.getElementById("split-control-panel")) return; // панель уже существует

        // Создаем контейнер панели
        const panel = document.createElement("div");
        panel.id = "split-control-panel";
        panel.style.cssText = "margin-top: 10px; padding: 10px; background: #f1f1f1; border: 1px solid #ccc; display: flex; align-items: center; gap: 10px;";

        // Кнопка "Установить СПЛИТ"
        const setButton = document.createElement("button");
        setButton.textContent = "Установить СПЛИТ";
        setButton.style.cssText = "padding: 5px 10px; font-size: 16px; cursor: pointer;";
        setButton.addEventListener("click", function() {
            const inputField = document.getElementById("split-input");
            const inputVal = parseInt(inputField.value, 10);
            if (!isNaN(inputVal) && inputVal >= 0) {
                splitMinutes = inputVal;
                video.pause();       // Останавливаем видео
                splitTriggered = true;
                showOverlay();       // Показываем оверлей, как в оригинальном скрипте
            } else {
                alert("Введите корректное число минут.");
            }
        });

        // Метка "СПЛИТ (мин):"
        const label = document.createElement("span");
        label.textContent = "СПЛИТ (мин):";
        label.style.fontSize = "16px";

        // Кнопка уменьшения (стрелка вниз)
        const decrementButton = document.createElement("button");
        decrementButton.textContent = "↓";
        decrementButton.style.cssText = "padding: 5px; font-size: 16px; cursor: pointer;";
        decrementButton.addEventListener("click", function() {
            const inputField = document.getElementById("split-input");
            let currentVal = parseInt(inputField.value, 10);
            if (!isNaN(currentVal) && currentVal > 0) {
                inputField.value = currentVal - 1;
                updateSplitTime();
            }
        });

        // Поле ввода (spinner) для установки минут сплита
        const inputField = document.createElement("input");
        inputField.type = "number";
        inputField.id = "split-input";
        inputField.value = "0";
        inputField.min = "0";
        inputField.style.cssText = "width: 60px; text-align: center; font-size: 16px;";
        inputField.addEventListener("change", updateSplitTime);

        // Кнопка увеличения (стрелка вверх)
        const incrementButton = document.createElement("button");
        incrementButton.textContent = "↑";
        incrementButton.style.cssText = "padding: 5px; font-size: 16px; cursor: pointer;";
        incrementButton.addEventListener("click", function() {
            const inputField = document.getElementById("split-input");
            let currentVal = parseInt(inputField.value, 10);
            if (!isNaN(currentVal)) {
                inputField.value = currentVal + 1;
                updateSplitTime();
            }
        });

        // Собираем панель
        panel.appendChild(setButton);
        panel.appendChild(label);
        panel.appendChild(decrementButton);
        panel.appendChild(inputField);
        panel.appendChild(incrementButton);

        // Вставляем панель в "clarify-box"
        clarifyBox.appendChild(panel);
    }

    // Обновление значения сплита при изменении в спинере
    function updateSplitTime() {
        const inputField = document.getElementById("split-input");
        const newVal = parseInt(inputField.value, 10);
        if (!isNaN(newVal)) {
            splitMinutes = newVal;
            updateSplitDisplay();
            // Если видео остановлено из-за сплита и текущее время стало меньше нового порога,
            // убираем оверлей и продолжаем воспроизведение
            if (video && splitTriggered && video.currentTime < splitMinutes * 60) {
                video.play();
                splitTriggered = false;
                removeOverlay();
            }
        }
    }

    // Проверка времени видео – если текущее время достигло или превысило порог, останавливаем видео и показываем оверлей
    function checkSplitCondition() {
        if (!video || splitMinutes === null) return;
        const thresholdSeconds = splitMinutes * 60;
        if (video.currentTime >= thresholdSeconds && !splitTriggered) {
            video.pause();
            splitTriggered = true;
            showOverlay();
        }
        // Если сплит активирован, но пользователь увеличил его и текущее время стало меньше порога,
        // возобновляем воспроизведение
        if (splitTriggered && video.currentTime < thresholdSeconds) {
            video.play();
            splitTriggered = false;
            removeOverlay();
        }
    }

    // Функция показа полноэкранного оверлея с надписями (как в исходном скрипте)
    function showOverlay() {
        if (overlay) return;
        overlay = document.createElement("div");
        overlay.style.cssText = `
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.95);
            color: white;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            z-index: 99999;
        `;

        // Надпись с предупреждением
        const warningMessage = document.createElement("div");
        warningMessage.textContent = "⚠️ НУЖНО ДОНАТНОЕ ТОПЛИВО ⚠️";
        warningMessage.style.cssText = "font-size: 48px; margin-bottom: 20px;";

        // Надпись "СПЛИТ НЕ ОПЛАЧЕН"
        const splitMessage = document.createElement("div");
        splitMessage.textContent = "СПЛИТ НЕ ОПЛАЧЕН";
        splitMessage.style.cssText = "font-size: 64px; font-weight: bold; margin-bottom: 30px;";

        // Кнопка для продления сплита (увеличение на 1 минуту)
        const extendButton = document.createElement("button");
        extendButton.textContent = "+ 1 минута - 300 рублей";
        extendButton.style.cssText = "padding: 10px 20px; font-size: 24px; cursor: pointer; background: #ff4500; border: none; color: white;";
        extendButton.addEventListener("click", function() {
            extendSplit();
        });

        // Собираем оверлей
        overlay.appendChild(warningMessage);
        overlay.appendChild(splitMessage);
        overlay.appendChild(extendButton);

        document.body.appendChild(overlay);
    }

    // Удаление оверлея
    function removeOverlay() {
        if (overlay) {
            overlay.remove();
            overlay = null;
        }
    }

    // Продление сплита – увеличение на 1 минуту
    function extendSplit() {
        if (splitMinutes === null) return;
        splitMinutes += 1;
        updateSplitDisplay();
        // Если текущее время стало меньше нового порога, убираем оверлей и продолжаем воспроизведение
        if (video.currentTime < splitMinutes * 60) {
            removeOverlay();
            video.play();
            splitTriggered = false;
        } else {
            alert("Продление недостаточно для продолжения воспроизведения. Продлите сплит ещё раз.");
        }
    }

    // Инициализация скрипта
    function init() {
        video = document.querySelector("video");
        if (!video) return;
        addControlPanel();
        setInterval(checkSplitCondition, 500);
    }

    // Ждем загрузки страницы
    setTimeout(init, 3000);
    setInterval(addControlPanel, 2000);
})();