Xoul AI Chat Unified Styler

Unified script for chat element color, transparency, blur effects, text styling.

Cài đặt script này?
Script được tác giả gợi ý

Bạn có thế thích Xoul AI Background Manager

Cài đặt script này
// ==UserScript==
// @name        Xoul AI Chat Unified Styler
// @namespace   CXoul AI Chat Unified Styler
// @match       https://xoul.ai/*
// @grant       none
// @license     MIT
// @version     1.1
// @description Unified script for chat element color, transparency, blur effects, text styling.
// @icon        https://i.imgur.com/REqi6Iw.png
// ==/UserScript==

(function() {
    'use strict';

    // Default customization values
    let savedColor = JSON.parse(localStorage.getItem('chatBubbleColor')) || { r: 0, g: 0, b: 255, a: 0.5 };
    let savedBlur = parseFloat(localStorage.getItem('chatBubbleBlur')) || 5; // Default blur intensity
    let savedFont = localStorage.getItem('chatBubbleFont') || 'Comic Sans MS, Comic Sans, cursive'; // Default font
    let savedTextSize = localStorage.getItem('chatBubbleTextSize') || '16px'; // Default text size
    let savedItalicColor = localStorage.getItem('italicTextColor') || 'green'; // Italic text color
    let savedQuoteColor = localStorage.getItem('quoteTextColor') || 'pink'; // Quoted text color
    let savedPlainTextColor = localStorage.getItem('plainTextColor') || 'black'; // Plain text color

    // Add custom styles for chat bubbles and text
    function addCustomStyles() {
        const existingStyle = document.getElementById('tampermonkey-style-overrides');
        if (existingStyle) {
            existingStyle.remove(); // Remove old styles to apply new updates
        }

        const customStyle = document.createElement('style');
        customStyle.id = 'tampermonkey-style-overrides';
        customStyle.textContent = `
            /* Override for left chat bubbles background color */
            body[data-theme="dark"] .ChatBubble_left__ZhCrR .ChatBubble_bubble__Zsfxg {
                background-color: rgba(${savedColor.r}, ${savedColor.g}, ${savedColor.b}, ${savedColor.a}) !important;
                backdrop-filter: blur(${savedBlur}px) !important;
            }

            /* Override for right chat bubbles background color */
            body[data-theme="dark"] .ChatBubble_right__58fYr .ChatBubble_bubble__Zsfxg {
                background-color: rgba(${savedColor.r}, ${savedColor.g}, ${savedColor.b}, ${savedColor.a}) !important;
                backdrop-filter: blur(${savedBlur}px) !important;
            }

            /* Override text styles */
            body[data-theme="dark"] .ChatBubble_messagecontainer__2PUrv {
                font-family: ${savedFont} !important;
                font-size: ${savedTextSize} !important;
                color: ${savedPlainTextColor} !important;
            }

            /* Override text styles in editing bubbles*/
            body[data-theme="dark"] .ChatBubble_bubble--editing___Go70 {
                font-family: ${savedFont} !important;
                font-size: ${savedTextSize} !important;
                color: ${savedPlainTextColor} !important;
            }

            /* Italic text color */
            body[data-theme="dark"] .ChatBubble_messagecontainer__2PUrv i {
                color: ${savedItalicColor} !important;
            }

            /* Quoted text color */
            body[data-theme="dark"] .ChatBubble_messagecontainer__2PUrv span {
                color: ${savedQuoteColor} !important;
            }

            /* Override for left chat bubbles (message border) */
            .ChatBubble_left__ZhCrR body[data-theme="dark"] .ChatBubble_bubble__Zsfxg::before,
            body[data-theme="dark"] .ChatBubble_focused_message_bot__PHyy1::before,
            body[data-theme="dark"] .ChatBubble_left__ZhCrR .ChatBubble_bubble__Zsfxg::before {
                border-right: none !important;
            }

            /* Override for right chat bubbles (message border) */
            .ChatBubble_right__58fYr body[data-theme="dark"] .ChatBubble_bubble__Zsfxg::before,
            body[data-theme="dark"] .ChatBubble_focused_message_user__Hd6Zk::before,
            body[data-theme="dark"] .ChatBubble_right__58fYr .ChatBubble_bubble__Zsfxg::before {
                border-left: none !important;
            }
        `;
        document.head.appendChild(customStyle);
    }

    // Create the control panel with customization options
    function createControlPanel() {
        const panel = document.createElement('div');
        panel.style.position = 'fixed';
        panel.style.top = '50%';
        panel.style.left = '50%';
        panel.style.transform = 'translate(-50%, -50%)';
        panel.style.padding = '20px';
        panel.style.backgroundColor = 'rgb(10, 10, 10)';
        panel.style.color = 'white';
        panel.style.borderRadius = '8px';
        panel.style.zIndex = '9999';
        panel.style.boxShadow = '0 4px 8px rgba(0, 0, 0, 0.5)';
        panel.style.display = 'none'; // Initially hidden
        // Add this section after creating the panel
document.addEventListener('click', function(e) {
    // Check if the click is outside the control panel and the toggle button
    if (!panel.contains(e.target) && !sidebarButton.contains(e.target)) {
        panel.style.display = 'none'; // Hide the panel
    }
});


        // Add button to the sidebar
        const sidebarButton = document.createElement('button');
        sidebarButton.textContent = 'Tt';
        sidebarButton.style.margin = '10px';
        sidebarButton.style.backgroundColor = 'transparent'; // Transparent background
        sidebarButton.style.border = 'none'; // No border
        sidebarButton.style.color = 'white'; // Text color
        sidebarButton.style.cursor = 'pointer'; // Pointer cursor for better UX
        sidebarButton.style.fontSize = '16px'; // Adjust font size as needed
        sidebarButton.style.fontWeight = 'bold'; // Optional for emphasis
        sidebarButton.addEventListener('click', () => {
            panel.style.display = panel.style.display === 'none' ? 'block' : 'none'; // Toggle the panel visibility
        });

        // Locate the Sidebar container and append the button
        const sidebarNav = document.querySelector('.Sidebar_nav__a5780');
        if (sidebarNav) {
            const sidebarLink = sidebarNav.querySelector('a.Sidebar_link__0EvG_:nth-child(6)');
            if (sidebarLink) {
                sidebarLink.after(sidebarButton); // Add button underneath the target link
            }
        }

        // RGB input field
        const rgbInput = document.createElement('input');
        rgbInput.type = 'color';
        rgbInput.value = rgbToHex(savedColor.r, savedColor.g, savedColor.b);
        rgbInput.addEventListener('input', function() {
            const rgb = hexToRgb(rgbInput.value);
            savedColor.r = rgb.r;
            savedColor.g = rgb.g;
            savedColor.b = rgb.b;
            localStorage.setItem('chatBubbleColor', JSON.stringify(savedColor));
            addCustomStyles();
        });

        // Alpha slider
        const alphaSlider = document.createElement('input');
        alphaSlider.type = 'range';
        alphaSlider.min = 0;
        alphaSlider.max = 1;
        alphaSlider.step = 0.05;
        alphaSlider.value = savedColor.a;
        alphaSlider.addEventListener('input', function() {
            savedColor.a = alphaSlider.value;
            localStorage.setItem('chatBubbleColor', JSON.stringify(savedColor));
            addCustomStyles();
        });

        // Blur slider
        const blurSlider = document.createElement('input');
        blurSlider.type = 'range';
        blurSlider.min = 0;
        blurSlider.max = 20;
        blurSlider.step = 1;
        blurSlider.value = savedBlur;
        blurSlider.addEventListener('input', function() {
            savedBlur = blurSlider.value;
            localStorage.setItem('chatBubbleBlur', savedBlur.toString());
            addCustomStyles();
        });

        // Font dropdown
        const fontDropdown = document.createElement('select');
        const fonts = [
            'Comic Sans MS, Comic Sans, cursive',
            'Arial, sans-serif',
            'Georgia, serif',
            'Courier New, Courier, monospace',
            'Verdana, sans-serif',
            'Times New Roman, Times, serif',
                        'Papyrus, fantasy',
            'Comic Neue, cursive',
            'Open Sans, sans-serif',
            'Roboto, sans-serif',
            'Lato, sans-serif',
            'Ubuntu, sans-serif',
            'Poppins, sans-serif',
            'Montserrat, sans-serif',
            'Fira Code, monospace',
            'Anonymous Pro, monospace',
            'Ubuntu Mono, monospace',
            'OpenDyslexic, sans-serif',
            'Caveat, cursive',
            'Patrick Hand, cursive',
            'Shadows Into Light, cursive',
            'Amatic SC, cursive',
            'Permanent Marker, cursive',
            'Indie Flower, cursive',
            'Raleway Dots, sans-serif'

        ];
        fonts.forEach(font => {
            const option = document.createElement('option');
            option.value = font;
            option.textContent = font.split(',')[0];
            if (font === savedFont) option.selected = true;
            fontDropdown.appendChild(option);
        });
        fontDropdown.addEventListener('change', function() {
            savedFont = fontDropdown.value;
            localStorage.setItem('chatBubbleFont', savedFont);
            addCustomStyles();
        });

        // Text size dropdown
        const textSizeDropdown = document.createElement('select');
        const textSizes = ['12px', '14px', '16px', '18px', '20px', '24px'];
        textSizes.forEach(size => {
            const option = document.createElement('option');
            option.value = size;
            option.textContent = size;
            if (size === savedTextSize) option.selected = true;
            textSizeDropdown.appendChild(option);
        });
        textSizeDropdown.addEventListener('change', function() {
            savedTextSize = textSizeDropdown.value;
            localStorage.setItem('chatBubbleTextSize', savedTextSize);
            addCustomStyles();
        });

        // Color pickers for text types
        const createColorPicker = (labelText, colorKey, defaultColor, callback) => {
            const label = document.createElement('label');
            label.textContent = labelText;
            const colorPicker = document.createElement('input');
            colorPicker.type = 'color';
            colorPicker.value = defaultColor;
            colorPicker.addEventListener('input', function() {
                callback(colorPicker.value);
                localStorage.setItem(colorKey, colorPicker.value);
                addCustomStyles();
            });
            panel.appendChild(label);
            panel.appendChild(colorPicker);
            panel.appendChild(document.createElement('br'));
        };

        createColorPicker('Italic Text Color: ', 'italicTextColor', savedItalicColor, value => {
            savedItalicColor = value;
        });

        createColorPicker('Quote Text Color: ', 'quoteTextColor', savedQuoteColor, value => {
            savedQuoteColor = value;
        });

        createColorPicker('Plain Text Color: ', 'plainTextColor', savedPlainTextColor, value => {
            savedPlainTextColor = value;
        });

        // Add controls to the panel
        const rgbLabel = document.createElement('label');
        rgbLabel.textContent = 'Bubble Color: ';
        panel.appendChild(rgbLabel);
        panel.appendChild(rgbInput);
        panel.appendChild(document.createElement('br'));

        const alphaLabel = document.createElement('label');
        alphaLabel.textContent = 'Alpha (Transparency): ';
        panel.appendChild(alphaLabel);
        panel.appendChild(alphaSlider);
        panel.appendChild(document.createElement('br'));

        const blurLabel = document.createElement('label');
        blurLabel.textContent = 'Blur Effect: ';
        panel.appendChild(blurLabel);
        panel.appendChild(blurSlider);
        panel.appendChild(document.createElement('br'));

        const fontLabel = document.createElement('label');
        fontLabel.textContent = 'Font Style: ';
        panel.appendChild(fontLabel);
        panel.appendChild(fontDropdown);
        panel.appendChild(document.createElement('br'));

        const textSizeLabel = document.createElement('label');
        textSizeLabel.textContent = 'Text Size: ';
        panel.appendChild(textSizeLabel);
        panel.appendChild(textSizeDropdown);

        document.body.appendChild(panel);
    }

    // Helper functions
    function rgbToHex(r, g, b) {
        return `#${(1 << 24 | r << 16 | g << 8 | b).toString(16).slice(1).toUpperCase()}`;
    }

    function hexToRgb(hex) {
        const bigint = parseInt(hex.slice(1), 16);
        return {
            r: (bigint >> 16) & 255,
            g: (bigint >> 8) & 255,
            b: bigint & 255
        };
    }

    // Initialize styles and control panel
    window.addEventListener('load', function() {
        addCustomStyles();
        createControlPanel();
    });

    // Observe changes for dynamically added elements
    const observer = new MutationObserver(() => {
        addCustomStyles();
    });

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