From db155fbe27157239663da7b095e8b6522df90068 Mon Sep 17 00:00:00 2001 From: x0x7 Date: Sat, 8 Feb 2025 12:41:00 -0500 Subject: [PATCH] Add Save Prompt userscript --- saveprompt.user.js | 78 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 saveprompt.user.js diff --git a/saveprompt.user.js b/saveprompt.user.js new file mode 100644 index 0000000..4b95532 --- /dev/null +++ b/saveprompt.user.js @@ -0,0 +1,78 @@ +// ==UserScript== +// @name Save Unsent AI Prompts +// @namespace Violent Monkey Scripts +// @version 1.0 +// @description Auto-save unsent AI prompts as drafts +// @match https://chatgpt.com/* +// @grant none +// ==/UserScript== + + +//This userscript will save any prompt you write into chatgpt into your local storage +//This means if a tab gets closed and you had a very well thought out prompt that gets lost you can still dig for it +//Prompts are saved by their unix timestamp + +(async function(){ + function timeout(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + // Continuously looks for new #prompt-textarea divs + async function* targetDivs() { + let found = new Set(); + while(true) { + let divs = document.querySelectorAll('#prompt-textarea'); + for(let div of divs) { + if(!found.has(div)) { + found.add(div); + yield div; + } + } + await timeout(500); + } + } + for await (let newTarget of targetDivs()) { + applyHandler(newTarget); + } +})(); + +function shouldSaveDraft(oldVal, newVal) { + // Save if text was added or replaced (not pure deletion). + if (newVal.length > oldVal.length) return true; + if (newVal.length === oldVal.length && newVal !== oldVal) return true; + return false; +} + +function saveDraft(id, text) { + localStorage.setItem('draft-'+id, text); +} + +function applyHandler(div) { + let currentId = null; + let oldValue = ''; + + // Called whenever mutations occur + function onDivMutate() { + let newValue = div.innerHTML.trim(); + if (!newValue) { + // If there's nothing left, reset + currentId = null; + oldValue = ''; + return; + } + // If we had no oldValue, this is the first time we're typing => new ID + if (!oldValue || !currentId) { + currentId = Date.now(); + } + // Only save if something was added (newValue got longer than oldValue) + if(shouldSaveDraft(oldValue,newValue)) { + saveDraft(currentId,newValue); + } + // Update the known current content + oldValue = newValue; + } + + // Observe changes in the div (childList & characterData changes) + let observer = new MutationObserver(onDivMutate); + observer.observe(div, {childList: true, characterData: true, subtree: true}); +}