Access Control For Maintaining Mindfulness

Allow website access only during specified hours with beautiful config panel

目前為 2024-11-06 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Access Control For Maintaining Mindfulness
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  Allow website access only during specified hours with beautiful config panel
// @author       KQ yang
// @match        *://*/*
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // Default configuration
    const DEFAULT_CONFIG = {
        startHour: 12,
        endHour: 14,
        restrictedSites: {},
        messageStyle: "background-color: white; margin-top: 20vh; margin-left: 100px; margin-right: 100px; font-size:64px"
    };

    // Load configuration from localStorage
    let CONFIG = JSON.parse(localStorage.getItem('mindfulnessConfig')) || DEFAULT_CONFIG;

    // 添加样式
    function addStyles() {
        const styleSheet = document.createElement("style");
        styleSheet.textContent = `
            .mindfulness-panel {
                position: fixed;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                background: white;
                padding: 30px;
                border-radius: 12px;
                box-shadow: 0 10px 25px rgba(0,0,0,0.2);
                z-index: 999999;
                min-width: 380px;
                font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
            }

            .mindfulness-panel h2 {
                margin: 0 0 25px 0;
                color: #2c3e50;
                font-size: 24px;
                text-align: center;
                font-weight: 600;
            }

            .mindfulness-panel .setting-group {
                margin-bottom: 20px;
                padding: 15px;
                background: #f8f9fa;
                border-radius: 8px;
            }

            .mindfulness-panel .setting-item {
                margin-bottom: 15px;
            }

            .mindfulness-panel label {
                display: block;
                margin-bottom: 8px;
                color: #495057;
                font-weight: 500;
            }

            .mindfulness-panel input[type="number"] {
                width: 70px;
                padding: 8px;
                border: 2px solid #e9ecef;
                border-radius: 6px;
                font-size: 14px;
                transition: border-color 0.2s;
            }

            .mindfulness-panel input[type="number"]:focus {
                outline: none;
                border-color: #4dabf7;
            }

            .mindfulness-panel .toggle-switch {
                position: relative;
                display: inline-block;
                width: 60px;
                height: 34px;
            }

            .mindfulness-panel .toggle-switch input {
                opacity: 0;
                width: 0;
                height: 0;
            }

            .mindfulness-panel .toggle-slider {
                position: absolute;
                cursor: pointer;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background-color: #ccc;
                transition: .4s;
                border-radius: 34px;
            }

            .mindfulness-panel .toggle-slider:before {
                position: absolute;
                content: "";
                height: 26px;
                width: 26px;
                left: 4px;
                bottom: 4px;
                background-color: white;
                transition: .4s;
                border-radius: 50%;
            }

            .mindfulness-panel input:checked + .toggle-slider {
                background-color: #2196F3;
            }

            .mindfulness-panel input:checked + .toggle-slider:before {
                transform: translateX(26px);
            }

            .mindfulness-panel .button-group {
                display: flex;
                justify-content: center;
                gap: 15px;
                margin-top: 25px;
            }

            .mindfulness-panel button {
                padding: 10px 20px;
                border: none;
                border-radius: 6px;
                font-size: 14px;
                font-weight: 500;
                cursor: pointer;
                transition: all 0.2s;
            }

            .mindfulness-panel button.save {
                background-color: #228be6;
                color: white;
            }

            .mindfulness-panel button.save:hover {
                background-color: #1c7ed6;
            }

            .mindfulness-panel button.cancel {
                background-color: #e9ecef;
                color: #495057;
            }

            .mindfulness-panel button.cancel:hover {
                background-color: #dee2e6;
            }

            .mindfulness-panel .site-info {
                color: #868e96;
                font-size: 14px;
                text-align: center;
                margin-bottom: 20px;
            }

            .mindfulness-panel .time-inputs {
                display: flex;
                gap: 20px;
                justify-content: center;
            }

            .mindfulness-panel .status-label {
                margin-left: 10px;
                font-size: 14px;
                color: #495057;
            }
        `;
        document.head.appendChild(styleSheet);
    }

    // 创建配置面板
    function createConfigPanel() {
        const panel = document.createElement('div');
        panel.className = 'mindfulness-panel';
        
        const currentHost = window.location.hostname;
        const isRestricted = CONFIG.restrictedSites[currentHost];

        panel.innerHTML = `
            <h2>Mindfulness Settings</h2>
            
            <div class="site-info">
                Current Site: ${currentHost}
            </div>

            <div class="setting-group">
                <div class="setting-item">
                    <label class="toggle-switch">
                        <input type="checkbox" id="restrictSite" ${isRestricted ? 'checked' : ''}>
                        <span class="toggle-slider"></span>
                    </label>
                    <span class="status-label">
                        ${isRestricted ? 'Site is restricted' : 'Site is not restricted'}
                    </span>
                </div>

                <div class="setting-item">
                    <label>Access Time Range</label>
                    <div class="time-inputs">
                        <div>
                            <label>Start</label>
                            <input type="number" id="startHour" value="${CONFIG.startHour}" min="0" max="23">
                        </div>
                        <div>
                            <label>End</label>
                            <input type="number" id="endHour" value="${CONFIG.endHour}" min="0" max="23">
                        </div>
                    </div>
                </div>
            </div>

            <div class="button-group">
                <button class="save" id="saveConfig">Save Changes</button>
                <button class="cancel" id="cancelConfig">Cancel</button>
            </div>
        `;

        // 添加事件监听器
        panel.querySelector('#restrictSite').addEventListener('change', function(e) {
            const statusLabel = panel.querySelector('.status-label');
            statusLabel.textContent = e.target.checked ? 'Site is restricted' : 'Site is not restricted';
        });

        panel.querySelector('#saveConfig').addEventListener('click', saveConfiguration);
        panel.querySelector('#cancelConfig').addEventListener('click', () => panel.remove());

        document.body.appendChild(panel);
    }

    // 保存配置
    function saveConfiguration() {
        const panel = document.querySelector('.mindfulness-panel');
        const currentHost = window.location.hostname;
        
        const newStartHour = parseInt(panel.querySelector('#startHour').value) || 12;
        const newEndHour = parseInt(panel.querySelector('#endHour').value) || 14;
        const newIsRestricted = panel.querySelector('#restrictSite').checked;

        // 保存新配置
        CONFIG.startHour = newStartHour;
        CONFIG.endHour = newEndHour;
        
        if (newIsRestricted) {
            CONFIG.restrictedSites[currentHost] = true;
        } else {
            delete CONFIG.restrictedSites[currentHost];
        }

        // 保存到 localStorage
        localStorage.setItem('mindfulnessConfig', JSON.stringify(CONFIG));
        
        // 关闭面板
        panel.remove();
        
        // 如果网站现在是不受限的,刷新页面恢复访问
        if (!newIsRestricted && wasPreviouslyBlocked()) {
            window.location.reload();
        } else {
            // 检查并应用新的限制
            checkAndApplyRestriction();
        }
    }

    // 检查页面是否之前被阻止
    function wasPreviouslyBlocked() {
        const currentContent = document.body.innerHTML;
        return currentContent.includes("Dear Me!") && 
               currentContent.includes("You preserved this page") &&
               currentContent.includes("maintained mindfulness");
    }

    // 检查并应用访问限制
    function checkAndApplyRestriction() {
        const currentHost = window.location.hostname;
        
        // 如果当前网站不在限制列表中,直接返回
        if (!CONFIG.restrictedSites[currentHost]) {
            return;
        }

        const now = new Date();
        const hours = now.getHours();
        const minutes = now.getMinutes();

        // 检查是否在允许的时间范围内
        if (hours < CONFIG.startHour || (hours >= CONFIG.endHour && minutes > 0)) {
            // 如果在限制时间内,替换页面内容
            document.body.innerHTML = `
                <h1 style="${CONFIG.messageStyle}">
                    Dear Me!<br>
                    You preserved this page 👍<br><br>
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;👏 Congratulations! You successfully maintained mindfulness! Well done!👏<br><br>
                    This is restricted time.<br>
                    Welcome back between ${CONFIG.startHour}:00 and ${CONFIG.endHour}:00.
                </h1>`;
        }
    }

    // 添加快捷键监听器
    document.addEventListener('keydown', function(e) {
        if (e.ctrlKey && (e.key === 's' || e.key === 'S')) {
            e.preventDefault();
            createConfigPanel();
        }
    });

    // 初始化
    addStyles();
    checkAndApplyRestriction();
})();