Dark Mode Toggle

Enable dark mode with a toggle button

当前为 2025-01-15 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Dark Mode Toggle
// @version      0.0.2
// @description  Enable dark mode with a toggle button
// @namespace    https://greasyfork.org/en/users/28298
// @author       https://greasyfork.org/en/users/28298
// @homepage     https://greasyfork.org/en/scripts/523690
// @license      MIT
// @match        *://*/*
// @grant        GM_getValue
// @grant        GM_setValue
// ==/UserScript==

// @grant        none
// original author: Michael Wang https://greasyfork.org/en/scripts/472251-dark-mode/code
// with help of claude ai

(function() {
    'use strict';

    // Create style element for dark mode
    const darkStyle = document.createElement('style');
    darkStyle.textContent = `
        html {
            filter: invert(1) hue-rotate(180deg) contrast(0.8);
        }
        /** reverse filter for media elements */
        img, video, picture, canvas, iframe, embed {
            filter: invert(1) hue-rotate(180deg);
        }
    `;

    // Initialize based on page's current state
    let darkMode = false; // Start with no filter
    const pageIsDark = document.documentElement.classList.contains('dark');

    // Create toggle button
    const button = document.createElement('button');
    button.innerHTML = pageIsDark ? '☼' : '☽';
    button.style.position = 'fixed';
    button.style.top = '5px';
    button.style.right = '10px';
    button.style.zIndex = '1000';
    button.style.background = 'none';
    button.style.border = 'none';
    button.style.fontSize = '24px';
    button.style.cursor = 'pointer';
    button.style.color = 'inherit';

    // Function to get location and store it
    async function setupLocation() {
        let location = GM_getValue('userLocation');

        if (!location) {
            try {
                const position = await new Promise((resolve, reject) => {
                    navigator.geolocation.getCurrentPosition(resolve, reject);
                });

                location = {
                    latitude: position.coords.latitude,
                    longitude: position.coords.longitude,
                    timestamp: Date.now()
                };

                GM_setValue('userLocation', location);
                console.log('Location saved successfully');
            } catch (error) {
                console.error('Error getting location:', error);
                // Default to a fallback location (e.g., UTC+0)
                location = {
                    latitude: 51.5074,  // London coordinates as fallback
                    longitude: -0.1278,
                    timestamp: Date.now()
                };
                GM_setValue('userLocation', location);
            }
        }
        return location;
    }

    // Function to get sunrise/sunset times using stored location
    async function getSunTimes() {
        try {
            const location = await setupLocation();
            const response = await fetch(
                `https://api.sunrise-sunset.org/json?lat=${location.latitude}&lng=${location.longitude}&formatted=0`
            );
            const data = await response.json();
            return {
                sunrise: new Date(data.results.sunrise),
                sunset: new Date(data.results.sunset)
            };
        } catch (error) {
            console.error('Error getting sun times:', error);
            // Fallback to approximate times
            const now = new Date();
            return {
                sunrise: new Date(now.setHours(6, 0, 0, 0)),
                sunset: new Date(now.setHours(18, 0, 0, 0))
            };
        }
    }

    // Function to toggle dark mode
    function toggleDarkMode(forceDark) {
        darkMode = forceDark ?? !darkMode;
        if (darkMode) {
            document.head.appendChild(darkStyle);
            button.innerHTML = pageIsDark ? '☽' : '☼';
        } else {
            document.head.removeChild(darkStyle);
            button.innerHTML = pageIsDark ? '☼' : '☽';
        }
    }

    // Function to check and update dark mode based on time
    async function updateDarkMode() {
        const sunTimes = await getSunTimes();
        const now = new Date();
        const isDark = now < sunTimes.sunrise || now > sunTimes.sunset;
        toggleDarkMode(isDark);
    }

    // Add settings button
    const settingsButton = document.createElement('button');
    settingsButton.innerHTML = '⚙';
    settingsButton.style.position = 'fixed';
    settingsButton.style.top = '30px';
    settingsButton.style.right = '15px';
    settingsButton.style.zIndex = '1000';
    settingsButton.style.background = 'none';
    settingsButton.style.border = 'none';
    settingsButton.style.fontSize = '12px';
    settingsButton.style.cursor = 'pointer';
    settingsButton.style.color = 'inherit';

    // Settings panel to reset location
    settingsButton.addEventListener('click', () => {
        if (confirm('Reset location settings?')) {
            GM_setValue('userLocation', null);
            location.reload();
        }
    });

    // Initial update
    updateDarkMode();

    // Update every hour
    setInterval(updateDarkMode, 3600000);

    // Manual toggle still works
    button.addEventListener('click', () => toggleDarkMode());

    // Add buttons to page
    document.body.appendChild(button);
    document.body.appendChild(settingsButton);
})();