Greasy Fork is available in English.

😍ChatGPT - Prompt便签

一个帮助用户在ChatGPT原生网页添加可移动且大小可调的便签,用于快速选择和添加prompt的脚本。

// ==UserScript==
// @name         😍ChatGPT - Prompt便签
// @version      3.0
// @description  一个帮助用户在ChatGPT原生网页添加可移动且大小可调的便签,用于快速选择和添加prompt的脚本。
// @author       futureo0
// @require      https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.6.4.min.js
// @match        https://chat.openai.com/*
// @match        https://chat.openai.com/c/*
// @match        https://chat.openai.com/?*
// @match        https://neu.learnwithgpt.beauty/
// @match        https://neu.learnwithgpt.beauty/c
// @match        https://neu.learnwithgpt.beauty/c/*
// @match        *://chatgpt.com/*
// @run-at       document-start
// @grant        GM_setValue
// @grant        GM_getValue
// @namespace https://greasyfork.org/users/1242018
// ==/UserScript==

(function () {
    'use strict';

    $(document).ready(function() {
        const stickyNoteHtml = `
            <div id="stickyNoteContainer" style="position: fixed; top: 20px; right: 20px; width: 300px; min-height: 300px; background-color: lightyellow; border: 1px solid black; padding-bottom: 10px; box-shadow: 3px 3px 5px rgba(0,0,0,0.2); z-index: 1000; resize: both; overflow: auto; color: black;">
                <div id="stickyNoteHeader" style="cursor: move; background-color: #ddd; height: 10px; width: 100%;"></div>
                <input type="text" id="newPromptInput" placeholder="输入新prompt" style="width: calc(100% - 20px); margin: 10px;">
                <button id="savePromptButton" style="width: calc(100% - 20px); margin: 0 10px;">保存</button>
                <div id="promptsList" style="margin: 5px 10px;"></div>
            </div>
        `;
        $('body').append(stickyNoteHtml);

        dragElement(document.getElementById("stickyNoteContainer"), document.getElementById("stickyNoteHeader"));

        loadPrompts();

        $('#savePromptButton').click(function() {
            const newPrompt = $('#newPromptInput').val().trim();
            if(newPrompt) {
                addPromptToStickyNote(newPrompt);
                savePrompt(newPrompt);
                $('#newPromptInput').val('');
            }
        });
    });

    function loadPrompts() {
        const prompts = JSON.parse(GM_getValue('prompts', '[]'));
        prompts.forEach(prompt => {
            addPromptToStickyNote(prompt);
        });
    }

function addPromptToStickyNote(promptText) {
    const promptHtml = `
        <div style="display: flex; align-items: center; margin-bottom: 10px;">
            <button class="deletePromptButton" style="cursor: pointer; background: none; border: none; color: grey; margin-right: 5px;">×</button>
            <div style="cursor: pointer; flex-grow: 1;">${promptText}</div>
        </div>
    `;
    $('#promptsList').prepend(promptHtml); // 使用prepend将新的prompt添加到最前面

    $('#promptsList .deletePromptButton:first').click(function() {
        // 删除按钮的点击事件处理程序
        const promptIndex = $('#promptsList .deletePromptButton').index(this);
        removePrompt(promptIndex);
        $(this).parent().remove(); // 从界面中删除对应的 prompt
    });

    $('#promptsList div:first').click(function() {
        const chatInputSelector = 'textarea';
        insertAtCursor($(chatInputSelector)[0], promptText); // 插入文本到光标位置
    });
}


function removePrompt(index) {
    let prompts = JSON.parse(GM_getValue('prompts', '[]'));
    if (index >= 0 && index < prompts.length) {
        prompts.splice(index, 1);
        GM_setValue('prompts', JSON.stringify(prompts));
    }
}


    function savePrompt(promptText) {
        let prompts = JSON.parse(GM_getValue('prompts', '[]'));
        prompts.push(promptText);
        GM_setValue('prompts', JSON.stringify(prompts));
    }

    function dragElement(elmnt, header) {
        var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;

        header.onmousedown = dragMouseDown;

        function dragMouseDown(e) {
            if (e.target === header) { // 只有点击横条时才触发拖动事件
                e = e || window.event;
                e.preventDefault();
                pos3 = e.clientX;
                pos4 = e.clientY;
                document.onmouseup = closeDragElement;
                document.onmousemove = elementDrag;
            }
        }

        function elementDrag(e) {
            e = e || window.event;
            e.preventDefault();
            pos1 = pos3 - e.clientX;
            pos2 = pos4 - e.clientY;
            pos3 = e.clientX;
            pos4 = e.clientY;

            // 计算新的位置
            elmnt.style.top = (elmnt.offsetTop - pos2) + "px";
            elmnt.style.left = (elmnt.offsetLeft - pos1) + "px";
        }

        function closeDragElement() {
            document.onmouseup = null;
            document.onmousemove = null;
        }
    }


function insertAtCursor(myField, myValue) {
    // 确保输入框是活动的
    myField.focus();

    // 插入文本并移动光标
    if (myField.selectionStart || myField.selectionStart == '0') {
        var startPos = myField.selectionStart;
        var endPos = myField.selectionEnd;
        myField.value = myField.value.substring(0, startPos)
            + myValue
            + myField.value.substring(endPos, myField.value.length);
        myField.selectionStart = myField.selectionEnd = startPos + myValue.length;
    } else {
        myField.value += myValue;
    }

    // 触发input事件以确保更改被识别
    var event = new Event('input', { bubbles: true });
    myField.dispatchEvent(event);
}
})();