AI对话宽度调整 | AI Chat Width Controller

Add draggable width control slider for AI chat websites

// ==UserScript==
// @name         AI对话宽度调整 | AI Chat Width Controller
// @namespace    http://tampermonkey.net/
// @version      0.0.2
// @description  Add draggable width control slider for AI chat websites
// @match        https://chatglm.cn/*
// @match        https://kimi.moonshot.cn/*
// @match        https://chat.deepseek.com/*
// @match        https://tongyi.aliyun.com/*
// @match        https://www.tiangong.cn/*
// @match        https://gemini.google.com/*
// @match        *://*.dawuai.de/c/*
// @match        *://*.dwai.work/c/*
// @match        *://*.dawuai.buzz/c/*
// @match        *://*.dwaiai.de/c/*
// @match        *://*.dwai.world/c/*
// @match        https://chatgpt.com/c/*
// @match        https://*.claudesvip.top/chat/*
// @match        https://*.claude.ai/chat/*
// @match        https://*.fuclaude.com/chat/*
// @match        https://*.aikeji.vip/chat/*
// @match        https://www.doubao.com/*
// @match        https://copilot.microsoft.com/chats/*
// @license      Custom License
// @grant        GM_addStyle
// ==/UserScript==

/*
 您可以在个人设备上使用和修改该代码。
 不得将该代码或其修改版本重新分发、再发布或用于其他公众渠道。
 保留所有权利,未经授权不得用于商业用途。
*/

/*
You may use and modify this code on your personal devices.
You may not redistribute, republish, or use this code or its modified versions in other public channels.
All rights reserved. Unauthorized commercial use is prohibited.
*/

