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.

// ==UserScript==
// @name         AI Studio Style Enhancer
// @namespace    http://tampermonkey.net/
// @version      1.5
// @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" !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(.prompt-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
    });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址