Fixes UI visibility issues for TimerHooker Unified Version.
当前为
// ==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://greasyfork.org/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);