Greasy Fork

Greasy Fork is available in English.

AI Studio Style Enhancer

Eye-Friendly Styles & Element Control: Enhances Google AI Studio with eye-friendly styles and toggles visibility for user prompts, thinking process, system instructions, and input box. Includes menu controls.

当前为 2025-02-09 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         AI Studio Style Enhancer
// @namespace    http://tampermonkey.net/
// @version      1.4.2
// @description  Eye-Friendly Styles & Element Control: Enhances Google AI Studio with eye-friendly styles and toggles visibility for user prompts, thinking process, system instructions, and input box. Includes menu controls.
// @author       Claude 3.5 Sonnet & Gemini 2.0 Flash Thinking Experimental 01-21
// @match        https://aistudio.google.com/*
// @grant        GM_addStyle
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_registerMenuCommand
// @grant        GM_unregisterMenuCommand
// @license MIT 
// ==/UserScript==

(function() {
    'use strict';

    // Default settings
    const defaultSettings = {
        useCustomStyles: true,
        showUserPrompts: true,
        showThinkingProcess: true,
        showSystemInstructions: true,
        showInputBox: true
    };

    // **Ensure default settings are saved on first run**
    for (const key in defaultSettings) {
        if (GM_getValue(key) === undefined) {
            GM_setValue(key, defaultSettings[key]);
        }
    }

    // Initialize settings
    let settings = {
        useCustomStyles: GM_getValue('useCustomStyles', defaultSettings.useCustomStyles),
        showUserPrompts: GM_getValue('showUserPrompts', defaultSettings.showUserPrompts),
        showThinkingProcess: GM_getValue('showThinkingProcess', defaultSettings.showThinkingProcess),
        showSystemInstructions: GM_getValue('showSystemInstructions', defaultSettings.showSystemInstructions),
        showInputBox: GM_getValue('showInputBox', defaultSettings.showInputBox)
    };

    // Menu Definition (similar to example)
    var menu_ALL = [
        [
            "useCustomStyles",
            "Custom Styles",
        ],
        [
            "showUserPrompts",
            "User Messages Display",
        ],
        [
            "showThinkingProcess",
            "Thinking Process Display",
        ],
        [
            "showSystemInstructions",
            "System Instructions Display",
        ],
        [
            "showInputBox",
            "Input Box Display",
        ],
        [
            "toggleAllDisplays", // Special key for toggle all
            "Toggle All Displays",
        ],
    ];
    var menu_ID = []; // Array to store menu command IDs for unregistering

    // Custom styles (no changes needed here)
    const customStyles = `
        .chunk-editor-main {
            background: #e6e5e0 !important;
            font-size: 2em !important;
        }
        .chunk-editor-main p {
            font-family: "Times New Roman", "思源宋体 CN", 文泉驿等宽微米黑, "FZLanTingKanSongK" !important;
        }
        .user-prompt-container .text-chunk {
            background: #d6d5b7 !important;
        }
        .model-prompt-container {
            background: #f3f2ee !important;
            padding: 15px !important;
            border-radius: 16px !important;
        }
        .model-prompt-container:has(.mat-accordion) {
            background: none !important;
        }
        .turn-footer {
            font-size: 10px !important;
            background: none !important;
        }
        .user-prompt-container p {
            font-size: 15px !important;
            line-height: 1.3 !important;
        }
        .model-prompt-container p {
            font-size: 20px !important;
            line-height: 2 !important;
        }
        .mat-accordion p {
            font-size: 15px !important;
        }
    `;

    const hideUserPromptsStyle = `
        .chat-turn-container:has(.user-prompt-container) {
            display: none !important;
        }
    `;

    const hideThinkingProcessStyle = `
        .chat-turn-container:has(.mat-accordion)  {
            display: none !important;
        }
    `;

    const hideSystemInstructionsStyle = `
        .system-instructions {
            display: none !important;
        }
    `;

    const hideInputBoxStyle = `
        footer:has(.input-wrapper){
            display: none !important;
        }
    `;


    // Function to apply styles based on settings (no changes needed here)
    function updateStyles() {
        // Remove existing style elements
        const existingStyles = document.querySelectorAll('style[data-custom-styles]');
        existingStyles.forEach(style => style.remove());

        // Apply custom styles if enabled
        if (settings.useCustomStyles) {
            const styleElement = document.createElement('style');
            styleElement.setAttribute('data-custom-styles', 'base');
            styleElement.textContent = customStyles;
            document.head.appendChild(styleElement);
        }

        // Apply user prompts visibility style if hidden
        if (!settings.showUserPrompts) {
            const hideUserStyle = document.createElement('style');
            hideUserStyle.setAttribute('data-custom-styles', 'user-visibility');
            hideUserStyle.textContent = hideUserPromptsStyle;
            document.head.appendChild(hideUserStyle);
        }

        // Apply thinking process visibility style if hidden
        if (!settings.showThinkingProcess) {
            const hideThinkingStyle = document.createElement('style');
            hideThinkingStyle.setAttribute('data-custom-styles', 'thinking-visibility');
            hideThinkingStyle.textContent = hideThinkingProcessStyle;
            document.head.appendChild(hideThinkingStyle);
        }

        // Apply system instructions visibility style if hidden
        if (!settings.showSystemInstructions) {
            const hideSystemInstructions = document.createElement('style');
            hideSystemInstructions.setAttribute('data-custom-styles', 'system-instructions-visibility');
            hideSystemInstructions.textContent = hideSystemInstructionsStyle;
            document.head.appendChild(hideSystemInstructions);
        }

        // Apply input box visibility style if hidden
        if (!settings.showInputBox) {
            const hideInputBox = document.createElement('style');
            hideInputBox.setAttribute('data-custom-styles', 'input-box-visibility');
            hideInputBox.textContent = hideInputBoxStyle;
            document.head.appendChild(hideInputBox);
        }
    }

    // Function to show a floating notification (no changes needed here)
    function showNotification(message) {
        const notification = document.createElement('div');
        notification.textContent = message;
        notification.style.cssText = `
            position: fixed;
            top: 20px;
            left: 50%;
            transform: translateX(-50%);
            background-color: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 10px 20px;
            border-radius: 5px;
            z-index: 9999; /* Make sure it's on top */
            opacity: 1;
            transition: opacity 1s ease-in-out;
        `;
        document.body.appendChild(notification);

        // Fade out and remove after 1 second
        setTimeout(() => {
            notification.style.opacity = '0';
            setTimeout(() => {
                if (notification.parentNode) {
                    notification.parentNode.removeChild(notification);
                }
            }, 1000); // Wait for fade out transition to complete (1s)
        }, 1000); // Show for 1 second
    }


    // Register script menus
    function registerMenuCommand() {
        console.log("[AI Studio Enhancer] - registerMenuCommand, menu_ALL : ", menu_ALL);
        for (let i = 0; i < menu_ID.length; i++) {
            GM_unregisterMenuCommand(menu_ID[i]); // Unregister previous commands
        }
        menu_ID = []; // Clear the menu_ID array

        for (let i = 0; i < menu_ALL.length; i++) {
            const localStorageKeyName = menu_ALL[i][0];
            const baseMenuText = menu_ALL[i][1];

            if (localStorageKeyName === "toggleAllDisplays") {
                // Handle "Toggle All Displays" menu text specifically
                const displaySettingsKeys = ["showUserPrompts", "showThinkingProcess", "showSystemInstructions", "showInputBox"];
                // Determine current "all displays" state based on the first setting (e.g., showUserPrompts)
                const currentAllDisplaysState = settings[displaySettingsKeys[0]];
                // Corrected menu text:
                const menuText = `${currentAllDisplaysState ? "🔴 Disable All Displays" : "🟢 Enable All Displays"}`;
                menu_ID.push(GM_registerMenuCommand(
                    menuText,
                    function () {
                        toggleAllDisplays(); // Call toggleAllDisplays function
                    }
                ));
            } else {
                const currentSettingValue = GM_getValue(localStorageKeyName, defaultSettings[localStorageKeyName]); // Get current setting
                const menuText = `${currentSettingValue ? "🔴 Disable" : "🟢 Enable"} ${baseMenuText}`; // Dynamic menu text
                menu_ID.push(GM_registerMenuCommand(
                    menuText,
                    function () {
                        menuSwitch(localStorageKeyName); // Call menuSwitch with the key
                    }
                ));
            }
        }
    }


    //切换单个选项
    function menuSwitch(localStorageKeyName) {
        let currentValue = GM_getValue(localStorageKeyName);
        let newValue = !currentValue; // Toggle the boolean value

        settings[localStorageKeyName] = newValue; // Update settings object
        GM_setValue(localStorageKeyName, newValue); // Save to GM_setValue

        updateStyles(); // Apply style changes
        registerMenuCommand(); // Re-register menus to update text and emoji

        const baseMenuText = menu_ALL.find(item => item[0] === localStorageKeyName)[1]; // Find base text for notification
        showNotification(`${baseMenuText} ${newValue ? 'Enabled' : 'Disabled'}`); // Show notification
    }

    // 切换全部显示项
    function toggleAllDisplays() {
        const displaySettingsKeys = ["showUserPrompts", "showThinkingProcess", "showSystemInstructions", "showInputBox"];
        // Determine the new state - if any is enabled, disable all, otherwise enable all
        const enableAll = !settings[displaySettingsKeys[0]]; // Toggle based on the first setting

        displaySettingsKeys.forEach(key => {
            settings[key] = enableAll;
            GM_setValue(key, enableAll);
        });

        updateStyles();
        registerMenuCommand(); // Update menus to reflect new states

        showNotification(`All Displays ${enableAll ? 'Enabled' : 'Disabled'}`);
    }


    // Initial style application
    updateStyles();
    // Initial menu command registration
    registerMenuCommand();


    // Watch for dynamic content changes (no changes needed here, but keep it)
    const observer = new MutationObserver(() => {
        updateStyles();
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
})();