ChatGPT Smart Message Queue

Queue messages based on input field state

Από την 18/03/2025. Δείτε την τελευταία έκδοση.

// ==UserScript==
// @name        ChatGPT Smart Message Queue
// @match       https://chat.openai.com/*
// @match       https://chatgpt.com/*
// @description Queue messages based on input field state
// @version 0.0.1.20250318144238
// @namespace https://gf.zukizuki.org/users/1435046
// ==/UserScript==

(function() {
    'use strict';
    
    let queueCount = 0;
    let queueDisplay;
    let isWaitingForClear = false;
    let originalMessage = '';

    function createQueueDisplay() {
        queueDisplay = document.createElement('div');
        queueDisplay.style.position = 'fixed';
        queueDisplay.style.bottom = '100px';
        queueDisplay.style.right = '20px';
        queueDisplay.style.background = 'rgba(0,0,0,0.7)';
        queueDisplay.style.color = 'white';
        queueDisplay.style.padding = '8px 16px';
        queueDisplay.style.borderRadius = '8px';
        queueDisplay.style.zIndex = '9999';
        queueDisplay.innerHTML = `
            <div style="display: flex; gap: 12px; align-items: center">
                <span>Queue: ${queueCount}</span>
                <button style="
                    background: transparent;
                    border: none;
                    color: white;
                    cursor: pointer;
                    padding: 4px 8px;
                    border-radius: 4px;
                " id="clear-queue">Clear</button>
            </div>
        `;
        
        queueDisplay.querySelector('#clear-queue').addEventListener('click', () => {
            queueCount = 0;
            queueDisplay.querySelector('span').textContent = `Queue: ${queueCount}`;
        });

        document.body.appendChild(queueDisplay);
    }

    function trySendMessage() {
        const textarea = document.getElementById('prompt-textarea');
        const sendButton = document.querySelector('[data-testid="send-button"]');
        
        if (textarea && sendButton && !sendButton.disabled && textarea.value === '') {
            const queuedMessage = originalMessage;
            textarea.value = queuedMessage;
            textarea.dispatchEvent(new Event('input', { bubbles: true }));
            
            // Use small timeout to ensure UI updates
            setTimeout(() => {
                if (sendButton && !sendButton.disabled) {
                    originalMessage = queuedMessage;
                    sendButton.click();
                    isWaitingForClear = true;
                }
            }, 50);
        }
    }

    function handleKeyDown(e) {
        if (e.key === 'Enter' && !e.shiftKey && !e.altKey && !e.ctrlKey && !e.metaKey) {
            const textarea = e.target;
            if (textarea.value.trim() === '') return;

            // Store original message before submission
            originalMessage = textarea.value.trim();
            
            // Check if message was accepted within 500ms
            setTimeout(() => {
                if (textarea.value !== '') {
                    queueCount++;
                    queueDisplay.querySelector('span').textContent = `Queue: ${queueCount}`;
                    isWaitingForClear = true;
                }
            }, 500);
        }
    }

    function init() {
        createQueueDisplay();
        
        // Observe textarea for clearing events
        const textareaObserver = new MutationObserver((mutations) => {
            mutations.forEach(mutation => {
                if (mutation.target.value === '' && isWaitingForClear) {
                    isWaitingForClear = false;
                    if (queueCount > 0) {
                        queueCount--;
                        queueDisplay.querySelector('span').textContent = `Queue: ${queueCount}`;
                        trySendMessage();
                    }
                }
            });
        });

        const textarea = document.getElementById('prompt-textarea');
        if (textarea) {
            textarea.addEventListener('keydown', handleKeyDown);
            textareaObserver.observe(textarea, {
                attributes: true,
                attributeFilter: ['value']
            });
        }
    }

    // Start the script
    init();
})();