🤖ChatGPT - 提示选择器

一个帮助用户在ChatGPT原生网页快速选择 ChatGPT 提示"Prompt"的脚本。

目前為 2023-04-19 提交的版本,檢視 最新版本

// ==UserScript==
// @name         🤖ChatGPT - 提示选择器
// @namespace    https://gf.qytechs.cn/
// @version      1.0.4
// @description  一个帮助用户在ChatGPT原生网页快速选择 ChatGPT 提示"Prompt"的脚本。
// @author       OpenAI - ChatGPT
// @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/?*
// @run-at       document-start
// @grant        GM_xmlhttpRequest
// @grant        GM_setValue
// @grant        GM_getValue
// @license      GNU GPLv3
// ==/UserScript==

(function () {
    "use strict";

    const DARK_MODE_STYLE = `
    .dark-mode-compatible {
      background-color: white;
      color: black;
    }
    .dark .dark-mode-compatible {
      background-color: #343540;
      color: white;
    }

    select {
      font-size: 16px;
      border-radius: 4px;
    }

    select option {
      font-size: 16px;
      padding: 8px;
    }

  `;

    //可通过替换下面的Json链接来自定义提示库。
    const DATA_URL =
      "https://fs-im-kefu.7moor-fs1.com/29397395/4d2c3f00-7d4c-11e5-af15-41bf63ae4ea0/1681658246070/input.json";

    const CATEGORY_DROPDOWN_ID = "chatgpt-prompt-selector-category";
    const SUBCATEGORY_DROPDOWN_ID = "chatgpt-prompt-selector-subcategory";
    const CUSTOM_PROMPT_DROPDOWN_ID = "customPromptDropdown";
    const CATEGORY_DROPDOWN_PLACEHOLDER = "[类别]";
    const SUBCATEGORY_DROPDOWN_PLACEHOLDER = "[提示]";
    const CUSTOM_PROMPT_DROPDOWN_PLACEHOLDER = "[自定义提示]";

    const CATEGORY_DROPDOWN_WIDTH = 100;
    const SUBCATEGORY_DROPDOWN_WIDTH = 180;
    const CUSTOM_PROMPT_DROPDOWN_WIDTH = 180;
    const DEFAULT_ENTRY_HEIGHT = 20;

    const CHECK_MARKUP_INTERVAL = 500;
    const ENTRY_HEIGHT_RESET_DELAY = 500;

    const CONTAINER_SELECTOR = "form div.md\\:w-full.justify-center";
    const ENTRY_SELECTOR = "textarea";

    const SELECT_START_TAG_TEMPLATE =
      '<select id="{{id}}" class="dark-mode-compatible" style="width: {{width}}px">';
    const SELECT_END_TAG_TEMPLATE = "</select>";
    const OPTION_TAG_TEMPLATE =
      '<option value="{{value}}" title="{{titleMark}}">{{title}}</option>';
    const DATA_LOAD_ERROR_MESSAGE =
      "ChatGPT提示选择器错误:无法下载数据集请检查json链接是否正确。";

    const NEW_LINE = "\r\n";

    let promptItems = null;

    function placeholder(name) {
      return "{{" + name + "}}";
    }

    function createDropdown(parent, id, defaultOptionTitle, width, items) {
      let markup = SELECT_START_TAG_TEMPLATE.replace(
        placeholder("id"),
        id
      ).replace(placeholder("width"), width);

      markup += OPTION_TAG_TEMPLATE.replace(placeholder("value"), "")
        .replace(placeholder("title"), defaultOptionTitle)
        .replace(placeholder("titleMark"), "");

      for (const item of items) {
        const title = item.title;
        const mark = item.mark;
        markup += OPTION_TAG_TEMPLATE.replace(placeholder("value"), mark)
          .replace(placeholder("title"), title)
          .replace(placeholder("titleMark"), mark);
      }

      markup += SELECT_END_TAG_TEMPLATE;

      if (id === CATEGORY_DROPDOWN_ID) {
        parent.prepend(markup);
      } else {
        getCategoryDropdown().after(markup);
      }
    }

    function getCategoryDropdown() {
      return $("#" + CATEGORY_DROPDOWN_ID);
    }

    function getSubcategoryDropdown() {
      return $("#" + SUBCATEGORY_DROPDOWN_ID);
    }

    function getCustomPromptDropdown() {
      return $("#" + CUSTOM_PROMPT_DROPDOWN_ID);
    }

    function handleSubcategoryChange() {
      const categoryDropdown = getCategoryDropdown();
      const categoryMark = categoryDropdown.val();
      const categoryItem = promptItems.find((item) => item.mark === categoryMark);

      if (categoryItem === null) return;

      const subcategoryMark = $(this).val();
      const subcategoryItem = categoryItem.items.find(
        (item) => item.mark === subcategoryMark
      );

      if (subcategoryItem === null) return;

      const prompt = categoryItem.prompt.replace(
        placeholder("prompt"),
        subcategoryItem.prompt
      );
      const parts = prompt.split(NEW_LINE);
      const heightInPixels = DEFAULT_ENTRY_HEIGHT * parts.length + 1;

      const entry = $(ENTRY_SELECTOR);
      const button = entry.next();

      entry.height(heightInPixels);
      entry.val(prompt);

      button.prop("disabled", false);
      button.click(() => {
        setTimeout(() => {
          entry.height(DEFAULT_ENTRY_HEIGHT);
        }, ENTRY_HEIGHT_RESET_DELAY);
      });
      const defaultCategoryMark = categoryDropdown
        .find('option:contains("默认")')
        .val();
      categoryDropdown.val(defaultCategoryMark);
      categoryDropdown.trigger("change");
    }

    function handleCategoryChange() {
      const categoryMark = $(this).val();
      const categoryItem = promptItems.find((item) => item.mark === categoryMark);
      if (categoryItem === null) return;

      const dropdown = getSubcategoryDropdown();
      if (dropdown.length > 0) dropdown.remove();

      const container = getContainer();
      createDropdown(
        container,
        SUBCATEGORY_DROPDOWN_ID,
        SUBCATEGORY_DROPDOWN_PLACEHOLDER,
        SUBCATEGORY_DROPDOWN_WIDTH,
        categoryItem.items
      );

      const subcategoryDropdown = getSubcategoryDropdown();
      subcategoryDropdown.change(handleSubcategoryChange);
    }

    function handleCustomPromptChange() {
      const customPrompt = $(this).val();
      const entry = $(ENTRY_SELECTOR);
      const button = entry.next();

      entry.val(customPrompt);

      // 计算所选自定义提示的高度,并将其应用于输入框
      const parts = customPrompt.split(NEW_LINE);
      const heightInPixels = DEFAULT_ENTRY_HEIGHT * parts.length + 1;
      entry.height(heightInPixels);

      button.prop("disabled", false);
      button.click(() => {
        setTimeout(() => {
          entry.height(DEFAULT_ENTRY_HEIGHT);
        }, ENTRY_HEIGHT_RESET_DELAY);
      });
    }

    function activateCheckTimer() {
      setInterval(checkMarkup, CHECK_MARKUP_INTERVAL);
    }

    function getContainer() {
      return $(CONTAINER_SELECTOR);
    }

    function checkMarkup() {
      const container = getContainer();

      if (container.has("select").length > 0) return;
      if (window.innerWidth <= 480) return;

      createDropdown(
        container,
        CATEGORY_DROPDOWN_ID,
        CATEGORY_DROPDOWN_PLACEHOLDER,
        CATEGORY_DROPDOWN_WIDTH,
        promptItems
      );
      createDropdown(
        container,
        SUBCATEGORY_DROPDOWN_ID,
        SUBCATEGORY_DROPDOWN_PLACEHOLDER,
        SUBCATEGORY_DROPDOWN_WIDTH,
        []
      );
      const customPrompts = JSON.parse(GM_getValue("customPrompts", "[]"));
      createDropdown(
        container,
        CUSTOM_PROMPT_DROPDOWN_ID,
        CUSTOM_PROMPT_DROPDOWN_PLACEHOLDER,
        CUSTOM_PROMPT_DROPDOWN_WIDTH,
        customPrompts
      );
      const customPromptDropdown = getCustomPromptDropdown();
      customPromptDropdown.toggle(customPrompts.length > 0);
      customPromptDropdown.change(handleCustomPromptChange);

      const categoryDropdown = getCategoryDropdown();
      categoryDropdown.change(handleCategoryChange);
      const defaultCategoryMark = categoryDropdown
        .find('option:contains("默认")')
        .val();
      categoryDropdown.val(defaultCategoryMark);
      categoryDropdown.trigger("change");
      addCustomPromptButton();
    }

    function addCustomPrompt() {
      const title = prompt("请输入提示的标题:");
      if (!title) return;
      const customPrompts = JSON.parse(GM_getValue("customPrompts", "[]"));
      if (customPrompts.find((item) => item.title === title)) {
        alert("该标题已经存在,请输入一个新的标题。");
        return;
      }

      const content = prompt("请输入提示的内容:");
      if (!content) return;

      customPrompts.push({ title, mark: content });
      GM_setValue("customPrompts", JSON.stringify(customPrompts));

      const customPromptDropdown = getCustomPromptDropdown();
      customPromptDropdown.append(
        OPTION_TAG_TEMPLATE.replace(placeholder("value"), content)
          .replace(placeholder("title"), title)
          .replace(placeholder("titleMark"), content)
      );
      customPromptDropdown.val(content);
      customPromptDropdown.trigger("change");
      customPromptDropdown.show();
    }

    function removeCustomPrompt(mark) {
      let customPrompts = JSON.parse(GM_getValue("customPrompts", "[]"));
      customPrompts = customPrompts.filter((item) => item.mark !== mark);
      GM_setValue("customPrompts", JSON.stringify(customPrompts));
    }

    function addCustomPromptButton() {
        let addButton, removeButton;

        const container = getContainer();
        addButton = $(
          '<button class="dark-mode-compatible btn relative btn-neutral border-0 md:border" type="button">添加</button>'
        );
        addButton.click(addCustomPrompt);
        removeButton = $(
          '<button class="dark-mode-compatible btn relative btn-neutral border-0 md:border" type="button">删除</button>'
        );
        removeButton.click(() => {
          const customPromptDropdown = getCustomPromptDropdown();
          const mark = customPromptDropdown.val();
          if (!mark) return;
          customPromptDropdown.find(`option[value="${mark}"]`).remove();
          removeCustomPrompt(mark);
          if (customPromptDropdown.children().length <= 1) {
            customPromptDropdown.hide();
            removeButton.hide();
            addButton.show(); // 显示添加按钮
          }

          // 清空输入框
          const entry = $(ENTRY_SELECTOR);
          entry.val("");
        });
        removeButton.hide();
        getCustomPromptDropdown().after(removeButton);
        getCustomPromptDropdown().after(addButton);

        const customPromptDropdown = getCustomPromptDropdown();
        if (customPromptDropdown.children().length <= 1) {
          removeButton.hide();
          addButton.show(); // 显示添加按钮
        }

        customPromptDropdown.on("change", () => {
          if (customPromptDropdown.val()) {
            removeButton.show();
            addButton.hide(); // 隐藏添加按钮
          } else {
            removeButton.hide();
            addButton.show(); // 显示添加按钮
          }
        });
      }




    function createCustomPromptDropdown() {
      const container = getContainer();
      const customPrompts = JSON.parse(GM_getValue("customPrompts", "[]"));
      const customPromptDropdown = $(
        `<select id="${CUSTOM_PROMPT_DROPDOWN_ID}" class="${CATEGORY_DROPDOWN_ID}" style="width: ${CATEGORY_DROPDOWN_WIDTH}px" size="${customPrompts.length}"></select>`
      );
      container.append(customPromptDropdown);

      for (const customPrompt of customPrompts) {
        customPromptDropdown.append(
          `<option value="${customPrompt.mark}" title="${customPrompt.mark}">${customPrompt.title}</option>`
        );
      }

      if (customPrompts.length === 0) {
        customPromptDropdown.hide();
      } else {
        customPromptDropdown.show();
      }

      customPromptDropdown.change(() => {
        const selectedPrompt = customPromptDropdown.val();
        if (selectedPrompt) {
          const entry = $(ENTRY_SELECTOR);
          entry.val(selectedPrompt);
        }
      });

      return customPromptDropdown;
    }

    function setReceivedData(jsonText) {
      promptItems = JSON.parse(jsonText);
    }

    function loadData() {
      const getData = new Promise((resolve, reject) => {
        GM_xmlhttpRequest({
          method: "GET",
          url: DATA_URL,
          onload: (response) => {
            resolve(response.responseText);
          },
          onerror: () => {
            reject(DATA_LOAD_ERROR_MESSAGE);
          },
        });
      });

      getData
        .then((data) => {
          setReceivedData(data);
          activateCheckTimer();
        })
        .catch((error) => {
          console.error(error);
        });
    }

    function addDarkModeStyles() {
      const styleTag = document.createElement("style");
      styleTag.innerHTML = DARK_MODE_STYLE;
      document.head.appendChild(styleTag);
    }

    createCustomPromptDropdown();
    activateCheckTimer();
    addDarkModeStyles();
    loadData();
    addCustomPromptButton();
  })();

QingJ © 2025

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