Skip to content

Instantly share code, notes, and snippets.

@darotar
Last active February 22, 2024 07:55
Show Gist options
  • Save darotar/bb2cc301f5dc642b5e0b0f8bf0281de0 to your computer and use it in GitHub Desktop.
Save darotar/bb2cc301f5dc642b5e0b0f8bf0281de0 to your computer and use it in GitHub Desktop.
Custom key bindings for Chat Open AI using TamperMonkey
// ==UserScript==
// @name Custom Key Bindings for Chat.OpenAI
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Add custom key bindings to Chat.OpenAI
// @author You
// @match https://chat.openai.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=openai.com
// @grant none
// ==/UserScript==
(function() {
'use strict';
let currentSelectionIndex = -1; // No selection initially
function setupInputStyles(inputOverlay) {
inputOverlay.style.position = 'fixed';
inputOverlay.style.top = '10px';
inputOverlay.style.left = '50%';
inputOverlay.style.transform = 'translateX(-50%)';
inputOverlay.style.zIndex = '10000';
inputOverlay.style.width = '80%';
inputOverlay.style.padding = '10px';
inputOverlay.style.fontSize = '16px';
}
function setupDropdownStyles(dropdown) {
dropdown.style.position = 'fixed';
dropdown.style.top = '50px';
dropdown.style.left = '50%';
dropdown.style.transform = 'translateX(-50%)';
dropdown.style.zIndex = '10000';
dropdown.style.width = '80%';
dropdown.style.maxHeight = '300px';
dropdown.style.overflowY = 'auto';
dropdown.style.background = '#3b3b3b';
dropdown.style.border = '1px solid #ccc';
dropdown.style.boxShadow = '0 4px 6px rgba(0,0,0,.1)';
}
function updateDropdown(value, dropdown) {
// Clear previous results
dropdown.innerHTML = '';
// Get all li elements
const items = Array.from(document.querySelector('nav').querySelectorAll('li')).filter(li => li.querySelector('div > a > div').textContent.toLowerCase().includes(value.toLowerCase()));
// Create a dropdown item for each match
items.forEach(item => {
const div = document.createElement('div');
div.style.padding = '10px';
div.style.borderBottom = '1px solid #eee';
div.textContent = item.querySelector('div > a > div').textContent;
div.setAttribute('data-link', item.querySelector('div > a').attributes.href.value);
div.addEventListener('click', () => {
document.getElementById('customInputOverlay').value = div.textContent;
dropdown.innerHTML = ''; // Clear dropdown after selection
});
dropdown.appendChild(div);
});
// Show or hide dropdown based on matches
dropdown.style.display = items.length > 0 ? '' : 'none';
}
function createInputOverlay() {
// Check if the input already exists
let inputOverlay = document.getElementById('customInputOverlay');
if (!inputOverlay) {
// Create the input element
inputOverlay = document.createElement('input');
inputOverlay.id = 'customInputOverlay';
setupInputStyles(inputOverlay);
// Append the input to the body
document.body.appendChild(inputOverlay);
// Focus the input
inputOverlay.focus();
let dropdown = document.createElement('div');
dropdown.id = 'customInputDropdown';
setupDropdownStyles(dropdown);
document.body.appendChild(dropdown);
inputOverlay.addEventListener('input', function() {
updateDropdown(inputOverlay.value, dropdown);
});
// Handle the enter key (submit)
inputOverlay.addEventListener('keydown', function(e) {
const items = dropdown.querySelectorAll('div');
if (e.key === 'ArrowDown') {
e.preventDefault();
if (currentSelectionIndex < items.length - 1) {
currentSelectionIndex++;
updateHighlight(items);
}
} else if (e.key === 'ArrowUp') {
e.preventDefault();
if (currentSelectionIndex > 0) {
currentSelectionIndex--;
updateHighlight(items);
}
} else if (e.key === 'Enter') {
e.preventDefault();
if (currentSelectionIndex >= 0 && currentSelectionIndex < items.length) {
document.querySelector(`a[href="${items[currentSelectionIndex].dataset.link}"]`).click();
inputOverlay.value = items[currentSelectionIndex].textContent;
dropdown.innerHTML = '';
dropdown.style.display = 'none';
document.getElementById('customInputOverlay').remove();
document.getElementById('customInputDropdown').remove();
currentSelectionIndex = -1;
}
}
});
} else {
document.getElementById('customInputOverlay').remove();
document.getElementById('customInputDropdown').remove();
currentSelectionIndex = -1;
}
}
function updateHighlight(items) {
// Remove highlight from all items
items.forEach(item => {
item.style.background = '#3b3b3b';
});
// Highlight the current selection
if (items[currentSelectionIndex]) {
items[currentSelectionIndex].style.background = '#7f7f7f';
items[currentSelectionIndex].scrollIntoView({ block: 'nearest', behavior: 'smooth' });
}
}
document.addEventListener('keydown', function(e) {
if (e.altKey && e.shiftKey) {
switch (e.code) {
case "KeyN":
e.preventDefault();
document.querySelector('button > svg').parentElement.click();
break;
case "KeyF":
e.preventDefault();
createInputOverlay();
break;
}
}
});
// Your code here...
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment