Greasy Fork is available in English.

Smart ChatGPT Window Optimizer (Chat AI Response Manager)

Automatically collapses long AI responses on ChatGPT to optimize the chat window, featuring quick toggle and content preview.

От 21.11.2025. Виж последната версия.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name         Smart ChatGPT Window Optimizer (Chat AI Response Manager)
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Automatically collapses long AI responses on ChatGPT to optimize the chat window, featuring quick toggle and content preview.
// @author       John
// @match        https://chatgpt.com/*
// @grant        GM_addStyle
// @license      MIT
// @run-at       document-idle
// ==/UserScript==

(function() {
    'use strict';

    const COLLAPSED_CLASS = 'response-container-collapsed';
    const COLLAPSE_HEIGHT = '120px';
    let timeoutHandle = null;
    let initialFoldingComplete = false;

    // (样式注入和 MutationObserver 逻辑保持 V20.0 不变)
// --- 1. 注入基础样式 (V25.0: 恢复渐变和内容上滚) ---
GM_addStyle(`
    div[data-message-author-role="user"] { cursor: pointer !important; }

    /* 核心折叠容器样式 */
    .${COLLAPSED_CLASS} {
        height: ${COLLAPSE_HEIGHT} !important;
        overflow: hidden !important;
        transition: height 0.3s ease-out;
        position: relative !important;
        border-radius: 8px !important; /* 恢复圆角 */
    }

    /* *** 1. 内容上滚:强制内容上移 90px,显示底部内容 *** */
    /* 假设内容包装器是折叠容器的第一个直接子元素 */
    .${COLLAPSED_CLASS} > div:first-child {
        margin-top: -90px !important;
    }

    /* *** 2. 渐变样式:浅蓝色渐变指示 *** */
    .${COLLAPSED_CLASS}:after {
        content: "";
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        height: 20px;
        background: linear-gradient(to top,
            #ADD8E6 5%, /* 浅蓝色 (#ADD8E6) */
            rgba(173, 216, 230, 0.0) 100% /* 透明 */
        );
        border-bottom-left-radius: 8px;
        border-bottom-right-radius: 8px;
        pointer-events: none;
        z-index: 2;
    }

    /* 统一折叠按钮样式 */
    #collapse-all-button {
        position: fixed; bottom: 20px; right: 20px; z-index: 10000;
        background-color: #4285F4; color: white; border: none;
        border-radius: 8px; padding: 10px 15px; font-size: 14px;
        cursor: pointer; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
        transition: background-color 0.2s;
    }
    #collapse-all-button:hover { background-color: #357ae8; }
`);

// --- 2. 核心函数:处理新的/未处理的聊天元素 (V24.0: 精准目标修复) ---
function processNewElements(targetNode) {
    const triggers = targetNode.querySelectorAll('div[data-message-author-role="user"]:not([data-has-listener])');

    triggers.forEach(trigger => {
        trigger.setAttribute('data-has-listener', 'true');

        trigger.addEventListener('click', function(event) {
            event.preventDefault();

            // *** V24.0 修复:严格遵循用户指定的 3 步遍历路径 ***

            // 1. 查找上级 article
            const ancestorArticle = this.closest('article');
            if (!ancestorArticle) return;

            // 2. 查找下一个兄弟元素
            const nextSibling = ancestorArticle.nextElementSibling;
            if (!nextSibling) return;

            // 3. 在兄弟元素中查找目标 article[data-turn="assistant"]
            let targetResponse = nextSibling.querySelector('article[data-turn="assistant"]');

            // 考虑目标就是兄弟元素本身的情况 (如果它自带 data-turn="assistant" 属性)
            if (!targetResponse && nextSibling.matches('article[data-turn="assistant"]')) {
                 targetResponse = nextSibling;
            }
            if (!targetResponse) return; // 目标仍未找到,退出

            // 4. 执行折叠/展开逻辑 (使用 V21.0 的精简展开逻辑)
            if (targetResponse.classList.contains(COLLAPSED_CLASS)) {
                // 展开
                targetResponse.classList.remove(COLLAPSED_CLASS);
                targetResponse.style.height = ''; // 清除内联高度
                targetResponse.style.overflow = 'visible';
            } else {
                // 折叠
                targetResponse.style.height = COLLAPSE_HEIGHT;
                targetResponse.style.overflow = 'hidden';
                targetResponse.classList.add(COLLAPSED_CLASS);
            }
        });

        // --- 新元素保持展开 (5 秒后) ---
        if (initialFoldingComplete) {
            const ancestorArticle = trigger.closest('article');
            if (ancestorArticle) {
                const nextSibling = ancestorArticle.nextElementSibling;
                if (nextSibling) {
                    let targetResponse = nextSibling.querySelector('article[data-turn="assistant"]');
                    if (!targetResponse && nextSibling.matches('article[data-turn="assistant"]')) {
                        targetResponse = nextSibling;
                    }

                    if (targetResponse) {
                        targetResponse.classList.remove(COLLAPSED_CLASS);
                        targetResponse.style.height = '';
                        targetResponse.style.overflow = 'visible';
                    }
                }
            }
        }
    });
}

    // --- (initializeFolding, createCollapseAllButton, MutationObserver 保持 V20.0 逻辑不变) ---

    function initializeFolding() {
        const responses = document.querySelectorAll('article[data-turn="assistant"]');
        responses.forEach(response => {
            response.classList.add(COLLAPSED_CLASS);
            response.style.height = COLLAPSE_HEIGHT;
            response.style.overflow = 'hidden';
        });
        initialFoldingComplete = true;
        createCollapseAllButton();
        console.log("ChatGPT Auto-Collapse: Initial folding completed after delay.");
    }

    function createCollapseAllButton() {
        if (document.getElementById('collapse-all-button')) return;
        const button = document.createElement('button');
        button.id = 'collapse-all-button';
        button.textContent = '折叠全部';
        button.addEventListener('click', function() {
            const allResponses = document.querySelectorAll('article[data-turn="assistant"]');
            allResponses.forEach(response => {
                response.style.height = COLLAPSE_HEIGHT;
                response.style.overflow = 'hidden';
                response.classList.add(COLLAPSED_CLASS);
            });
        });
        document.body.appendChild(button);
    }

    const targetNode = document.body;
    const observer = new MutationObserver(() => {
        if (timeoutHandle) { clearTimeout(timeoutHandle); }
        timeoutHandle = setTimeout(() => {
            processNewElements(document);
            createCollapseAllButton();
            timeoutHandle = null;
        }, 50);
    });

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

    processNewElements(document);
    createCollapseAllButton();

    // 延迟 3 秒后,执行最终强制折叠
    setTimeout(initializeFolding, 3000);

})();