diff --git a/chatgpt-chat-prefixer/ChatGPTChatPrefixer.user.js b/chatgpt-chat-prefixer/ChatGPTChatPrefixer.user.js new file mode 100644 index 0000000..56ea0bb --- /dev/null +++ b/chatgpt-chat-prefixer/ChatGPTChatPrefixer.user.js @@ -0,0 +1,126 @@ +// ==UserScript== +// @name Prefix ChatGPT chats with "S:" +// @namespace http://tampermonkey.net/ +// @version 2024-11-23 +// @description For TOTALLY legit usage reasons... +// @author Sangeeth Sudheer +// @match https://chatgpt.com/c/* +// @icon https://www.google.com/s2/favicons?sz=64&domain=chatgpt.com +// @updateURL https://git.sangeeth.dev/x/userscripts/raw/branch/main/chatgpt-chat-prefixer/ChatGPTChatPrefixer.user.js +// @downloadURL https://git.sangeeth.dev/x/userscripts/raw/branch/main/chatgpt-chat-prefixer/ChatGPTChatPrefixer.user.js +// @grant none +// ==/UserScript== + +(function() { + 'use strict'; + + const PREFIX = "S: "; + + const sels = { + activeChatSidebarItem: '[data-testid^="history-item"]:has(> [class*="active"])', + renamePopoverItem: '[data-testid="share-chat-menu-item"] + div', + } + + function triggerEnterKey(el) { + const event = new KeyboardEvent('keydown', { + key: 'Enter', + code: 'Enter', + bubbles: true + }); + + el.dispatchEvent(event); + } + + function wait(ms) { + const { resolve, reject, promise } = Promise.withResolvers(); + + setTimeout(resolve, ms); + + return promise; + } + + function waitFor(sel, el = document) { + const { resolve, reject, promise } = Promise.withResolvers(); + let count = 0; + + function _wait() { + if (el.querySelector(sel)) { + resolve(); + } + + ++count; + + if (count >= 5) { + reject(); + } + + setTimeout(_wait, 1000); + } + + _wait(); + } + + let isRunning = false; + + async function main() { + try { + if (isRunning) { + console.log("Script already running"); + return; + } + + isRunning = true; + + const menuItem = document.querySelector(sels.activeChatSidebarItem); + + if (!menuItem) { + console.log("Active chat menu item wasn't found. You're either not on the regular chat page or the markup has changed"); + return; + } + + const label = menuItem.querySelector("a").textContent.trim(); + + if (/new chat/i.test(label)) { + console.log("Chat label isn't yet autopopulated by LLM"); + return; + } + + if (label.startsWith(PREFIX)) { + console.log("No need to rename chat"); + return; + } + + triggerEnterKey(menuItem.querySelector("button")); + await wait(500); + + document.querySelector(sels.renamePopoverItem).click(); + await wait(2000); + + const input = menuItem.querySelector("input"); + const prevValue = input.value; + + input.focus(); + await wait(500); + + input.value = `${PREFIX}${label}`; + + if (input._valueTracker) { + input._valueTracker.setValue(prevValue); + } + + const inputEvent = new Event('input', { bubbles: true }); + input.dispatchEvent(inputEvent); + + triggerEnterKey(input); + await wait(500); + + console.log("Renamed chat"); + isRunning = false; + } finally { + isRunning = false; + } + } + + + setInterval(main, 5000); +})();