- // ==UserScript==
- // @name Komica 定時功能與鎖定畫面
- // @namespace http://komica.org
- // @version 1.0
- // @description 提供懸浮計時功能,並在超時後鎖定畫面提示休息。
- // @author Yun
- // @match https://gita.komica1.org/*
- // @icon https://i.ibb.co/bscXhHh/icon.png
- // @license GNU GPLv3
- // ==/UserScript==
-
- (function() {
- 'use strict';
-
- // 插入CSS樣式
- const style = document.createElement('style');
- style.textContent = `
- @keyframes fadeIn {
- from { opacity: 0; }
- to { opacity: 1; }
- }
- @keyframes fadeOut {
- from { opacity: 1; }
- to { opacity: 0; }
- }
- .fade-in {
- animation: fadeIn 0.5s ease-in-out forwards;
- }
- .fade-out {
- animation: fadeOut 0.5s ease-in-out forwards;
- }
- .timer-button {
- width: 24px;
- height: 24px;
- background: rgba(68, 68, 68, 0.5);
- border: none;
- border-radius: 50%;
- color: #fff;
- font-size: 12px;
- cursor: pointer;
- display: flex;
- align-items: center;
- justify-content: center;
- margin-left: 4px;
- transition: background 0.3s ease;
- }
- .timer-button:hover {
- background: rgba(85, 85, 85, 0.7);
- }
- `;
- document.head.appendChild(style);
-
- // 計時相關變數
- const TIMER_KEY = 'komica-timer-seconds';
- const WARNING_INDEX_KEY = 'komica-warning-index';
- const LOCK_STATE_KEY = 'komica-lock-state';
- const INITIAL_TIME = 600; // 10分鐘 = 600秒
- let seconds = parseInt(localStorage.getItem(TIMER_KEY), 10) || INITIAL_TIME;
- let timerInterval = null;
- let isPaused = false;
-
- // 插入懸浮計時器
- const container = document.createElement('div');
- Object.assign(container.style, {
- position: 'fixed',
- top: '40px',
- right: '10px',
- display: 'flex',
- flexDirection: 'row',
- alignItems: 'center',
- background: 'rgba(30, 30, 30, 0.4)',
- padding: '6px 10px',
- borderRadius: '8px',
- boxShadow: '0 2px 6px rgba(0, 0, 0, 0.2)',
- zIndex: '10000',
- color: '#ffffff',
- fontFamily: 'Arial, sans-serif',
- fontSize: '12px',
- backdropFilter: 'blur(5px)'
- });
-
- const timerDiv = document.createElement('div');
- timerDiv.id = 'komica-timer';
- Object.assign(timerDiv.style, {
- fontWeight: 'bold',
- marginRight: '6px'
- });
-
- // 更新計時器顯示
- const updateTimerDisplay = () => {
- const minutes = Math.floor(seconds / 60).toString().padStart(2, '0');
- const secs = (seconds % 60).toString().padStart(2, '0');
- timerDiv.textContent = `${minutes}:${secs}`;
- };
-
- // 計時器核心邏輯
- const tick = () => {
- if (seconds <= 0) {
- clearInterval(timerInterval);
- triggerSiteblock();
- return;
- }
- seconds--;
- localStorage.setItem(TIMER_KEY, seconds);
- updateTimerDisplay();
- };
-
- const startTimer = () => {
- if (timerInterval) clearInterval(timerInterval);
- timerInterval = setInterval(tick, 1000);
- };
-
- const stopTimer = () => {
- if (timerInterval) {
- clearInterval(timerInterval);
- timerInterval = null;
- }
- };
-
- // 重置按鈕
- const resetButton = document.createElement('button');
- resetButton.innerHTML = '⟳';
- resetButton.className = 'timer-button';
- resetButton.title = '重置你無謂的人生';
-
- // 播放/暫停按鈕
- const playPauseButton = document.createElement('button');
- playPauseButton.innerHTML = '⏸︎';
- playPauseButton.className = 'timer-button';
- playPauseButton.title = '暫停你的墮落時光';
-
- resetButton.addEventListener('click', () => {
- if (confirm('真的要重置?反正你的人生也就這樣了!')) {
- seconds = INITIAL_TIME;
- localStorage.setItem(TIMER_KEY, seconds);
- updateTimerDisplay();
- if (!isPaused) {
- startTimer();
- }
- }
- });
-
- playPauseButton.addEventListener('click', () => {
- isPaused = !isPaused;
- if (isPaused) {
- playPauseButton.innerHTML = '▶︎';
- playPauseButton.title = '繼續你可悲的瀏覽';
- stopTimer();
- } else {
- playPauseButton.innerHTML = '⏸︎';
- playPauseButton.title = '暫停你的墮落時光';
- startTimer();
- }
- });
-
- container.appendChild(timerDiv);
- container.appendChild(playPauseButton);
- container.appendChild(resetButton);
- document.body.appendChild(container);
-
- // 警告訊息
- const warningMessages = [
- '哈!又在這裡浪費生命?真有你的!',
- '媽媽知道你在這邊當廢物嗎?',
- '看來你是打算繼續當個魯蛇了?',
- '這就是你的人生價值?在這裡虛度光陰?',
- '你以為躲在這裡就能逃避現實?',
- '真替你感到可悲,繼續宅下去吧!',
- '又在這裡當個失敗者了?',
- '外面的世界很可怕?還是你太廢了?',
- '這就是你的極限了?真可憐!',
- '看來你是打算一輩子當個廢物了!'
- ];
-
- const getNextWarning = () => {
- let currentIndex = parseInt(localStorage.getItem(WARNING_INDEX_KEY), 10) || 0;
- const warning = warningMessages[currentIndex];
- currentIndex = (currentIndex + 1) % warningMessages.length;
- localStorage.setItem(WARNING_INDEX_KEY, currentIndex);
- return warning;
- };
-
- // 鎖定畫面處理
- const triggerSiteblock = () => {
- localStorage.setItem(LOCK_STATE_KEY, 'locked');
- stopTimer();
-
- const oldOverlay = document.getElementById('komica-siteblock');
- if (oldOverlay) {
- oldOverlay.remove();
- }
-
- const overlay = document.createElement('div');
- overlay.id = 'komica-siteblock';
- overlay.classList.add('fade-in');
-
- Object.assign(overlay.style, {
- position: 'fixed',
- top: '0',
- left: '0',
- width: '100%',
- height: '100%',
- background: 'rgba(0, 0, 0, 0.85)',
- backdropFilter: 'blur(12px)',
- display: 'flex',
- flexDirection: 'column',
- alignItems: 'center',
- justifyContent: 'center',
- color: '#ffffff',
- zIndex: '10001',
- fontFamily: 'Arial, sans-serif'
- });
-
- const warningText = document.createElement('div');
- warningText.textContent = getNextWarning();
- Object.assign(warningText.style, {
- fontSize: '24px',
- fontWeight: 'bold',
- marginBottom: '20px',
- textAlign: 'center',
- padding: '0 20px'
- });
-
- const unlockButton = document.createElement('button');
- Object.assign(unlockButton.style, {
- padding: '12px 24px',
- fontSize: '18px',
- background: '#ffffff',
- color: '#000000',
- border: 'none',
- borderRadius: '8px',
- cursor: 'pointer',
- fontWeight: 'bold',
- position: 'relative',
- overflow: 'hidden'
- });
-
- const progressIndicator = document.createElement('div');
- Object.assign(progressIndicator.style, {
- position: 'absolute',
- top: '0',
- left: '0',
- height: '100%',
- width: '0%',
- background: 'rgba(0, 128, 0, 0.5)',
- borderRadius: '8px',
- zIndex: '1',
- transition: 'width 0.1s linear'
- });
-
- const buttonText = document.createElement('span');
- buttonText.textContent = '堅持要繼續浪費生命?按住 5 秒!';
- Object.assign(buttonText.style, {
- position: 'relative',
- zIndex: '2'
- });
-
- unlockButton.appendChild(progressIndicator);
- unlockButton.appendChild(buttonText);
-
- let pressStartTime = 0;
- let isPressed = false;
- let progressInterval;
-
- const startUnlockProcess = () => {
- isPressed = true;
- pressStartTime = Date.now();
- progressInterval = setInterval(() => {
- if (!isPressed) return;
- const progress = Math.min((Date.now() - pressStartTime) / 5000 * 100, 100);
- progressIndicator.style.width = `${progress}%`;
-
- if (progress >= 100) {
- clearInterval(progressInterval);
- overlay.classList.add('fade-out');
- setTimeout(() => {
- overlay.remove();
- localStorage.removeItem(LOCK_STATE_KEY);
- seconds = INITIAL_TIME;
- localStorage.setItem(TIMER_KEY, seconds);
- updateTimerDisplay();
- if (!isPaused) {
- startTimer();
- }
- }, 500);
- }
- }, 100);
- };
-
- const stopUnlockProcess = () => {
- isPressed = false;
- clearInterval(progressInterval);
- progressIndicator.style.width = '0%';
- };
-
- unlockButton.addEventListener('mousedown', startUnlockProcess);
- unlockButton.addEventListener('mouseup', stopUnlockProcess);
- unlockButton.addEventListener('mouseleave', stopUnlockProcess);
- unlockButton.addEventListener('touchstart', startUnlockProcess);
- unlockButton.addEventListener('touchend', stopUnlockProcess);
-
- overlay.appendChild(warningText);
- overlay.appendChild(unlockButton);
- document.body.appendChild(overlay);
- };
-
- // 初始化
- updateTimerDisplay();
- if (localStorage.getItem(LOCK_STATE_KEY) === 'locked') {
- triggerSiteblock();
- } else {
- startTimer();
- }
- })();