userscripts/chatgpt-chat-prefixer/ChatGPTChatPrefixer.user.js

130 lines
3.5 KiB
JavaScript

// ==UserScript==
// @name Prefix ChatGPT chats with "S:"
// @namespace http://tampermonkey.net/
// @version 2024-11-23T16:11:30+05:30
// @description For TOTALLY legit usage reasons...
// @author Sangeeth Sudheer
// @match https://chatgpt.com/*
// @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~="bg-token-sidebar-surface-secondary"])',
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();
}
async function getStableLabelText(el) {
while (true) {
const prev = el.textContent.trim();
await wait(1000);
const curr = el.textContent.trim();
if (prev === curr) {
return curr;
}
}
}
async function main() {
try {
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 = await getStableLabelText(menuItem.querySelector("a"));
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(100);
document.querySelector(sels.renamePopoverItem).click();
await wait(500);
const input = menuItem.querySelector("input");
const prevValue = input.value;
input.focus();
await wait(100);
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(100);
console.log("Renamed chat");
} finally {
setTimeout(main, 5000);
}
}
setTimeout(main, 5000);
})();