Skip to content

Instantly share code, notes, and snippets.

@rf5860
Created July 28, 2023 09:54
Show Gist options
  • Save rf5860/2b4e87492b9847a7941966d55e828982 to your computer and use it in GitHub Desktop.
Save rf5860/2b4e87492b9847a7941966d55e828982 to your computer and use it in GitHub Desktop.
Adds a button to scroll to the top of a ChatGPT chat
// ==UserScript==
// @name ChatGPT TopScroll Arrow
// @author rf5860
// @version 1.0
// @description Adds a button to scroll to the top of a ChatGPT chat
// @match https://chat.openai.com/*
// @grant none
// ==/UserScript==
var DEBUG = false; // Set to true to enable debug logging, false to disable
function debug(message) {
if (DEBUG) {
console.log(message);
}
}
debug("Script start");
// Create the scroll to top button
function createButton() {
debug("Creating button");
var button = document.createElement("button");
button.className = "cursor-pointer absolute right-6 bottom-[134px] md:bottom-[130px] z-10 rounded-full border border-gray-200 bg-gray-50 text-gray-600 dark:border-white/10 dark:bg-white/10 dark:text-gray-200";
button.id = "scrollUpButton";
button.style.bottom = "160px";
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svg.setAttribute("stroke", "currentColor");
svg.setAttribute("fill", "none");
svg.setAttribute("stroke-width", "2");
svg.setAttribute("viewBox", "0 0 24 24");
svg.setAttribute("stroke-linecap", "round");
svg.setAttribute("stroke-linejoin", "round");
svg.setAttribute("class", "h-4 w-4 m-1");
svg.setAttribute("height", "1em");
svg.setAttribute("width", "1em");
var line = document.createElementNS("http://www.w3.org/2000/svg", "line");
line.setAttribute("x1", "12");
line.setAttribute("y1", "19");
line.setAttribute("x2", "12");
line.setAttribute("y2", "5");
var polyline = document.createElementNS("http://www.w3.org/2000/svg", "polyline");
polyline.setAttribute("points", "5 12 12 5 19 12");
svg.appendChild(line);
svg.appendChild(polyline);
button.appendChild(svg);
// Add the mousedown event listener
button.addEventListener('mousedown', function() {
// Change the outline to orange
button.style.outline = '2px solid orange';
});
// Add the mouseup event listener
button.addEventListener('mouseup', function() {
// Remove the outline
button.style.outline = '';
});
// Add the click event listener
button.addEventListener('click', function() {
// Scroll to the top of the document body or html
document.querySelectorAll('div[class*="react-scroll-to-bottom"]').forEach(e => {
e.scrollTo({
top: 0,
behavior: 'smooth' // Optional: smooth scrolling
});
})
});
return button;
}
var scrollTopButton = createButton();
var appended = false;
// Create a mutation observer to watch for changes in the chat window
var observer = new MutationObserver(function(mutations) {
debug("Mutation observed");
if (!appended && !!document.querySelector('div>div.relative >div.flex.h-full.flex-col')) {
debug("Adding scroll to top button");
appended = true;
document.querySelector('div>div.relative >div.flex.h-full.flex-col').parentElement.appendChild(scrollTopButton);
}
});
debug("Starting to observe");
// Start observing the chat window with the configured mutation observer
observer.observe(document.body, {
childList: true, subtree: true
, attributes: true
, characterData: false
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment