TimerHooker Unified Version (UI Fix)

Fixes UI visibility issues for TimerHooker Unified Version.

Versión del día 8/4/2025. Echa un vistazo a la versión más reciente.

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

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

Tendrás que instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Tendrás que instalar una extensión como Tampermonkey antes de poder instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Tendrás que instalar una extensión como Stylus antes de poder instalar este script.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

Para poder instalar esto tendrás que instalar primero una extensión de estilos de usuario.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name            TimerHooker Unified Version (UI Fix)
// @version         4.1.0
// @description     Fixes UI visibility issues for TimerHooker Unified Version.
// @author          Combined
// @match           http://*/*
// @run-at          document-start
// @grant           none
// @license         GPL-3.0-or-later
// @namespace https://greatest.deepsurf.us/users/1356925
// ==/UserScript==

(function (global) {
    let isRunning = false; // Tracks whether the timer is active
    let speedMultiplier = localStorage.getItem("timerHookerSpeed") || 2.0; // Default speed (2x)
    let autoHideTimeout; // For auto-hide functionality

    // Override timers with speed adjustment
    const overrideTimers = function (factor) {
        ["setTimeout", "setInterval"].forEach((method) => {
            window[method] = ((original) => (fn, time) => {
                // Exclude video-related timers
                const fnString = fn.toString();
                if (fnString.includes("playback") || fnString.includes("video")) {
                    return original(fn, time);
                }
                return original(fn, time / factor);
            })(window[method]);
        });
    };

    const changeTimerSpeed = function (multiplier) {
        speedMultiplier = multiplier;
        localStorage.setItem("timerHookerSpeed", multiplier);
        if (isRunning) overrideTimers(speedMultiplier);
        console.log(`[TimerHooker] Timer speed changed to x${multiplier}`);
    };

    const createUI = function () {
        const style = `
            .timer-ball {
                position: fixed;
                bottom: 20px;
                right: 20px;
                width: 60px;
                height: 60px;
                border-radius: 50%;
                background-color: #4CAF50;
                display: flex;
                justify-content: center;
                align-items: center;
                box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
                cursor: pointer;
                touch-action: manipulation;
                transition: background-color 0.3s ease;
                z-index: 9999; /* Ensure visibility above other elements */
            }
            .timer-ball:hover {
                background-color: #45A049;
            }
            .timer-symbol {
                font-size: 24px;
                color: white;
                font-weight: bold;
            }
            .slider-container {
                position: fixed;
                bottom: 90px;
                right: 20px;
                z-index: 9999; /* Ensure visibility above other elements */
                display: none;
                background: rgba(0, 0, 0, 0.6);
                padding: 10px;
                border-radius: 10px;
                box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.4);
                user-select: none;
            }
            .slider {
                width: 120px;
            }
        `;

        const styleNode = document.createElement('style');
        styleNode.type = 'text/css';
        styleNode.textContent = style;

        // Main ball UI
        const ball = document.createElement('div');
        ball.className = 'timer-ball';
        ball.innerHTML = '<div class="timer-symbol">▶</div>'; // Start symbol

        // Speed adjustment slider
        const sliderContainer = document.createElement('div');
        sliderContainer.className = 'slider-container';

        const slider = document.createElement('input');
        slider.className = 'slider';
        slider.type = 'range';
        slider.min = "1";
        slider.max = "200";
        slider.value = speedMultiplier * 100; // Scale multiplier to slider range
        slider.addEventListener('input', (event) => {
            const newSpeed = event.target.value / 100;
            changeTimerSpeed(newSpeed);
        });

        sliderContainer.appendChild(slider);

        ball.addEventListener('click', () => {
            isRunning = !isRunning;
            ball.querySelector('.timer-symbol').innerHTML = isRunning ? '■' : '▶'; // Toggle Start/Stop symbol
            overrideTimers(isRunning ? speedMultiplier : 1.0);
            sliderContainer.style.display = isRunning ? 'block' : 'none'; // Show/hide slider
            resetAutoHide(); // Reset auto-hide timer
        });

        // Add auto-hide functionality
        const resetAutoHide = function () {
            clearTimeout(autoHideTimeout);
            autoHideTimeout = setTimeout(() => {
                if (isRunning) sliderContainer.style.display = 'none';
            }, 3000);
        };

        document.body.appendChild(ball);
        document.body.appendChild(sliderContainer);
        document.head.appendChild(styleNode);
    };

    const init = function () {
        console.log("[TimerHooker] Unified version activated.");
        createUI();
        overrideTimers(speedMultiplier);
    };

    // Initialize when the DOM is loaded
    if (document.readyState === "complete") {
        init();
    } else {
        window.addEventListener("load", () => init());
    }
})(window);