(function () {
    'use strict';

    function addCustomStyle(css) {
        const style = document.createElement('style');
        style.textContent = css;
        document.head.appendChild(style);
    }

    const widthControlDiv = document.createElement('div');
    widthControlDiv.id = 'width-control';
    widthControlDiv.innerHTML = `
        <input type="range" id="width-slider" min="33" max="100" value="67">
        <span id="width-value">67%</span>
    `;
    widthControlDiv.style.position = 'fixed';
    widthControlDiv.style.right = '20px';
    widthControlDiv.style.top = '20px';
    widthControlDiv.style.zIndex = '9999';
    widthControlDiv.style.background = '#f0f0f0';
    widthControlDiv.style.padding = '10px';
    widthControlDiv.style.borderRadius = '5px';
    widthControlDiv.style.boxShadow = '0 2px 5px rgba(0,0,0,0.2)';
    widthControlDiv.style.cursor ='move';
    widthControlDiv.style.userSelect = 'none';

    document.body.appendChild(widthControlDiv);

    let isDragging = false;
    let currentX = 0, currentY = 0, initialX, initialY;

    widthControlDiv.addEventListener('mousedown', initiateDrag);
    document.addEventListener('mousemove', carryOutDrag);
    document.addEventListener('mouseup', concludeDrag);

    function initiateDrag(e) {
        if (e.target === document.getElementById('width-slider')) return;
        initialX = e.clientX - currentX;
        initialY = e.clientY - currentY;
        isDragging = true;
    }

    function carryOutDrag(e) {
        if (!isDragging) return;
        e.preventDefault();
        currentX = e.clientX - initialX;
        currentY = e.clientY - initialY;
        applyPositionChange(currentX, currentY, widthControlDiv);
    }

    function concludeDrag() {
        isDragging = false;
    }

    function applyPositionChange(xPos, yPos, element) {
        element.style.transform = `translate(${xPos}px, ${yPos}px)`;
    }

    const widthSlider = document.getElementById('width-slider');
    const widthValueDisplay = document.getElementById('width-value');

    widthSlider.addEventListener('input', function () {
        const width = this.value;
        widthValueDisplay.textContent = width + '%';
        const vwWidth = width + 'vw';

        if (/kimi.moonshot.cn/.test(location.href)) {
            addCustomStyle(`
                div[data-testid] div[data-index] div.MuiBox-root { max-width: ${vwWidth}!important; }
                div[class^=mainContent] div.MuiBox-root > div[class^=chatBottom_] { max-width: ${vwWidth}!important; }
            `);
        } else if (/doubao.com/.test(location.href)) {
            addCustomStyle(`
                div.container-rBgb6B.chrome70-container {
                    padding-left: 0!important;
                    padding-right: 0!important;
                    width: 100vw!important; /* 尝试将宽度设置为视窗宽度 */
                    display: flex;
                    justify-content: center;
                }
                div.inner-LOKNYu.inner-item-AQrr_W {
                    max-width: ${vwWidth}!important;
                    margin: 0 auto;
                }
            `);
        } else if (/chat.deepseek.com/.test(location.href)) {
            addCustomStyle(`
                div:has(> #latest-context-divider) { width: ${vwWidth}!important; }
                div:has(> div > #chat-input) { width: ${vwWidth}!important; }
            `);
        } else if (/tongyi.aliyun.com/.test(location.href)) {
            addCustomStyle(`
                div[class^=mainContent] div[class^=questionItem--] { width: ${vwWidth}!important; }
                div[class^=mainContent] div[class^=answerItem--] { width: ${vwWidth}!important; }
            `);
        } else if (/www.tiangong.cn/.test(location.href)) {
            addCustomStyle(`
                #app > div > div > main > div.overflow-y-scroll.w-full > div.search-content { max-width: ${vwWidth}!important; }
            `);
        } else if (/chatglm.cn/.test(location.href)) {
            addCustomStyle(`
                div.conversation-inner.dialogue > div.conversation-list.detail > div.item.conversation-item { max-width: ${vwWidth}!important; }
             .markdown-body.md-body { max-width: ${vwWidth}!important; }
            `);
        } else if (/gemini.google.com/.test(location.href)) {
            addCustomStyle(`
                #chat-history > infinite-scroller > div { max-width: ${vwWidth}!important; }
                #app-root main div.bottom-container { max-width: ${vwWidth}!important; }
            `);
        } else if (/chat.openai.com/.test(location.href) || /claude.ai/.test(location.href) || /gemini.google.com/.test(location.href)) {
            addCustomStyle(`
             .xl\\:max-w-\\[48rem\\] { width: ${vwWidth}!important; }
                div.mx-auto.md\\:max-w-3xl { max-width: ${vwWidth}!important; }
                div.mx-auto.flex { max-width: ${vwWidth}!important; }
            `);
        } else {
            addCustomStyle(`
             .xl\\:max-w-\\[48rem\\] { width: ${vwWidth}!important; }
                div.mx-auto.md\\:max-w-3xl { max-width: ${vwWidth}!important; }
                div.mx-auto.flex { max-width: ${vwWidth}!important; }
            `);
        }
    });

    // 手动触发一次input事件
    widthSlider.dispatchEvent(new Event('input'));

    function ensureWidthControl() {
        if (!document.getElementById('width-control')) {
            document.body.appendChild(widthControlDiv);
        }
    }

    const chatGPTMirrors = ['https://chat.openai.com/*', 'https://*.dawuai.de/c/*', 'https://*.dwai.work/c/*', 'https://*.dawuai.buzz/c/*', 'https://*.dwaiai.de/c/*', 'https://*.dwai.world/c/*'];
    const claudeMirrors = ['https://claude.ai/*'];
    const geminiMirrors = ['https://gemini.google.com/*'];

    const allMirrors = [...chatGPTMirrors,...claudeMirrors,...geminiMirrors];

    allMirrors.forEach(mirror => {
        if (new RegExp(mirror).test(location.href)) {
            const observer = new MutationObserver(ensureWidthControl);
            observer.observe(document.body, {
                childList: true,
                subtree: true
            });

            setInterval(ensureWidthControl, 1000);
        }
    });
})();