Sexy.AI to SillyTavern origin

Sync between Sexy.AI and SillyTavern

目前為 2024-11-20 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Sexy.AI to SillyTavern origin
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Sync between Sexy.AI and SillyTavern
// @author       You
// @match        https://sexy.ai/workflow*
// @match        https://staticui.sexy.ai/*
// @match        http://ducninh.top:8000/*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        unsafeWindow
// ==/UserScript==

(function() {
    'use strict';

    console.log("Script started on URL:", window.location.href);

    const isSexyAI = window.location.href.includes('sexy.ai') || window.location.href.includes('staticui.sexy.ai');
    const isSillyTavern = window.location.href.includes('ducninh.top:8000');

    function createStyledButton(text, onClick, isFixed = false) {
        const button = document.createElement('button');
        button.textContent = text;
        let baseStyle = `
            padding: 5px 8px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 3px;
            cursor: pointer;
            font-size: 12px;
            opacity: 0.8;
            transition: opacity 0.3s;
            z-index: 9999;
        `;

        if(isFixed) {
            baseStyle += `
                position: fixed;
                right: 20px;
            `;
        } else {
            baseStyle += `
                margin-left: 5px;
            `;
        }

        button.style.cssText = baseStyle;
        button.addEventListener('mouseover', () => button.style.opacity = '1');
        button.addEventListener('mouseout', () => button.style.opacity = '0.8');
        button.addEventListener('click', onClick);
        return button;
    }

if (isSexyAI) {
    // Chỉ thêm nút khi trong iframe
    if (window.location.href.includes('staticui.sexy.ai')) {
        const promptButton = createStyledButton('Get Prompt', () => {
            const prompt = GM_getValue('st_prompt', null);
            if (prompt) {
                const positiveInput = document.querySelector('textarea') ||
                                    document.querySelector('input[type="text"]');

                if (positiveInput) {
                    positiveInput.value = prompt;
                    const event = new Event('input', { bubbles: true });
                    positiveInput.dispatchEvent(event);
                    GM_setValue('st_prompt', null);
                    alert('Prompt added!');
                } else {
                    console.error('Available inputs:', document.querySelectorAll('input, textarea'));
                    alert('Input field not found.');
                }
            } else {
                alert('No prompt found. Copy from SillyTavern first.');
            }
        }, true);

        promptButton.style.top = '80px';
        document.body.appendChild(promptButton);
    }

    // Image click handler
    document.addEventListener('click', (e) => {
        if (e.target.tagName === 'IMG') {
            const markdownUrls = [`![alt-text](${e.target.src})`];
            GM_setValue('sexyai_images', markdownUrls.join('\n'));
            alert('Image copied! Switch to SillyTavern tab.');
        }
    }, true);

    } else if (isSillyTavern) {
        // Theo dõi sự thay đổi DOM để thêm button vào tin nhắn mới
        const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                mutation.addedNodes.forEach((node) => {
                    if (node.classList?.contains('mes')) {
                        const messageText = node.querySelector('.mes_text');
                        if (messageText && !messageText.querySelector('.button-container')) {
                            const buttonContainer = document.createElement('div');
                            buttonContainer.className = 'button-container';
                            buttonContainer.style.display = 'flex';
                            buttonContainer.style.gap = '5px';
                            buttonContainer.style.marginTop = '5px';

                            // Nút Sync Image
                            const syncButton = createStyledButton('📥 Sync Image', () => {
                                const markdownUrls = GM_getValue('sexyai_images', null);
                                if (!markdownUrls) {
                                    alert('No images found. Click an image in Sexy.AI first.');
                                    return;
                                }

                                const editButton = node.querySelector('.mes_edit');
                                if (editButton) {
                                    editButton.click();
                                    setTimeout(() => {
                                        const textarea = document.getElementById('curEditTextarea');
                                        if (textarea) {
                                            textarea.value = textarea.value + '\n' + markdownUrls;
                                            setTimeout(() => {
                                                const confirmButton = node.querySelector('.mes_edit_done');
                                                if (confirmButton) {
                                                    confirmButton.click();
                                                    GM_setValue('sexyai_images', null);
                                                    alert('Images added successfully!');
                                                }
                                            }, 100);
                                        }
                                    }, 100);
                                }
                            });

                            // Nút Send Prompt
                            const sendPromptButton = createStyledButton('📤 Send Prompt', () => {
                                const text = messageText.textContent;
                                const match = text.match(/image###([^#]+)###/);
                                if (match) {
                                    const prompt = match[1].trim();
                                    GM_setValue('st_prompt', prompt);
                                    alert('Prompt copied! Click "Get Prompt" in Sexy.AI tab');
                                } else {
                                    alert('No valid prompt found. Message should contain image###prompt###');
                                }
                            });

                            // Thêm các button vào container
                            buttonContainer.appendChild(syncButton);
                            buttonContainer.appendChild(sendPromptButton);

                            // Thêm container vào tin nhắn
                            messageText.appendChild(buttonContainer);
                        }
                    }
                });
            });
        });

        // Bắt đầu theo dõi thay đổi DOM
        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    }
})();

QingJ © 2025

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