您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
NovelAi Prompts Management
// ==UserScript== // @name NovelAi online Prompts Tool // @namespace npm/vite-plugin-monkey // @version 0.9.9 // @author ChatGPT4 // @icon https://vitejs.dev/logo.svg // @match https://novelai.net/image // @require https://cdn.jsdelivr.net/npm/[email protected]/umd/react.production.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/umd/react-dom.production.min.js // @grant GM_addStyle // @description NovelAi Prompts Management // @license MIT // ==/UserScript== (o=>{if(typeof GM_addStyle=="function"){GM_addStyle(o);return}const t=document.createElement("style");t.textContent=o,document.head.append(t)})(" #root{max-width:1280px;margin:0 auto;padding:2rem;text-align:center}.logo{height:6em;padding:1.5em;will-change:filter}.logo:hover{filter:drop-shadow(0 0 2em #646cffaa)}.logo.react:hover{filter:drop-shadow(0 0 2em #61dafbaa)}@keyframes logo-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@media (prefers-reduced-motion: no-preference){a:nth-of-type(2) .logo{animation:logo-spin infinite 20s linear}}.card{padding:2em}.read-the-docs{color:#888}.side-drawer{position:fixed;width:90%;background-color:#333;transition:transform 1s ease;z-index:100;transform:translate(-100%);top:5%}.side-drawer.visible{transform:translate(0)}.container input{position:absolute;opacity:0;cursor:pointer;height:0;width:0}.container{position:fixed;z-index:10003;display:block;cursor:pointer;-webkit-user-select:none;user-select:none}.container svg{position:relative;top:0;left:0;height:50px;width:50px;transition:all .3s;fill:#666}.container svg:hover{transform:scale(1.1)}.container input:checked~svg{fill:#f5f3c2}.starButton{position:fixed;background-color:#f5f3c2;color:#13152c;border:none;border-radius:4px;padding:8px 16px;cursor:pointer;box-shadow:0 2px 4px #0003;transition:background-color .3s ease}.animated-button{z-index:10000;position:absolute;display:flex;align-items:center;gap:4px;padding:6px 25px;border:4px solid;border-color:transparent;font-size:14px;background-color:inherit;border-radius:100px;font-weight:600;color:#fff;box-shadow:0 0 0 2px #fff;cursor:pointer;overflow:hidden;transition:all .6s cubic-bezier(.23,1,.32,1)}.animated-button svg{position:absolute;width:24px;fill:#fff;z-index:9;transition:all .8s cubic-bezier(.23,1,.32,1)}.animated-button .arr-1{right:16px}.animated-button .arr-2{left:-25%}.animated-button .circle{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:20px;height:20px;background-color:#fff;border-radius:50%;opacity:0;transition:all .8s cubic-bezier(.23,1,.32,1)}.animated-button .text{position:relative;z-index:1;transform:translate(-12px);transition:all .8s cubic-bezier(.23,1,.32,1)}.animated-button:hover{box-shadow:0 0 0 12px transparent;color:#212121;border-radius:12px}.animated-button:hover .arr-1{right:-25%}.animated-button:hover .arr-2{left:16px}.animated-button:hover .text{transform:translate(12px)}.animated-button:hover svg{fill:#212121}.animated-button:active{scale:.95;box-shadow:0 0 0 4px #fff}.animated-button:hover .circle{width:220px;height:220px;opacity:1}.thing{z-index:1;left:0}.container1{position:fixed;z-index:1005;background:transparent;border:solid white}.tab-manager-container{border:2px solid #2b2b2b;padding:2px;border-radius:5px;margin:2px auto;max-width:100%;position:fixed;top:0;left:450px;z-index:100;background-color:#1e1e1e;box-shadow:0 2px 4px #0000001a}.tabs-bar{display:flex;flex-wrap:wrap;align-items:center;padding:8px;background-color:#13152c;color:#13152c;box-shadow:0 0 10px #0003}.tab-content{padding-top:0;overflow-y:auto;max-height:500px;background-color:#34495e;color:#fff}.tab{flex:1 1 auto;text-align:center;cursor:pointer;padding:.1rem 0;color:#fff;transition:all .15s ease-in-out;border-radius:.5rem;background-color:#34495e;margin-right:5px;display:flex;justify-content:space-evenly;align-items:center}.delete-tab{background-color:#e74c3c;color:#fff;border:none;border-radius:4px;padding:4px 8px;cursor:pointer;transition:opacity .3s ease}.delete-tab:hover{opacity:.8}.tab:hover,.tab.active{background-color:#fff;color:#333;font-weight:600}.button{background-color:#f5f3c2;color:#13152c;border:none;border-radius:4px;padding:8px 16px;cursor:pointer;box-shadow:0 2px 4px #0003;transition:background-color .3s ease}.button:hover{background-color:#2980b9}.input{border:1px solid #ccc;border-radius:4px;padding:8px;width:100%}.bin-button{display:flex;flex-direction:column;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;background-color:#13152c;cursor:pointer;border:2px solid #34495e;transition-duration:.3s;position:relative;overflow:hidden}.bin-bottom{width:12px;z-index:2}.bin-top{width:12px;transform-origin:right;transition-duration:.3s;z-index:2}.bin-button:hover .bin-top{transform:rotate(45deg)}.bin-button:hover{background-color:red}.bin-button:active{transform:scale(.9)}.garbage{position:absolute;width:10px;height:auto;z-index:1;opacity:0;transition:all .3s}.bin-button:hover .garbage{animation:throw .4s linear}@keyframes throw{0%{transform:translate(-400%,-700%);opacity:0}to{transform:translate(0);opacity:1}}.input-group{position:relative}.input1{border:solid 1.5px #9e9e9e;border-radius:1rem;background:none;padding:1rem;font-size:1rem;color:#f5f5f5;transition:border .15s cubic-bezier(.4,0,.2,1)}.user-label{position:absolute;left:15px;color:#e8e8e8;pointer-events:none;transform:translateY(1rem);transition:.15s cubic-bezier(.4,0,.2,1)}.input1:focus{outline:none;border:1.5px solid #1a73e8}.input1:focus~label{transform:translateY(-50%) scale(.8);background-color:#212121;padding:0 .2em;color:#2196f3}.add-tab-button{background:#f5f3c2;border:none;font-size:10px;cursor:pointer}.tabs-bar{display:flex;justify-content:space-between}.input-group{display:none}.input-group.show{display:block}.promptAddButton{align-self:flex-end}.enter-button{align-items:center;justify-content:center;padding:4px 12px;gap:25px;font-size:.7em;letter-spacing:2px;color:#fff;cursor:pointer;background:#13152c;position:relative;border-radius:8px;border:1px solid rgb(65,65,65);transition-duration:.3s}.arrow{height:10px}.enter-button:hover{transition-duration:.3s;box-shadow:0 0 2px #b9b9b9,0 0 10px #616161}.enter-button:active{transform:scale(.95)}.asdasd{display:inline-flex}.search-results{background:#13152c;overflow-y:auto;max-height:400px}.a12345,.search-result-item{display:flex}.search-result-item h4{margin:0}.search-result-item p{margin:5px 0}.more-button{padding:inherit;background:inherit;border:1px solid rgb(65,65,65)}.tags-container{display:flex;flex-wrap:wrap;gap:5px;background-color:#2c2f33;padding:5px;border-radius:4px;font-size:.7rem;z-index:2000;position:fixed;max-width:400px;overflow:visible}.tag-item.dragging{opacity:.5}::-webkit-scrollbar{display:none}.tag-item-container{position:relative}.tag-item{display:flex;align-items:center;background-color:#3b3e43;border-radius:8px;padding:1px;position:relative}.tag-content{margin-right:5px;outline:none;background-color:transparent;border:none;color:#fff;max-width:100px;white-space:normal;word-wrap:break-word;overflow-wrap:break-word}.edit-tag{display:inline-flex;justify-content:center;align-items:center}.tag-content:focus{border-bottom:1px solid #7289da}.edit-tag,.delete-tag{margin:0 5px;cursor:pointer;padding:2px 4px;font-size:.5rem;width:25px;height:25px;display:flex;justify-content:center;align-items:center}.delete-tag{background:#cd5c5c}.tag-buttons{display:flex;justify-content:center;position:absolute;top:-24px;left:50%;transform:translate(-50%);visibility:hidden;opacity:0;transition:opacity .2s linear}.tag-item-container:hover .tag-buttons,.tag-buttons:hover{visibility:visible;opacity:1}.toggle-editor-btn{position:fixed;top:50%;left:0;transform:translateY(-50%);background-color:#7289da;color:#fff;border:none;cursor:pointer;padding:10px;border-top-right-radius:5px;border-bottom-right-radius:5px;font-size:1rem;z-index:1006}.tags-container.hidden{display:none}.tags-container.visible{display:flex}:root{font-family:Inter,Avenir,Helvetica,Arial,sans-serif;font-size:16px;line-height:24px;font-weight:400;color:#ffffffde;background-color:#242424;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;-webkit-text-size-adjust:100%}a{font-weight:500;color:#646cff;text-decoration:inherit}a:hover{color:#535bf2}body{margin:0;display:flex;place-items:center;min-width:320px;min-height:100vh}h1{font-size:3.2em;line-height:1.1}button{border-radius:8px;border:1px solid transparent;padding:.6em 1.2em;font-size:1em;font-weight:500;font-family:inherit;background-color:#1a1a1a;cursor:pointer;transition:border-color .25s}button:hover{border-color:#646cff}button:focus,button:focus-visible{outline:4px auto -webkit-focus-ring-color}@media (prefers-color-scheme: light){:root{color:#213547;background-color:#fff}a:hover{color:#747bff}button{background-color:#f9f9f9}} "); (function (require$$0, require$$0$1) { 'use strict'; var jsxRuntime = { exports: {} }; var reactJsxRuntime_production_min = {}; /** * @license React * react-jsx-runtime.production.min.js * * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var f = require$$0, k = Symbol.for("react.element"), l = Symbol.for("react.fragment"), m$1 = Object.prototype.hasOwnProperty, n = f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner, p = { key: true, ref: true, __self: true, __source: true }; function q(c, a, g) { var b, d = {}, e = null, h = null; void 0 !== g && (e = "" + g); void 0 !== a.key && (e = "" + a.key); void 0 !== a.ref && (h = a.ref); for (b in a) m$1.call(a, b) && !p.hasOwnProperty(b) && (d[b] = a[b]); if (c && c.defaultProps) for (b in a = c.defaultProps, a) void 0 === d[b] && (d[b] = a[b]); return { $$typeof: k, type: c, key: e, ref: h, props: d, _owner: n.current }; } reactJsxRuntime_production_min.Fragment = l; reactJsxRuntime_production_min.jsx = q; reactJsxRuntime_production_min.jsxs = q; { jsxRuntime.exports = reactJsxRuntime_production_min; } var jsxRuntimeExports = jsxRuntime.exports; var client = {}; var m = require$$0$1; { client.createRoot = m.createRoot; client.hydrateRoot = m.hydrateRoot; } function PromptHistory({ key, activeTab, setTabs, onPromptsUpdate }) { const [prompts, setPrompts] = require$$0.useState(() => { const saved = localStorage.getItem(`promptsHistory_${activeTab.id}`); const parsed = saved ? JSON.parse(saved) : []; return Array.isArray(parsed) ? parsed : []; }); const [newPrompt, setNewPrompt] = require$$0.useState(""); const [newName, setNewName] = require$$0.useState(""); const addPrompt = () => { if (!newPrompt.trim()) return; const newEntry = { name: newName.trim() || `Prompt ${prompts.length + 1}`, prompt: newPrompt }; setTabs((tabs) => { const updatedTabs = tabs.map((t) => { if (t.id === activeTab.id) { const updatedPrompts = [...t.prompts, newEntry]; return { ...t, prompts: updatedPrompts }; } return t; }); return updatedTabs; }); setNewPrompt(""); setNewName(""); }; require$$0.useEffect(() => { console.log("Prompts have been updated:", prompts); }, [prompts]); const deletePrompt = (index) => { setTabs((tabs) => { return tabs.map((t) => { if (t.id === activeTab.id) { const updatedPrompts = t.prompts.filter((_, i) => i !== index); return { ...t, prompts: updatedPrompts }; } return t; }); }); }; const addToTextarea = (promptText) => { const textarea = document.querySelector("textarea.sc-a2d0901c-45.kyIdtk"); if (textarea) { const existingContent = textarea.value; textarea.value = existingContent + promptText; } }; const replaceTextArea = (promptText) => { const textarea = document.querySelector("textarea.sc-a2d0901c-45.kyIdtk"); if (textarea) { textarea.value; textarea.value = promptText; } }; const [showInput, setShowInput] = require$$0.useState(false); const updatePromptContent = (e, index) => { const updatedPromptText = e.target.innerText; setTabs((tabs) => { return tabs.map((tab) => { console.log("现在扫到tab:"); console.log(tab.id); console.log("现在的id是"); console.log(key); if (tab.id === activeTab.id) { const updatedPrompts = [...tab.prompts]; updatedPrompts[index] = { ...updatedPrompts[index], prompt: updatedPromptText }; return { ...tab, prompts: updatedPrompts }; } return tab; }); }); }; const updatePromptName = (e, index) => { const updatedName = e.target.innerText; setTabs((tabs) => { return tabs.map((tab) => { console.log("现在扫到tab:"); console.log(tab.id); console.log("现在的id是"); console.log(key); if (tab.id === activeTab.id) { const updatedPrompts = [...tab.prompts]; updatedPrompts[index] = { ...updatedPrompts[index], name: updatedName }; console.log(updatedPrompts); return { ...tab, prompts: updatedPrompts }; } return tab; }); }); }; return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { padding: "2px", backgroundColor: "#13152c", color: "#FFF" }, children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: activeTab.prompts.map((item, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ item && item.name && /* @__PURE__ */ jsxRuntimeExports.jsx( "div", { contentEditable: "true", suppressContentEditableWarning: true, onBlur: (e) => updatePromptName(e, index), dangerouslySetInnerHTML: { __html: item.name }, style: { border: "1px solid #ccc", minHeight: "20px", cursor: "text", padding: "5px", margin: "5px 0" } } ), item && item.prompt && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsx( "div", { contentEditable: "true", suppressContentEditableWarning: true, onBlur: (e) => updatePromptContent(e, index), dangerouslySetInnerHTML: { __html: item.prompt }, style: { border: "1px solid #ccc", minHeight: "20px", cursor: "text", padding: "5px" } } ) }), /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "asdasd", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "enter-button", onClick: () => addToTextarea(item.prompt), children: "+" }), /* @__PURE__ */ jsxRuntimeExports.jsx( "button", { className: "enter-button", onClick: () => replaceTextArea(item.prompt), children: "use" } ), /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "bin-button", onClick: () => deletePrompt(index), children: [ /* @__PURE__ */ jsxRuntimeExports.jsxs( "svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 39 7", className: "bin-top", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("line", { strokeWidth: "4", stroke: "white", y2: "5", x2: "39", y1: "5" }), /* @__PURE__ */ jsxRuntimeExports.jsx("line", { strokeWidth: "3", stroke: "white", y2: "1.5", x2: "26.0357", y1: "1.5", x1: "12" }) ] } ), /* @__PURE__ */ jsxRuntimeExports.jsxs( "svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 33 39", className: "bin-bottom", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("mask", { id: "path-1-inside-1_8_19", fill: "white", children: /* @__PURE__ */ jsxRuntimeExports.jsx( "path", { d: "M0 0H33V35C33 37.2091 31.2091 39 29 39H4C1.79086 39 0 37.2091 0 35V0Z" } ) }), /* @__PURE__ */ jsxRuntimeExports.jsx( "path", { mask: "url(#path-1-inside-1_8_19)", fill: "white", d: "M0 0H33H0ZM37 35C37 39.4183 33.4183 43 29 43H4C-0.418278 43 -4 39.4183 -4 35H4H29H37ZM4 43C-0.418278 43 -4 39.4183 -4 35V0H4V35V43ZM37 0V35C37 39.4183 33.4183 43 29 43V35V0H37Z" } ), /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeWidth: "4", stroke: "white", d: "M12 6L12 29" }), /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeWidth: "4", stroke: "white", d: "M21 6V29" }) ] } ) ] }) ] }) ] }, index)) }), /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "promptAddButton", onClick: () => setShowInput(!showInput), children: "+" }), showInput && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "input-group1", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx( "input", { value: newName, onChange: (e) => setNewName(e.target.value), required: "", type: "text", name: "text", autoComplete: "off", className: "input" } ), /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "user-label", children: "Prompt" }), /* @__PURE__ */ jsxRuntimeExports.jsx( "input", { value: newPrompt, onChange: (e) => setNewPrompt(e.target.value), required: "", type: "text", name: "text", autoComplete: "off", className: "input" } ), /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "user-label", children: "Content" }), /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: addPrompt, children: "Add Prompt" }) ] }) ] }); } function TabManager({ tabs, setTabs, searchResults, setSearchResults, onActiveTabChange }) { const [newTabName, setNewTabName] = require$$0.useState(""); const [activeTabId, setActiveTabId] = require$$0.useState(() => { const savedActiveTabId = localStorage.getItem("activeTabId"); return savedActiveTabId ? JSON.parse(savedActiveTabId) : 1; }); const [draggingTabId, setDraggingTabId] = require$$0.useState(null); const [, setPosition] = require$$0.useState({ x: 0, y: 0 }); const [dragging, setDragging] = require$$0.useState(false); const [startPos] = require$$0.useState({ x: 0, y: 0 }); require$$0.useEffect(() => { localStorage.setItem("tabs", JSON.stringify(tabs)); localStorage.setItem("activeTabId", JSON.stringify(activeTabId)); }, [tabs, activeTabId]); require$$0.useEffect(() => { const handleMouseMove = (e) => { if (!dragging) return; const dx = e.clientX - startPos.x; const dy = e.clientY - startPos.y; setPosition({ x: dx, y: dy }); }; const handleMouseUp = () => { if (dragging) { setDragging(false); } }; if (dragging) { document.addEventListener("mousemove", handleMouseMove); document.addEventListener("mouseup", handleMouseUp); } return () => { document.removeEventListener("mousemove", handleMouseMove); document.removeEventListener("mouseup", handleMouseUp); }; }, [dragging, startPos]); const addTab = () => { const numericIds = tabs.map((tab) => Number(tab.id)).filter((id) => !isNaN(id)); const maxId = numericIds.length > 0 ? Math.max(...numericIds) : 0; const newTabId = maxId + 1; const newTab = { id: newTabId, name: newTabName || `Tab ${tabs.length + 1}`, prompts: [] }; setTabs((prevTabs) => [...prevTabs, newTab]); setNewTabName(""); setActiveTabId(newTabId); onActiveTabChange(newTabId); setShowAddTab(false); setNewTabName(""); }; const deleteTab = (tabId) => { const tabToDelete = tabs.find((tab) => tab.id === tabId); if (tabToDelete && !tabToDelete.isFixed) { const updatedTabs = tabs.filter((tab) => tab.id !== tabId); setTabs(updatedTabs); if (activeTabId === tabId) { setActiveTabId(updatedTabs.length > 0 ? updatedTabs[0].id : null); onActiveTabChange(updatedTabs.length > 0 ? updatedTabs[0].id : null); } localStorage.setItem("tabs", JSON.stringify(updatedTabs)); if (activeTabId === tabId) { localStorage.setItem("activeTabId", JSON.stringify(updatedTabs.length > 0 ? updatedTabs[0].id : null)); } localStorage.removeItem(`promptsHistory_${tabId}`); } }; const [, setButtonPosition] = require$$0.useState({ top: 0, left: 0 }); require$$0.useEffect(() => { const updateButtonPosition = () => { const promptElement = document.querySelector(".sc-b22b5055-22.ktRRzG"); if (promptElement) { const rect = promptElement.getBoundingClientRect(); setButtonPosition({ top: rect.top + window.scrollY - 10, left: rect.right + 10 }); } }; const observer = new MutationObserver(() => { updateButtonPosition(); }); const config = { childList: true, subtree: true }; const targetNode = document.body; observer.observe(targetNode, config); updateButtonPosition(); return () => observer.disconnect(); }, []); const handleTabChange = (id) => { setActiveTabId(id); onActiveTabChange(id); }; const handleDragStart = (id) => () => { setDraggingTabId(id); }; const handleDragOver = (e) => { e.preventDefault(); }; const handleDrop = (targetId) => (e) => { e.preventDefault(); const draggedTabIndex = tabs.findIndex((tab) => tab.id === draggingTabId); const targetTabIndex = tabs.findIndex((tab) => tab.id === targetId); if (draggedTabIndex !== -1 && targetTabIndex !== -1) { const newTabs = Array.from(tabs); const [removed] = newTabs.splice(draggedTabIndex, 1); newTabs.splice(targetTabIndex, 0, removed); setTabs(newTabs); } setDraggingTabId(null); }; const [showAddTab, setShowAddTab] = require$$0.useState(false); require$$0.useEffect(() => { if (showAddTab) { const inputElement = document.querySelector(".input1"); inputElement && inputElement.focus(); } }, [showAddTab]); const [searchTerm, setSearchTerm] = require$$0.useState(""); const [expandedResults, setExpandedResults] = require$$0.useState(/* @__PURE__ */ new Map()); require$$0.useEffect(() => { if (searchTerm.trim() === "") { setSearchResults([]); return; } const results = /* @__PURE__ */ new Map(); tabs.forEach((tab) => { tab.prompts.forEach((prompt) => { if (prompt.name.includes(searchTerm) || prompt.prompt.includes(searchTerm)) { const key = `${prompt.name}:${prompt.prompt}`; if (!results.has(key)) { results.set(key, prompt); } } }); }); setSearchResults(Array.from(results.values())); }, [searchTerm, tabs, setSearchResults]); const toggleExpandResult = (key) => { setExpandedResults((prev) => { const newExpanded = new Map(prev); newExpanded.set(key, !newExpanded.get(key)); return newExpanded; }); }; function truncateText(text, maxLength) { if (text.length <= maxLength) { return text; } return `${text.substring(0, maxLength)}...`; } const addToTextarea = (promptText) => { const textarea = document.querySelector("textarea.sc-a2d0901c-45.kyIdtk"); if (textarea) { const existingContent = textarea.value; textarea.value = existingContent + promptText; } }; const replaceTextArea = (promptText) => { const textarea = document.querySelector("textarea.sc-a2d0901c-45.kyIdtk"); if (textarea) { textarea.value; textarea.value = promptText; } }; const handlePromptsUpdate = (updatedPrompts) => { const updatedTabs = tabs.map((tab) => { if (tab.id === activeTabId) { return { ...tab, prompts: updatedPrompts }; } return tab; }); console.log("修改"); setTabs(updatedTabs); localStorage.setItem("tabs", JSON.stringify(updatedTabs)); }; const activeTab = tabs.find((tab) => tab.id === activeTabId); return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "tab-manager-container", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "search-results", children: searchResults.map((result, index) => { const key = `${result.name}:${index}`; const isExpanded = expandedResults.get(key); return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "search-result-item", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { children: result.name }), /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: isExpanded ? result.prompt : truncateText(result.prompt, 100) }), /* @__PURE__ */ jsxRuntimeExports.jsx( "button", { className: "more-button", onClick: () => toggleExpandResult(key), children: isExpanded ? "less" : "more" } ), /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "enter-button", onClick: () => addToTextarea(result.prompt), children: "+" }), /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "enter-button", onClick: () => replaceTextArea(result.prompt), children: "use" }) ] }, key); }) }), /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "search-container", children: /* @__PURE__ */ jsxRuntimeExports.jsx( "input", { type: "text", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), placeholder: "Search..." } ) }), /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "tabs-bar", children: [ tabs.map((tab) => /* @__PURE__ */ jsxRuntimeExports.jsxs( "div", { className: `tab ${tab.id === activeTabId ? "active" : ""}`, draggable: !tab.isFixed, onDragStart: tab.isFixed ? null : handleDragStart(tab.id), onDragOver: handleDragOver, onDrop: handleDrop(tab.id), onClick: () => handleTabChange(tab.id), children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: tab.name }), !tab.isFixed && /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "bin-button", onClick: () => deleteTab(tab.id), children: [ /* @__PURE__ */ jsxRuntimeExports.jsxs( "svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 39 7", className: "bin-top", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("line", { strokeWidth: "4", stroke: "white", y2: "5", x2: "39", y1: "5" }), /* @__PURE__ */ jsxRuntimeExports.jsx("line", { strokeWidth: "3", stroke: "white", y2: "1.5", x2: "26.0357", y1: "1.5", x1: "12" }) ] } ), /* @__PURE__ */ jsxRuntimeExports.jsxs( "svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 33 39", className: "bin-bottom", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("mask", { id: "path-1-inside-1_8_19", fill: "white", children: /* @__PURE__ */ jsxRuntimeExports.jsx( "path", { d: "M0 0H33V35C33 37.2091 31.2091 39 29 39H4C1.79086 39 0 37.2091 0 35V0Z" } ) }), /* @__PURE__ */ jsxRuntimeExports.jsx( "path", { mask: "url(#path-1-inside-1_8_19)", fill: "white", d: "M0 0H33H0ZM37 35C37 39.4183 33.4183 43 29 43H4C-0.418278 43 -4 39.4183 -4 35H4H29H37ZM4 43C-0.418278 43 -4 39.4183 -4 35V0H4V35V43ZM37 0V35C37 39.4183 33.4183 43 29 43V35V0H37Z" } ), /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeWidth: "4", stroke: "white", d: "M12 6L12 29" }), /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeWidth: "4", stroke: "white", d: "M21 6V29" }) ] } ), /* @__PURE__ */ jsxRuntimeExports.jsx( "svg", { xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 89 80", className: "garbage", children: /* @__PURE__ */ jsxRuntimeExports.jsx( "path", { fill: "white", d: "M20.5 10.5L...L35.5 79.5L28 67L16 63L12 51.5L0 48L16 25L22.5 17L20.5 10.5Z" } ) } ) ] }) ] }, tab.id )), /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => { setShowAddTab(true); }, className: "add-tab-button", children: "+" }), showAddTab && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `input-group ${showAddTab ? "show" : ""}`, children: [ /* @__PURE__ */ jsxRuntimeExports.jsx( "input", { value: newTabName, onChange: (e) => setNewTabName(e.target.value), required: "", type: "text", name: "text", autoComplete: "off", className: "input1" } ), /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "user-label", children: "Tab" }), /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: addTab, className: "button", children: "Add Tab" }) ] }) ] }), /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "tab-content", children: activeTab ? /* @__PURE__ */ jsxRuntimeExports.jsx( PromptHistory, { activeTab, setTabs, onPromptsUpdate: handlePromptsUpdate }, activeTab.id ) : null }) ] }); } function TextAreaItemsEditor() { const [items, setItems] = require$$0.useState([]); const [isEditorVisible, setIsEditorVisible] = require$$0.useState(false); const [draggedItemIndex, setDraggedItemIndex] = require$$0.useState(null); const [dragging, setDragging] = require$$0.useState(false); const handleDragStart = (e, index) => { setDraggedItemIndex(index); setDragging(true); e.dataTransfer.effectAllowed = "move"; e.dataTransfer.setData("text/plain", ""); e.currentTarget.classList.add("dragging"); }; const handleDragOver = (e, index) => { e.preventDefault(); e.dataTransfer.dropEffect = "move"; }; const handleDragEnd = (e) => { setDragging(false); e.currentTarget.classList.remove("dragging"); }; const handleDrop = (e, targetIndex) => { e.preventDefault(); if (draggedItemIndex === null || draggedItemIndex === targetIndex) return; const newItems = [...items]; const [item] = newItems.splice(draggedItemIndex, 1); const newIndex = draggedItemIndex < targetIndex ? targetIndex - 1 : targetIndex; newItems.splice(newIndex, 0, item); setItems(newItems); updateTextArea(newItems); setDraggedItemIndex(null); }; require$$0.useEffect(() => { const observer = new MutationObserver((mutations, obs) => { const textArea = document.querySelector("textarea.sc-a2d0901c-45.kyIdtk"); if (textArea) { setItems(splitContent(textArea.value)); const handleInput = () => { setItems(splitContent(textArea.value)); }; textArea.addEventListener("input", handleInput); obs.disconnect(); return () => { textArea.removeEventListener("input", handleInput); }; } }); observer.observe(document.body, { childList: true, subtree: true }); const splitContent = (content) => { const pattern = /{(.*?)}|([^,]+)/g; let match; let initialItems = []; while ((match = pattern.exec(content)) !== null) { initialItems.push(match[1] ? `{${match[1]}}` : match[0].trim()); } return initialItems; }; return () => observer.disconnect(); }, []); const updateTextArea = (newItems) => { const textArea = document.querySelector("textarea.sc-a2d0901c-45.kyIdtk"); if (textArea) { textArea.value = newItems.join(", "); } }; const handleItemUpdate = (index, newItem) => { const newItems = [...items]; newItems[index] = newItem; setItems(newItems); updateTextArea(newItems); }; const handleItemDelete = (index) => { const newItems = items.filter((_, i) => i !== index); setItems(newItems); updateTextArea(newItems); }; const handleAddBraces = (index, openingBrace, closingBrace) => { const newItems = [...items]; newItems[index] = openingBrace + newItems[index] + closingBrace; setItems(newItems); updateTextArea(newItems); }; const handleRemoveBraces = (index) => { let newItem = items[index]; if (newItem.startsWith("{") && newItem.endsWith("}")) { newItem = newItem.slice(1, -1); } else if (newItem.startsWith("[") && newItem.endsWith("]")) { newItem = newItem.slice(1, -1); } const newItems = [...items]; newItems[index] = newItem; setItems(newItems); updateTextArea(newItems); }; return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ /* @__PURE__ */ jsxRuntimeExports.jsx( "button", { className: "toggle-editor-btn", onClick: () => setIsEditorVisible(!isEditorVisible), children: isEditorVisible ? "<" : ">" } ), /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `tags-container ${isEditorVisible ? "visible" : "hidden"}`, children: items.map((item, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs( "div", { className: "tag-item-container", draggable: "true", onDragStart: (e) => handleDragStart(e, index), onDragOver: (e) => handleDragOver(e), onDragEnd: handleDragEnd, onDrop: (e) => handleDrop(e, index), children: [ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "tag-buttons", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "edit-tag", onClick: () => handleAddBraces(index, "{", "}"), children: "丄" }), /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "edit-tag", onClick: () => handleAddBraces(index, "[", "]"), children: "丅" }), /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "edit-tag", onClick: () => handleRemoveBraces(index), children: "一" }) ] }), /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "tag-item", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx( "span", { contentEditable: true, className: "tag-content", onBlur: (e) => handleItemUpdate(index, e.target.textContent), dangerouslySetInnerHTML: { __html: item } } ), /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "delete-tag", onClick: () => handleItemDelete(index), children: "x" }) ] }) ] }, index )) }) ] }); } function SideDrawer({ triggerSelector }) { const [isVisible, setIsVisible] = require$$0.useState(true); const triggerRef = require$$0.useRef(); const [buttonPosition, setButtonPosition] = require$$0.useState({ top: 0, left: 0 }); const [tabs, setTabs] = require$$0.useState(() => { const savedTabs = localStorage.getItem("tabs"); const parsedTabs = savedTabs ? JSON.parse(savedTabs) : null; console.log(savedTabs); const defaultTabs = [ { id: "favorites", name: "收藏", prompts: [], isFixed: true }, { id: "history", name: "历史", prompts: [], isFixed: true } ]; return Array.isArray(parsedTabs) && parsedTabs.length > 0 ? parsedTabs : defaultTabs; }); const [activeTabId, setActiveTabId] = require$$0.useState(null); const handleActiveTabChange = (newActiveTabId) => { setActiveTabId(newActiveTabId); }; require$$0.useEffect(() => { localStorage.setItem("tabs", JSON.stringify(tabs)); }, [tabs]); const addPromptToFavorites = () => { const textArea = document.querySelector("textarea.sc-a2d0901c-45.kyIdtk"); if (textArea) { const promptText = textArea.value; const favoritesTab = tabs.find((tab) => tab.id === "favorites"); if (favoritesTab && Array.isArray(favoritesTab.prompts)) { const isDuplicate = favoritesTab.prompts.some((prompt) => (prompt == null ? void 0 : prompt.prompt) === promptText); if (!isDuplicate) { const newName = `Prompt ${favoritesTab.prompts.length + 1}`; const newPrompt = { name: newName, prompt: promptText }; const updatedTabs = tabs.map((tab) => { if (tab.id === "favorites") { const updatedPrompts = [...tab.prompts, newPrompt]; return { ...tab, prompts: updatedPrompts }; } return tab; }); setTabs(updatedTabs); console.log(updatedTabs); localStorage.setItem("tabs", JSON.stringify(updatedTabs)); } } } }; const addPromptToActiveTab = () => { const textArea = document.querySelector("textarea.sc-a2d0901c-45.kyIdtk"); if (textArea) { const promptText = textArea.value; console.log("标记"); const activeTab = tabs.find((tab) => tab.id === activeTabId); if (activeTab && Array.isArray(activeTab.prompts)) { const isDuplicate = activeTab.prompts.some((prompt) => (prompt == null ? void 0 : prompt.prompt) === promptText); if (!isDuplicate) { const newName = `Prompt ${activeTab.prompts.length + 1}`; const newPrompt = { name: newName, prompt: promptText }; setTabs((tabs2) => tabs2.map((tab) => { if (tab.id === activeTab.id) { return { ...tab, prompts: [...tab.prompts, newPrompt] }; } return tab; })); } } } }; const [isFavorited, setIsFavorited] = require$$0.useState(false); require$$0.useEffect(() => { if (isFavorited) { addPromptToFavorites(); const timer = setTimeout(() => { setIsFavorited(false); }, 300); return () => clearTimeout(timer); } }, [isFavorited]); const handleFavoriteClick = () => { setIsFavorited(true); }; const toggleDrawer = () => { setIsVisible((prevState) => !prevState); }; const setTriggerPosition = require$$0.useCallback(() => { const triggerElement = document.querySelector(triggerSelector); if (triggerElement && triggerRef.current) { const { right, top, height } = triggerElement.getBoundingClientRect(); triggerRef.current.style.top = `${top}px`; triggerRef.current.style.height = `${height}px`; triggerRef.current.style.left = `${right + 13}px`; console.log(triggerRef.current.style.left); } const promptElement1 = document.querySelector(".sc-b22b5055-22.ktRRzG"); if (promptElement1) { const promptElementRect = promptElement1.getBoundingClientRect(); setButtonPosition({ top: promptElementRect.top + window.scrollY - 10, // 加上滚动偏移量 left: promptElementRect.right + 10 // 右侧偏移10px }); } }, [triggerSelector]); require$$0.useEffect(() => { const observer = new MutationObserver((mutationsList) => { for (const mutation of mutationsList) { if (mutation.type === "childList") { setTriggerPosition(); const promptElement = document.querySelector(".sc-b22b5055-22.ktRRzG"); if (promptElement) { const promptElementRect = promptElement.getBoundingClientRect(); setButtonPosition({ top: promptElementRect.top + window.scrollY - 10, // 加上滚动偏移量 left: promptElementRect.right + 10 // 右侧偏移10px }); } observer.disconnect(); break; } } }); observer.observe(document.body, { childList: true, subtree: true }); return () => observer.disconnect(); }, [setTriggerPosition, triggerSelector]); require$$0.useEffect(() => { setTriggerPosition(); window.addEventListener("resize", setTriggerPosition); return () => window.removeEventListener("resize", setTriggerPosition); }, [setTriggerPosition]); require$$0.useEffect(() => { const observer = new MutationObserver((mutationsList) => { for (const mutation of mutationsList) { if (mutation.type === "childList") { const triggerElement = document.querySelector(triggerSelector); if (triggerElement) { setTriggerPosition(); const targetElement = document.querySelector(".sc-b22b5055-0.kWaZHl"); if (targetElement) { targetElement.style.zIndex = "1001"; } observer.disconnect(); break; } } } }); observer.observe(document.body, { childList: true, subtree: true }); return () => observer.disconnect(); }, [setTriggerPosition, triggerSelector]); const [, setOffset] = require$$0.useState(0); require$$0.useEffect(() => { if (isVisible) { setOffset((prevOffset) => prevOffset + 10); } }, [isVisible]); const addToHistory = (promptText) => { if (typeof promptText !== "string" || !promptText.trim()) { console.warn("Invalid promptText provided to addToHistory"); return; } console.log(tabs); setTabs((tabs2) => tabs2.map((tab) => { if (tab.id === "history") { const isDuplicate = tab.prompts.some((prompt) => (prompt == null ? void 0 : prompt.prompt) === promptText); if (!isDuplicate) { return { ...tab, prompts: [...tab.prompts, { name: `Prompt ${tab.prompts.length + 1}`, prompt: promptText }] }; } else { return tab; } } return tab; })); }; const handleButtonClick = () => { const inputText = document.querySelector("textarea").value; addToHistory(inputText); }; require$$0.useEffect(() => { const observer = new MutationObserver((mutations) => { for (const mutation of mutations) { if (mutation.addedNodes.length) { const button = document.querySelector(".sc-d72450af-1.sc-2fe5a182-20.kXFbYD.kHiDKS"); if (button) { button.addEventListener("click", handleButtonClick); observer.disconnect(); break; } } } }); observer.observe(document.body, { childList: true, subtree: true }); return () => { observer.disconnect(); const button = document.querySelector(".sc-d72450af-1.sc-2fe5a182-20.kXFbYD.kHiDKS"); if (button) { button.removeEventListener("click", handleButtonClick); } }; }, []); require$$0.useEffect(() => { const observer = new MutationObserver((mutationsList, observer2) => { for (const mutation of mutationsList) { if (mutation.type === "childList") { const button = document.querySelector(".sc-d72450af-1.sc-2fe5a182-20.kXFbYD.kHiDKS"); if (button) { button.addEventListener("click", handleButtonClick); observer2.disconnect(); break; } } } }); observer.observe(document.body, { childList: true, subtree: true }); return () => observer.disconnect(); }, []); const [searchResults, setSearchResults] = require$$0.useState([]); return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "thing", children: [ /* @__PURE__ */ jsxRuntimeExports.jsxs( "button", { className: "animated-button", onClick: toggleDrawer, style: { top: "650px", left: `0px` }, children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", className: "arr-2", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsxRuntimeExports.jsx( "path", { d: "M16.1716 10.9999L10.8076 5.63589L12.2218 4.22168L20 11.9999L12.2218 19.778L10.8076 18.3638L16.1716 12.9999H4V10.9999H16.1716Z" } ) }), /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text", children: "Prompt Tab" }), /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "circle" }), /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", className: "arr-1", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsxRuntimeExports.jsx( "path", { d: "M16.1716 10.9999L10.8076 5.63589L12.2218 4.22168L20 11.9999L12.2218 19.778L10.8076 18.3638L16.1716 12.9999H4V10.9999H16.1716Z" } ) }) ] } ), /* @__PURE__ */ jsxRuntimeExports.jsxs( "label", { className: "container", style: { top: "645px", left: `145px` }, children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("input", { type: "checkbox", onClick: handleFavoriteClick, readOnly: true, checked: isFavorited }), /* @__PURE__ */ jsxRuntimeExports.jsx( "svg", { height: "24px", id: "Layer_1", version: "1.2", viewBox: "0 0 24 24", width: "24px", "xml:space": "preserve", xmlns: "http://www.w3.org/2000/svg", "xmlns:xlink": "http://www.w3.org/1999/xlink", children: /* @__PURE__ */ jsxRuntimeExports.jsx("g", { children: /* @__PURE__ */ jsxRuntimeExports.jsx("g", { children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M9.362,9.158c0,0-3.16,0.35-5.268,0.584c-0.19,0.023-0.358,0.15-0.421,0.343s0,0.394,0.14,0.521 c1.566,1.429,3.919,3.569,3.919,3.569c-0.002,0-0.646,3.113-1.074,5.19c-0.036,0.188,0.032,0.387,0.196,0.506 c0.163,0.119,0.373,0.121,0.538,0.028c1.844-1.048,4.606-2.624,4.606-2.624s2.763,1.576,4.604,2.625 c0.168,0.092,0.378,0.09,0.541-0.029c0.164-0.119,0.232-0.318,0.195-0.505c-0.428-2.078-1.071-5.191-1.071-5.191 s2.353-2.14,3.919-3.566c0.14-0.131,0.202-0.332,0.14-0.524s-0.23-0.319-0.42-0.341c-2.108-0.236-5.269-0.586-5.269-0.586 s-1.31-2.898-2.183-4.83c-0.082-0.173-0.254-0.294-0.456-0.294s-0.375,0.122-0.453,0.294C10.671,6.26,9.362,9.158,9.362,9.158z" }) }) }) } ) ] } ), /* @__PURE__ */ jsxRuntimeExports.jsx( "label", { className: "container1", style: { top: "650px", left: `215px` }, children: /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "container1", onClick: addPromptToActiveTab, children: "Add to Current->" }) } ), /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: `side-drawer ${isVisible ? "visible" : ""}`, children: /* @__PURE__ */ jsxRuntimeExports.jsx( TabManager, { tabs, setTabs, onActiveTabChange: handleActiveTabChange, addPromptToFavorites, searchResults, setSearchResults } ) }), /* @__PURE__ */ jsxRuntimeExports.jsx(TextAreaItemsEditor, {}) ] }); } function App() { return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "App", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SideDrawer, { triggerSelector: ".sc-5db1afd3-16.bwGvYE" }) }); } client.createRoot( (() => { const app = document.createElement("div"); document.body.append(app); return app; })() ).render( /* @__PURE__ */ jsxRuntimeExports.jsx(require$$0.StrictMode, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(App, {}) }) ); })(React, ReactDOM);