Coursera Transcript to AI: Video Summarizer 🎬📝

Adds buttons to copy Coursera transcripts and easily summarize videos with the most popular AI platforms.

目前為 2025-02-16 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Coursera Transcript to AI: Video Summarizer 🎬📝
// @namespace    thecolourofmadness
// @version      1.4
// @description  Adds buttons to copy Coursera transcripts and easily summarize videos with the most popular AI platforms.
// @author       nucleargengar
// @match        https://www.coursera.org/*
// @match        https://chatgpt.com/*
// @match        https://gemini.google.com/*
// @match        https://chat.deepseek.com/*
// @match        https://chat.qwenlm.ai/*
// @grant        GM_xmlhttpRequest
// @grant        GM_setClipboard
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_registerMenuCommand
// @icon         https://www.coursera.org/favicon.ico
// @license      All Rights Reserved
// ==/UserScript==

(function() {
    'use strict';

    // Global variable for auto-send feature
    const autoSendKey = "autoSendEnabled";
    let autoSendEnabled = GM_getValue(autoSendKey, false);

    // Function to get the full language name using Intl.DisplayNames API
    function getFullLanguageName() {
        const rawLanguage = navigator.language || navigator.userLanguage;
        const languageCode = rawLanguage.split('-')[0];
        let fullLanguage;
        try {
            const displayNames = new Intl.DisplayNames(['en'], { type: 'language' });
            fullLanguage = displayNames.of(languageCode);
        } catch (error) {
            fullLanguage = languageCode;
        }
        return fullLanguage;
    }

    // Global queue for actions when ctrl key is used
    let ctrlActionQueue = [];

    // Wrapper to handle ctrl key click events
    function handleCtrlClick(event, action) {
        if (event.ctrlKey) {
            ctrlActionQueue.push(action);
            console.log("Queued action for AI platform");
        } else {
            action();
        }
    }

    // Execute queued actions when ctrl key is released
    window.addEventListener('keyup', function(e) {
        if (e.key === "Control") {
            if (ctrlActionQueue.length > 0) {
                ctrlActionQueue.forEach(fn => fn());
                ctrlActionQueue = [];
            }
        }
    });

    // On Coursera pages (lecture pages): Setup UI and submission operations
    if (window.location.hostname.includes("coursera.org")) {

        GM_addStyle(`
            /* Common UI styles for all buttons */
            #copyTranscriptButton, #chatGPTButton, #geminiButton, #deepseekButton, #qwenButton {
                position: fixed;
                background-color: #f5f5f5;
                border: none;
                color: #0056d2;
                width: 40px;
                height: 40px;
                font-size: 18px;
                cursor: pointer;
                z-index: 9999;
                border-radius: 50%;
                transition: background-color 0.3s;
                display: flex;
                align-items: center;
                justify-content: center;
            }
            #copyTranscriptButton:hover, #chatGPTButton:hover, #geminiButton:hover, #deepseekButton:hover, #qwenButton:hover {
                background-color: #eee;
            }
            /* Initial left positioning; bottom will be set dynamically */
            #copyTranscriptButton, #chatGPTButton, #geminiButton, #deepseekButton, #qwenButton {
                left: 20px;
            }
            /* Message box style */
            #messageBox {
                position: fixed;
                top: 20px;
                left: 50%;
                transform: translateX(-50%);
                background-color: rgba(0, 0, 0, 0.8);
                color: white;
                padding: 10px 20px;
                border-radius: 5px;
                z-index: 10000;
                display: none;
            }
        `);

        function displayMessage(message) {
            const messageBox = document.getElementById('messageBox');
            if (!messageBox) return;
            messageBox.textContent = message;
            messageBox.style.display = 'block';
            setTimeout(() => messageBox.style.display = 'none', 3000);
        }

        // Fetch transcript and copy it to the clipboard
        function fetchAndCopyTranscript(url) {
            GM_xmlhttpRequest({
                method: "GET",
                url: url,
                onload: response => {
                    if (response.status === 200) {
                        GM_setClipboard(response.responseText, "text");
                        console.log("Transcript copied to clipboard!");
                        displayMessage("Transcript copied to clipboard!");
                    } else {
                        console.error("Error fetching transcript:", response.status, response.statusText);
                        displayMessage("Error copying transcript: " + response.statusText);
                    }
                },
                onerror: error => {
                    console.error("Request error:", error);
                    displayMessage("Error copying transcript: " + error);
                }
            });
        }

        // Fetch and send transcript for ChatGPT
        function fetchAndSendTranscriptForChatGPT(url) {
            GM_xmlhttpRequest({
                method: "GET",
                url: url,
                onload: response => {
                    if (response.status === 200) {
                        const fullLanguageName = getFullLanguageName();
                        const prefixText = "Here, a transcript of a lecture given by an educator to their students is provided. Summarize this content comprehensively and explain it in detail. Divide it into sections and keep its readability high. If necessary, support it with tables. Present it in " + fullLanguageName + " language.\n\n";
                        const combinedText = prefixText + response.responseText;
                        GM_setValue("chatgptTranscript", combinedText);
                        console.log("Transcript prepared for ChatGPT!");
                        displayMessage("Transcript prepared for ChatGPT!");
                        window.open("https://chatgpt.com", "_blank");
                    } else {
                        console.error("Error fetching transcript:", response.status, response.statusText);
                        displayMessage("Error sending transcript: " + response.statusText);
                    }
                },
                onerror: error => {
                    console.error("Request error:", error);
                    displayMessage("Error sending transcript: " + error);
                }
            });
        }

        // Fetch and send transcript for Gemini
        function fetchAndSendTranscriptForGemini(url) {
            GM_xmlhttpRequest({
                method: "GET",
                url: url,
                onload: response => {
                    if (response.status === 200) {
                        const fullLanguageName = getFullLanguageName();
                        const prefixText = "Here, a transcript of a lecture given by an educator to their students is provided. Summarize this content comprehensively and explain it in detail. Divide it into sections and keep its readability high. If necessary, support it with tables. Present it in " + fullLanguageName + " language.\n\n";
                        const combinedText = prefixText + response.responseText;
                        GM_setValue("geminiTranscript", combinedText);
                        console.log("Transcript prepared for Gemini!");
                        displayMessage("Transcript prepared for Gemini!");
                        window.open("https://gemini.google.com", "_blank");
                    } else {
                        console.error("Error fetching transcript:", response.status, response.statusText);
                        displayMessage("Error sending transcript: " + response.statusText);
                    }
                },
                onerror: error => {
                    console.error("Request error:", error);
                    displayMessage("Error sending transcript: " + error);
                }
            });
        }

        // Fetch and send transcript for DeepSeek
        function fetchAndSendTranscriptForDeepSeek(url) {
            GM_xmlhttpRequest({
                method: "GET",
                url: url,
                onload: response => {
                    if (response.status === 200) {
                        const fullLanguageName = getFullLanguageName();
                        const prefixText = "Here, a transcript of a lecture given by an educator to their students is provided. Summarize this content comprehensively and explain it in detail. Divide it into sections and keep its readability high. If necessary, support it with tables. Present it in " + fullLanguageName + " language.\n\n";
                        const combinedText = prefixText + response.responseText;
                        GM_setValue("deepseekTranscript", combinedText);
                        console.log("Transcript prepared for DeepSeek!");
                        displayMessage("Transcript prepared for DeepSeek!");
                        window.open("https://chat.deepseek.com", "_blank");
                    } else {
                        console.error("Error fetching transcript:", response.status, response.statusText);
                        displayMessage("Error sending transcript: " + response.statusText);
                    }
                },
                onerror: error => {
                    console.error("Request error:", error);
                    displayMessage("Error sending transcript: " + error);
                }
            });
        }

        // Fetch and send transcript for Qwen
        function fetchAndSendTranscriptForQwen(url) {
            GM_xmlhttpRequest({
                method: "GET",
                url: url,
                onload: response => {
                    if (response.status === 200) {
                        const fullLanguageName = getFullLanguageName();
                        const prefixText = "Here, a transcript of a lecture given by an educator to their students is provided. Summarize this content comprehensively and explain it in detail. Divide it into sections and keep its readability high. If necessary, support it with tables. Present it in " + fullLanguageName + " language.\n\n";
                        const combinedText = prefixText + response.responseText;
                        GM_setValue("qwenTranscript", combinedText);
                        console.log("Transcript prepared for Qwen!");
                        displayMessage("Transcript prepared for Qwen!");
                        window.open("https://chat.qwenlm.ai", "_blank");
                    } else {
                        console.error("Error fetching transcript:", response.status, response.statusText);
                        displayMessage("Error sending transcript: " + response.statusText);
                    }
                },
                onerror: error => {
                    console.error("Request error:", error);
                    displayMessage("Error sending transcript: " + error);
                }
            });
        }

        // Get the transcript URL using XPath
        function getTranscriptUrl() {
            const xpath = "//li[@class='css-ap6dbz']/a[contains(@href, '/api/subtitleAssetProxy.v1/') and contains(@download, 'transcript.txt')]";
            return document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
        }

        function copyTranscript() {
            let transcriptLink = getTranscriptUrl();
            if (transcriptLink) {
                fetchAndCopyTranscript(transcriptLink.href);
            } else {
                displayMessage("Transcript link not found. Clicking Downloads tab.");
                clickDownloadsTab();
                const pollInterval = setInterval(() => {
                    transcriptLink = getTranscriptUrl();
                    if (transcriptLink) {
                        clearInterval(pollInterval);
                        fetchAndCopyTranscript(transcriptLink.href);
                    }
                }, 500);
            }
        }

        function sendTranscriptToChatGPT() {
            let transcriptLink = getTranscriptUrl();
            if (transcriptLink) {
                fetchAndSendTranscriptForChatGPT(transcriptLink.href);
            } else {
                displayMessage("Transcript link not found. Clicking Downloads tab.");
                clickDownloadsTab();
                const pollInterval = setInterval(() => {
                    transcriptLink = getTranscriptUrl();
                    if (transcriptLink) {
                        clearInterval(pollInterval);
                        fetchAndSendTranscriptForChatGPT(transcriptLink.href);
                    }
                }, 500);
            }
        }

        function sendTranscriptToGemini() {
            let transcriptLink = getTranscriptUrl();
            if (transcriptLink) {
                fetchAndSendTranscriptForGemini(transcriptLink.href);
            } else {
                displayMessage("Transcript link not found. Clicking Downloads tab.");
                clickDownloadsTab();
                const pollInterval = setInterval(() => {
                    transcriptLink = getTranscriptUrl();
                    if (transcriptLink) {
                        clearInterval(pollInterval);
                        fetchAndSendTranscriptForGemini(transcriptLink.href);
                    }
                }, 500);
            }
        }

        function sendTranscriptToDeepSeek() {
            let transcriptLink = getTranscriptUrl();
            if (transcriptLink) {
                fetchAndSendTranscriptForDeepSeek(transcriptLink.href);
            } else {
                displayMessage("Transcript link not found. Clicking Downloads tab.");
                clickDownloadsTab();
                const pollInterval = setInterval(() => {
                    transcriptLink = getTranscriptUrl();
                    if (transcriptLink) {
                        clearInterval(pollInterval);
                        fetchAndSendTranscriptForDeepSeek(transcriptLink.href);
                    }
                }, 500);
            }
        }

        function sendTranscriptToQwen() {
            let transcriptLink = getTranscriptUrl();
            if (transcriptLink) {
                fetchAndSendTranscriptForQwen(transcriptLink.href);
            } else {
                displayMessage("Transcript link not found. Clicking Downloads tab.");
                clickDownloadsTab();
                const pollInterval = setInterval(() => {
                    transcriptLink = getTranscriptUrl();
                    if (transcriptLink) {
                        clearInterval(pollInterval);
                        fetchAndSendTranscriptForQwen(transcriptLink.href);
                    }
                }, 500);
            }
        }

        function addUI() {
            if (!document.getElementById('copyTranscriptButton')) {
                const btnCopy = document.createElement('button');
                btnCopy.id = 'copyTranscriptButton';
                btnCopy.innerHTML = '📋';
                btnCopy.title = 'Copy Transcript to Clipboard';
                btnCopy.addEventListener('click', copyTranscript);
                document.body.appendChild(btnCopy);
            }
            if (!document.getElementById('chatGPTButton')) {
                const btnChatGPT = document.createElement('button');
                btnChatGPT.id = 'chatGPTButton';
                btnChatGPT.innerHTML = '<img src="https://chatgpt.com/favicon.ico" alt="ChatGPT" style="width:24px;height:24px;">';
                btnChatGPT.title = 'Send Transcript to ChatGPT';
                btnChatGPT.addEventListener('click', function(e) {
                    handleCtrlClick(e, sendTranscriptToChatGPT);
                });
                document.body.appendChild(btnChatGPT);
            }
            if (!document.getElementById('geminiButton')) {
                const btnGemini = document.createElement('button');
                btnGemini.id = 'geminiButton';
                btnGemini.innerHTML = '<img src="https://www.gstatic.com/lamda/images/gemini_favicon_f069958c85030456e93de685481c559f160ea06b.png" alt="Gemini" style="width:24px;height:24px;">';
                btnGemini.title = 'Send Transcript to Gemini';
                btnGemini.addEventListener('click', function(e) {
                    handleCtrlClick(e, sendTranscriptToGemini);
                });
                document.body.appendChild(btnGemini);
            }
            if (!document.getElementById('qwenButton')) {
                const btnQwen = document.createElement('button');
                btnQwen.id = 'qwenButton';
                btnQwen.innerHTML = '<img src="https://i.imgur.com/HopZ9o1.png" alt="Qwen" style="width:24px;height:24px;">';
                btnQwen.title = 'Send Transcript to Qwen';
                btnQwen.addEventListener('click', function(e) {
                    handleCtrlClick(e, sendTranscriptToQwen);
                });
                document.body.appendChild(btnQwen);
            }
            if (!document.getElementById('deepseekButton')) {
                const btnDeepSeek = document.createElement('button');
                btnDeepSeek.id = 'deepseekButton';
                btnDeepSeek.innerHTML = '<img src="https://i.imgur.com/KQW7Nbc.png" alt="DeepSeek" style="width:24px;height:24px;">';
                btnDeepSeek.title = 'Send Transcript to DeepSeek';
                btnDeepSeek.addEventListener('click', function(e) {
                    handleCtrlClick(e, sendTranscriptToDeepSeek);
                });
                document.body.appendChild(btnDeepSeek);
            }
            if (!document.getElementById('messageBox')) {
                const messageBox = document.createElement('div');
                messageBox.id = 'messageBox';
                document.body.appendChild(messageBox);
            }
        }

        function removeUI() {
            document.getElementById('copyTranscriptButton')?.remove();
            document.getElementById('chatGPTButton')?.remove();
            document.getElementById('geminiButton')?.remove();
            document.getElementById('qwenButton')?.remove();
            document.getElementById('deepseekButton')?.remove();
            document.getElementById('messageBox')?.remove();
        }

        // updateIconVisibility controls which buttons are shown based on the stored settings.
        function updateIconVisibility() {
            const showCopy = GM_getValue("showCopyButton", true);
            const showChatGPT = GM_getValue("showChatGPTButton", true);
            const showGemini = GM_getValue("showGeminiButton", true);
            const showDeepSeek = GM_getValue("showDeepSeekButton", true);
            const showQwen = GM_getValue("showQwenButton", true);

            const btnCopy = document.getElementById('copyTranscriptButton');
            if (btnCopy) {
                btnCopy.style.display = showCopy ? 'flex' : 'none';
            }
            const btnChatGPT = document.getElementById('chatGPTButton');
            if (btnChatGPT) {
                btnChatGPT.style.display = showChatGPT ? 'flex' : 'none';
            }
            const btnGemini = document.getElementById('geminiButton');
            if (btnGemini) {
                btnGemini.style.display = showGemini ? 'flex' : 'none';
            }
            const btnDeepSeek = document.getElementById('deepseekButton');
            if (btnDeepSeek) {
                btnDeepSeek.style.display = showDeepSeek ? 'flex' : 'none';
            }
            const btnQwen = document.getElementById('qwenButton');
            if (btnQwen) {
                btnQwen.style.display = showQwen ? 'flex' : 'none';
            }
            // Reposition visible icons
            const iconOrder = [
                'copyTranscriptButton',
                'chatGPTButton',
                'geminiButton',
                'qwenButton',
                'deepseekButton'
            ];
            const spacing = 50; // pixels between icons
            const baseBottom = 20; // starting bottom position
            let visibleCount = 0;
            iconOrder.forEach(id => {
                const btn = document.getElementById(id);
                if (btn && btn.style.display !== 'none') {
                    btn.style.bottom = (baseBottom + visibleCount * spacing) + 'px';
                    visibleCount++;
                }
            });
        }

        function updateUI() {
            const isLecturePage = /^https:\/\/www\.coursera\.org\/learn\/[^\/]+\/lecture\/.+/.test(window.location.href);
            if (isLecturePage) {
                addUI();
                updateIconVisibility();  // Ensure icons are shown and positioned immediately
                clickDownloadsTab();
            } else {
                removeUI();
            }
        }

        const originalPushState = history.pushState;
        history.pushState = function(...args) {
            const result = originalPushState.apply(this, args);
            window.dispatchEvent(new Event('locationchange'));
            return result;
        };
        const originalReplaceState = history.replaceState;
        history.replaceState = function(...args) {
            const result = originalReplaceState.apply(this, args);
            window.dispatchEvent(new Event('locationchange'));
            return result;
        };
        window.addEventListener('popstate', () => window.dispatchEvent(new Event('locationchange')));
        window.addEventListener('locationchange', updateUI);

        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', updateUI);
        } else {
            updateUI();
        }

        function clickDownloadsTab() {
            let tab = document.querySelector("button[data-track-component='focused_lex_lecture_tabs_download']");
            if (tab) {
                tab.click();
                console.log("Downloads tab clicked.");
            } else {
                console.log("Downloads tab not found, retrying.");
                setTimeout(clickDownloadsTab, 1000);
            }
        }
        window.addEventListener('load', clickDownloadsTab);

        // Listeners to reload the page when settings change
        GM_addValueChangeListener("autoSendEnabled", function(name, oldValue, newValue) {
            if (oldValue !== newValue) {
                location.reload();
            }
        });
        GM_addValueChangeListener("showCopyButton", function(name, oldValue, newValue) {
            if (oldValue !== newValue) {
                location.reload();
            }
        });
        GM_addValueChangeListener("showChatGPTButton", function(name, oldValue, newValue) {
            if (oldValue !== newValue) {
                location.reload();
            }
        });
        GM_addValueChangeListener("showGeminiButton", function(name, oldValue, newValue) {
            if (oldValue !== newValue) {
                location.reload();
            }
        });
        GM_addValueChangeListener("showDeepSeekButton", function(name, oldValue, newValue) {
            if (oldValue !== newValue) {
                location.reload();
            }
        });
        GM_addValueChangeListener("showQwenButton", function(name, oldValue, newValue) {
            if (oldValue !== newValue) {
                location.reload();
            }
        });
    }
    // ChatGPT page: Auto-paste transcript.
    else if (window.location.hostname.includes("chatgpt.com")) {
        function autoPasteTranscriptForChatGPT() {
            const transcript = GM_getValue("chatgptTranscript", "");
            if (!transcript) return;
            console.log("Transcript found for ChatGPT, starting auto-paste.");
            const intervalId = setInterval(() => {
                const promptArea = document.getElementById("prompt-textarea");
                if (promptArea) {
                    promptArea.textContent = transcript;
                    promptArea.dispatchEvent(new Event("input", { bubbles: true }));
                    promptArea.focus();
                    clearInterval(intervalId);
                    console.log("Transcript pasted in ChatGPT.");
                    GM_setValue("chatgptTranscript", "");
                    if (autoSendEnabled) {
                        const sendInterval = setInterval(() => {
                            const sendButton = document.querySelector('button[data-testid="send-button"]');
                            if (sendButton) {
                                sendButton.click();
                                console.log("Auto-send triggered for ChatGPT.");
                                clearInterval(sendInterval);
                            }
                        }, 500);
                    }
                }
            }, 500);
        }
        window.addEventListener("load", () => {
            setTimeout(autoPasteTranscriptForChatGPT, 1000);
        });
    }
    // Gemini page: Auto-paste transcript.
    else if (window.location.hostname.includes("gemini.google.com")) {
        function autoPasteTranscriptForGemini() {
            const transcript = GM_getValue("geminiTranscript", "");
            if (!transcript) return;
            console.log("Transcript found for Gemini, starting auto-paste.");
            const intervalId = setInterval(() => {
                const promptArea = document.querySelector("div.ql-editor.ql-blank.textarea.new-input-ui");
                if (promptArea) {
                    promptArea.textContent = transcript;
                    promptArea.dispatchEvent(new Event("input", { bubbles: true }));
                    promptArea.focus();
                    clearInterval(intervalId);
                    console.log("Transcript pasted in Gemini.");
                    GM_setValue("geminiTranscript", "");
                    if (autoSendEnabled) {
                        const sendInterval = setInterval(() => {
                            const sendButton = document.querySelector('button[aria-label="Send message"]');
                            if (sendButton) {
                                sendButton.click();
                                console.log("Auto-send triggered for Gemini.");
                                clearInterval(sendInterval);
                            }
                        }, 500);
                    }
                }
            }, 500);
        }
        window.addEventListener("load", () => {
            setTimeout(autoPasteTranscriptForGemini, 1000);
        });
    }
    // DeepSeek page: Auto-paste transcript.
    else if (window.location.hostname.includes("chat.deepseek.com")) {
        function autoPasteTranscriptForDeepSeek() {
            const transcript = GM_getValue("deepseekTranscript", "");
            if (!transcript) return;
            console.log("Transcript found for DeepSeek, starting auto-paste.");
            const intervalId = setInterval(() => {
                const promptArea = document.getElementById("chat-input");
                if (promptArea) {
                    promptArea.textContent = transcript;
                    promptArea.dispatchEvent(new Event("input", { bubbles: true }));
                    promptArea.focus();
                    clearInterval(intervalId);
                    console.log("Transcript pasted in DeepSeek.");
                    GM_setValue("deepseekTranscript", "");
                    if (autoSendEnabled) {
                        const sendInterval = setInterval(() => {
                            const sendButton = document.querySelector('div[role="button"].f6d670');
                            if (sendButton) {
                                sendButton.click();
                                console.log("Auto-send triggered for DeepSeek.");
                                clearInterval(sendInterval);
                            }
                        }, 500);
                    }
                }
            }, 500);
        }
        window.addEventListener("load", () => {
            setTimeout(autoPasteTranscriptForDeepSeek, 1000);
        });
    }
    // Qwen page: Auto-paste transcript.
    else if (window.location.hostname.includes("chat.qwenlm.ai")) {
        function autoPasteTranscriptForQwen() {
            const transcript = GM_getValue("qwenTranscript", "");
            if (!transcript) return;
            console.log("Transcript found for Qwen, starting auto-paste.");
            const intervalId = setInterval(() => {
                const promptArea = document.getElementById("chat-input");
                if (promptArea) {
                    promptArea.value = transcript;
                    promptArea.dispatchEvent(new Event("input", { bubbles: true }));
                    promptArea.focus();
                    clearInterval(intervalId);
                    console.log("Transcript pasted in Qwen.");
                    GM_setValue("qwenTranscript", "");
                    if (autoSendEnabled) {
                        const sendInterval = setInterval(() => {
                            const sendButton = document.getElementById("send-message-button");
                            if (sendButton) {
                                sendButton.click();
                                console.log("Auto-send triggered for Qwen.");
                                clearInterval(sendInterval);
                            }
                        }, 500);
                    }
                }
            }, 500);
        }
        window.addEventListener("load", () => {
            setTimeout(autoPasteTranscriptForQwen, 1000);
        });
    }

    /* -----------------------------------------------------------------------
       Settings Panel
       -----------------------------------------------------------------------
       This panel is opened via the "Settings" command under the script name.
       It allows control over:
         - Auto-Send Function (controls whether transcripts are auto-sent)
         - Visibility of UI buttons (Copy Only, ChatGPT, Gemini, DeepSeek, Qwen)
       Changes are saved and take effect upon page reload.
    */

    GM_addStyle(`
        #videoSummarizerSettings {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background-color: #102a43;
            color: #ffffff;
            padding: 20px;
            border-radius: 8px;
            z-index: 100000;
            width: 300px;
            font-family: Arial, sans-serif;
            box-shadow: 0 4px 10px rgba(0,0,0,0.5);
        }
        #videoSummarizerSettings h2 {
            margin-top: 0;
            text-align: center;
        }
        #videoSummarizerSettings h3 {
            margin-bottom: 10px;
            border-bottom: 1px solid #ffffff;
            padding-bottom: 5px;
        }
        #videoSummarizerSettings .section {
            margin-bottom: 15px;
        }
        .toggle-label {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 10px;
            font-size: 14px;
        }
        /* Toggle Switch Styles */
        .switch {
            position: relative;
            display: inline-block;
            width: 40px;
            height: 20px;
        }
        .switch input {
            opacity: 0;
            width: 0;
            height: 0;
        }
        .slider {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #ccc;
            transition: .4s;
            border-radius: 20px;
        }
        .slider:before {
            position: absolute;
            content: "";
            height: 16px;
            width: 16px;
            left: 2px;
            bottom: 2px;
            background-color: white;
            transition: .4s;
            border-radius: 50%;
        }
        input:checked + .slider {
            background-color: #2196F3;
        }
        input:checked + .slider:before {
            transform: translateX(20px);
        }
        #settingsDoneButton {
            width: 100%;
            padding: 10px;
            background-color: #2196F3;
            color: #fff;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
        }
        #settingsDoneButton:hover {
            background-color: #1976D2;
        }
    `);

    function addSettingsPanel() {
        // Create settings panel container
        const panel = document.createElement('div');
        panel.id = 'videoSummarizerSettings';

        // Set inner HTML of the panel
        panel.innerHTML = `
            <h2>Video Summarizer Settings</h2>
            <div class="section">
                <h3>Functions</h3>
                <label class="toggle-label">Auto-Send Function
                    <label class="switch">
                        <input type="checkbox" id="autoSendToggle">
                        <span class="slider"></span>
                    </label>
                </label>
            </div>
            <div class="section">
                <h3>Buttons</h3>
                <label class="toggle-label">Copy Only
                    <label class="switch">
                        <input type="checkbox" id="copyOnlyToggle">
                        <span class="slider"></span>
                    </label>
                </label>
                <label class="toggle-label">ChatGPT
                    <label class="switch">
                        <input type="checkbox" id="chatGPTToggle">
                        <span class="slider"></span>
                    </label>
                </label>
                <label class="toggle-label">Gemini
                    <label class="switch">
                        <input type="checkbox" id="geminiToggle">
                        <span class="slider"></span>
                    </label>
                </label>
                <label class="toggle-label">DeepSeek
                    <label class="switch">
                        <input type="checkbox" id="deepseekToggle">
                        <span class="slider"></span>
                    </label>
                </label>
                <label class="toggle-label">Qwen
                    <label class="switch">
                        <input type="checkbox" id="qwenToggle">
                        <span class="slider"></span>
                    </label>
                </label>
            </div>
            <button id="settingsDoneButton">Done</button>
        `;
        document.body.appendChild(panel);

        // Set initial toggle states based on stored values
        document.getElementById('autoSendToggle').checked = GM_getValue("autoSendEnabled", false);
        document.getElementById('copyOnlyToggle').checked = GM_getValue("showCopyButton", true);
        document.getElementById('chatGPTToggle').checked = GM_getValue("showChatGPTButton", true);
        document.getElementById('geminiToggle').checked = GM_getValue("showGeminiButton", true);
        document.getElementById('deepseekToggle').checked = GM_getValue("showDeepSeekButton", true);
        document.getElementById('qwenToggle').checked = GM_getValue("showQwenButton", true);

        // Add event listener to Done button to save settings and reload the page
        document.getElementById('settingsDoneButton').addEventListener('click', () => {
            GM_setValue("autoSendEnabled", document.getElementById('autoSendToggle').checked);
            GM_setValue("showCopyButton", document.getElementById('copyOnlyToggle').checked);
            GM_setValue("showChatGPTButton", document.getElementById('chatGPTToggle').checked);
            GM_setValue("showGeminiButton", document.getElementById('geminiToggle').checked);
            GM_setValue("showDeepSeekButton", document.getElementById('deepseekToggle').checked);
            GM_setValue("showQwenButton", document.getElementById('qwenToggle').checked);
            location.reload();
        });
    }

    // Add a single "Settings" command under the script name to open the settings panel.
    GM_registerMenuCommand("Settings", addSettingsPanel);

})();

QingJ © 2025

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