c.ai X Panel

Adds a Description and an Autoscroll Button

目前为 2024-03-18 提交的版本。查看 最新版本

// ==UserScript==
// @name         c.ai X Panel
// @namespace    c.ai X Panel
// @version      0.1
// @description  Adds a Description and an Autoscroll Button
// @author       Vishanka
// @license     MIT
// @match        https://character.ai/*
// @grant        none
// @icon        https://i.imgur.com/ynjBqKW.png
// ==/UserScript==

(function() {
    'use strict';

    var descriptionAdded = false;
    var previousURL = document.location.href;

    function addDescriptionToElement(description) {
    var parentElement = document.querySelector('div.flex:nth-child(5)');
    if (!parentElement) {
        parentElement = document.querySelector('div.flex:nth-child(4)');
    }
        if (parentElement && !descriptionAdded) {
            var textContainer = document.createElement('div');
            textContainer.style.wordWrap = 'break-word';
            textContainer.style.overflowWrap = 'break-word';
            textContainer.style.maxWidth = '100%';
            textContainer.style.display = 'none';
            textContainer.style.fontSize = '15px';
            textContainer.style.hyphens = 'auto';
            textContainer.style.color = '#a2a2ac';
            var textNode = document.createTextNode(description);

            textContainer.appendChild(textNode);

            descriptionAdded = true;


var toggleButton = document.createElement('button');
toggleButton.style.display = 'flex';
toggleButton.style.alignItems = 'center';
toggleButton.style.textAlign = 'left';
toggleButton.style.paddingLeft = '17px';
toggleButton.style.fontSize = '14px';

toggleButton.style.width = '287px';
toggleButton.style.height = '40px';
toggleButton.style.borderRadius = '8px'; // Adding border radius

// Mouseover event with softer animation
toggleButton.addEventListener('mouseover', function() {
    toggleButton.style.transition = 'background-color 0.3s ease'; // Soften the animation
    toggleButton.style.backgroundColor = '#1F1F23';
});
toggleButton.addEventListener('mouseout', function() {
    toggleButton.style.transition = 'background-color 0.3s ease'; // Soften the animation
    toggleButton.style.backgroundColor = ''; // Reset to default
});



toggleButton.addEventListener('click', function() {
    if (textContainer.style.display === 'none') {
        textContainer.style.display = 'block';
    } else {
        textContainer.style.display = 'none';
    }
});

var image = document.createElement('img');
image.src = 'https://i.imgur.com/1DnLhLG.png';
image.style.marginRight = '12px';
image.style.width = '18px';

toggleButton.appendChild(image);
toggleButton.appendChild(document.createTextNode('Description'));
parentElement.appendChild(toggleButton);


    let intervalId;
    let autoPressEnabled = false;

    function ArrowRightKeyDown() {
        document.body.dispatchEvent(
            new KeyboardEvent('keydown', {
                bubbles: true,
                key: 'ArrowRight',
            })
        );
        console.log("Arrow right pressed");
    }

function toggleAutoPress() {
    autoPressEnabled = !autoPressEnabled;
    if (autoPressEnabled) {
        // Trigger 30 key presses to the right at once
        for (let i = 0; i < 30; i++) {
            ArrowRightKeyDown();
        }
        // Start interval function
        intervalId = setInterval(ArrowRightKeyDown, 1000); // Repeat every 1 second
autoscrollButton.innerHTML = '<span style="color: #A2A2AC; margin-left: 5px; margin-right: 13px;">■</span> Stop Autoscroll';


    } else {
        clearInterval(intervalId);
autoscrollButton.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="28" viewBox="0 0 16 32" fill="none" class="h-full" style="margin-right: 10px;"><path d="M9.59998 19.1998L12.8 15.9998L9.59998 12.7998" stroke="#A2A2AC" stroke-width="1.28" stroke-linecap="round" stroke-linejoin="round"></path><path d="M3.59998 19.1998L6.79998 15.9998L3.59998 12.7998" stroke="#A2A2AC" stroke-width="1.28" stroke-linecap="round" stroke-linejoin="round"></path></svg> Start Autoscroll';
    }
}


var autoscrollButton = document.createElement('button');
autoscrollButton.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="28" viewBox="0 0 16 32" fill="none" class="h-full" style="margin-right: 10px;"><path d="M9.59998 19.1998L12.8 15.9998L9.59998 12.7998" stroke="#A2A2AC" stroke-width="1.28" stroke-linecap="round" stroke-linejoin="round"></path><path d="M3.59998 19.1998L6.79998 15.9998L3.59998 12.7998" stroke="#A2A2AC" stroke-width="1.28" stroke-linecap="round" stroke-linejoin="round"></path></svg> Start Autoscroll';
        //autoscrollButton.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="28" viewBox="0 0 16 32" fill="none" class="h-full"><path d="M9.59998 19.1998L12.8 15.9998L9.59998 12.7998" stroke="#A2A2AC" stroke-width="1.28" stroke-linecap="round" stroke-linejoin="round"></path><path d="M3.59998 19.1998L6.79998 15.9998L3.59998 12.7998" stroke="#A2A2AC" stroke-width="1.28" stroke-linecap="round" stroke-linejoin="round"></path></svg> Start Autoscroll';
autoscrollButton.style.display = 'flex';
autoscrollButton.style.alignItems = 'center';
autoscrollButton.style.textAlign = 'left';
autoscrollButton.style.paddingLeft = '17px';
autoscrollButton.style.fontSize = '14px';
autoscrollButton.style.width = '287px'; //
autoscrollButton.style.height = '40px'; //
autoscrollButton.style.borderRadius = '8px'; // Adding border radius
autoscrollButton.addEventListener('click', toggleAutoPress);

// Mouseover event with softer animation
autoscrollButton.addEventListener('mouseover', function() {
    autoscrollButton.style.transition = 'background-color 0.3s ease'; // Soften the animation
    autoscrollButton.style.backgroundColor = '#1F1F23';
});
autoscrollButton.addEventListener('mouseout', function() {
    autoscrollButton.style.transition = 'background-color 0.3s ease'; // Soften the animation
    autoscrollButton.style.backgroundColor = ''; // Reset to default
});

    parentElement.appendChild(textContainer);
parentElement.appendChild(autoscrollButton);


        }
    }

// Function to make XMLHttpRequest and retrieve description
function fetchDescription() {
    var original_prototype_open = XMLHttpRequest.prototype.open;
    const intercepted_data_object_description = {};

    XMLHttpRequest.prototype.open = function(method, url, async) {
        if (
            url.startsWith('https://plus.character.ai/chat/character/info') ||
            url.startsWith('https://beta.character.ai/chat/character/info')
        ) {
            this.addEventListener('load', function() {
                if (this.status >= 200 && this.status < 300) {
                    try {
                        let Xdescription = JSON.parse(this.responseText);
                        if (Xdescription && Xdescription.character && Xdescription.character.description !== undefined) {
                            intercepted_data_object_description.description = Xdescription.character.description;
                            console.log("NextDescription:", intercepted_data_object_description.description);

                            // Call the function to add description to the element
                            addDescriptionToElement(intercepted_data_object_description.description || ' '); // Send a space if description is empty
                        } else {
                            console.error("Invalid or empty description field in the response");
                        }
                    } catch (error) {
                        console.error("Error parsing JSON response:", error);
                    }
                } else {
                    console.error("Request failed with status:", this.status);
                }
            });
        }

        // Call the original open method
        original_prototype_open.apply(this, arguments);
    };
}

fetchDescription();



    // Observer configuration
    function resetDescriptionFlag() {
        descriptionAdded = false;
    }

    // Observer configuration for DOM changes
    var observerConfig = { childList: true, subtree: true };
var observerCallback = function(mutationsList) {
    for (var mutation of mutationsList) {
        if (mutation.type === 'childList' && !descriptionAdded) {
            setTimeout(fetchDescription, 1000); // Add a 1-second delay
        }
    }
};

    var observer = new MutationObserver(observerCallback);
    observer.observe(document.body, observerConfig);

    // Observer configuration for URL changes
    var urlObserverConfig = { childList: true, subtree: true };
    var urlObserverCallback = function(mutationsList) {
        if (document.location.href !== previousURL) {
            resetDescriptionFlag();
            previousURL = document.location.href;
        }
    };
    var urlObserver = new MutationObserver(urlObserverCallback);
    urlObserver.observe(document.body, urlObserverConfig);
})();


//could be the collapsable bar #radix-\\:rc\\:

QingJ © 2025

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