ChatGPT Mini Panel with AI Conversation and Google Search

Mini chat panel with ChatGPT that relays messages between the user and AI, along with Google search functionality

目前为 2024-04-07 提交的版本。查看 最新版本

// ==UserScript==
// @name         ChatGPT Mini Panel with AI Conversation and Google Search
// @namespace    http://your.domain.com
// @version      1.1
// @description  Mini chat panel with ChatGPT that relays messages between the user and AI, along with Google search functionality
// @match        https://*/*
// @match        http://*/*
// @grant        GM_xmlhttpRequest
// @icon         https://img.icons8.com/nolan/77/chatgpt.png
// ==/UserScript==

(function() {
    'use strict';

    // Constants
    const panelColorDefault = 'linear-gradient(135deg, #ff6ec4, #7873f5)';
    const headerColorDefault = '#ff6ec4';
    const messageColorDefault = '#7873f5';

    // State
    let panelColor = localStorage.getItem('panelColor') || panelColorDefault;
    let headerColor = localStorage.getItem('headerColor') || headerColorDefault;
    let messageColor = localStorage.getItem('messageColor') || messageColorDefault;
    let apiKey = localStorage.getItem('apiKey') || '';

    // Load Font Awesome
    const faStylesheet = document.createElement('link');
    faStylesheet.rel = 'stylesheet';
    faStylesheet.href = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css';
    document.head.appendChild(faStylesheet);

    // Create draggable icon
    const chatIcon = document.createElement('div');
    chatIcon.innerHTML = `<img src="https://img.icons8.com/nolan/77/chatgpt.png" alt="ChatGPT Icon" style="width: 40px; height: 40px; cursor: pointer;">`;
    chatIcon.classList.add('chat-icon');
    document.body.appendChild(chatIcon);

    // Create chat panel
    const chatPanel = createChatPanel();
    document.body.appendChild(chatPanel);

    // Create help panel
    const helpPanel = createPanel('Help');
    document.body.appendChild(helpPanel);

    // Create settings panel
    const settingsPanel = createPanel('Settings');
    document.body.appendChild(settingsPanel);

    // Make icon draggable
    makeDraggable(chatIcon);

    // Toggle chat panel visibility when icon is clicked
    chatIcon.addEventListener('click', toggleChatPanel);

    // Event listeners for help and settings buttons
    document.getElementById('help-btn').addEventListener('click', togglePanel.bind(null, helpPanel));
    document.getElementById('settings-btn').addEventListener('click', togglePanel.bind(null, settingsPanel));

    // Close button functionality for panels
    document.querySelectorAll('.panel-header').forEach(header => {
        header.addEventListener('click', closePanel);
    });

    // Save settings button functionality
    document.getElementById('save-settings-btn').addEventListener('click', saveSettings);

    // Send button functionality
    document.getElementById('send-btn').addEventListener('click', sendMessage);

    // Enter key functionality for sending messages
    document.getElementById('chat-input').addEventListener('keydown', function(event) {
        if (event.key === 'Enter') {
            sendMessage();
        }
    });

    // Function to create chat panel
    function createChatPanel() {
        const chatPanel = createPanel('ChatGPT');
        chatPanel.id = 'chat-panel';
        return chatPanel;
    }

    // Function to create a generic panel
    function createPanel(title) {
        const panel = document.createElement('div');
        panel.classList.add('panel');
        panel.innerHTML = `
            <div class="panel-header">${title}</div>
            <div class="panel-content"></div>
        `;
        return panel;
    }

    // Function to toggle panel visibility
    function togglePanel(panel) {
        panel.style.display = panel.style.display === 'none' ? 'block' : 'none';
    }

    // Function to close panel
    function closePanel() {
        this.parentNode.style.display = 'none';
    }

    // Function to save settings
    function saveSettings() {
        panelColor = document.getElementById('panel-color').value;
        headerColor = document.getElementById('header-color').value;
        messageColor = document.getElementById('message-color').value;
        apiKey = document.getElementById('api-key').value;

        localStorage.setItem('panelColor', panelColor);
        localStorage.setItem('headerColor', headerColor);
        localStorage.setItem('messageColor', messageColor);
        localStorage.setItem('apiKey', apiKey);

        updateStyles();
        closePanel.call(this.parentNode);
    }

    // Function to update panel styles
    function updateStyles() {
        chatPanel.style.background = panelColor;
        document.getElementById('chat-header').style.backgroundColor = headerColor;
        document.getElementById('chat-messages').style.backgroundColor = messageColor;
    }

    // Function to make icon draggable
    function makeDraggable(icon) {
        let isDragging = false;
        let offsetX, offsetY;

        icon.addEventListener('mousedown', function(e) {
            isDragging = true;
            offsetX = e.clientX - icon.getBoundingClientRect().left;
            offsetY = e.clientY - icon.getBoundingClientRect().top;
        });

        document.addEventListener('mousemove', function(e) {
            if (isDragging) {
                const newX = e.clientX - offsetX;
                const newY = e.clientY - offsetY;
                const maxX = window.innerWidth - icon.offsetWidth;
                const maxY = window.innerHeight - icon.offsetHeight;
                icon.style.left = Math.max(0, Math.min(newX, maxX)) + 'px';
                icon.style.top = Math.max(0, Math.min(newY, maxY)) + 'px';
            }
        });

        document.addEventListener('mouseup', function() {
            isDragging = false;
        });
    }

    // Function to toggle chat panel visibility
    function toggleChatPanel() {
        const isVisible = chatPanel.style.display === 'block';
        chatPanel.style.display = isVisible ? 'none' : 'block';
        chatPanel.style.animation = isVisible ? 'fadeOutDown 0.5s' : 'fadeInUp 0.5s';

        spinIcon();
    }

    // Function to add spinning animation to icon
    function spinIcon() {
        chatIcon.querySelector('img').style.animation = 'spin 1s linear infinite';
        setTimeout(() => {
            chatIcon.querySelector('img').style.animation = 'none';
        }, 1000);
    }

    // Function to send message
    function sendMessage() {
        const input = document.getElementById('chat-input');
        const message = input.value.trim();
        if (message) {
            displayMessage('You', message);
            input.value = '';
        }
    }

    // Function to display message in chat panel
    function displayMessage(sender, message) {
        const messageDiv = document.createElement('div');
        messageDiv.textContent = `${sender}: ${message}`;
        document.getElementById('chat-messages').appendChild(messageDiv);
        document.getElementById('chat-messages').scrollTop = document.getElementById('chat-messages').scrollHeight;
    }
})();