Xoul AI Chat Unified Styler

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

Instalar este script¿?
Script recomendado por el autor

Puede que también te guste Xoul AI Background Manager.

Instalar este script
// ==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 });
})();