refac: shortcuts

This commit is contained in:
Timothy Jaeryang Baek 2025-11-06 13:08:48 -05:00
parent 8da4e5bb19
commit dc3d704800

View file

@ -165,119 +165,88 @@
]); ]);
// Helper function to check if the pressed keys match the shortcut definition // Helper function to check if the pressed keys match the shortcut definition
const checkShortcut = (event: KeyboardEvent, keys: string[]): boolean => { const isShortcutMatch = (event: KeyboardEvent, shortcut): boolean => {
const lowerCaseKeys = keys.map((key) => key.toLowerCase()); const keys = shortcut?.keys || [];
const isModPressed = lowerCaseKeys.includes('mod') ? event.ctrlKey || event.metaKey : true; const mainKeys = keys.filter(
const isShiftPressed = lowerCaseKeys.includes('shift') ? event.shiftKey : true; (k) => !['ctrl', 'Ctrl', 'shift', 'Shift', 'alt', 'Alt', 'mod', 'Mod'].includes(k)
const isAltPressed = lowerCaseKeys.includes('alt') ? event.altKey : true;
const isCtrlPressed = lowerCaseKeys.includes('ctrl') ? event.ctrlKey : true;
const mainKeys = lowerCaseKeys.filter(
(key) => !['mod', 'shift', 'alt', 'ctrl'].includes(key)
); );
if (mainKeys.length > 0 && !mainKeys.includes(event.code.toLowerCase())) { const normalized = keys.map((k) => k.toLowerCase());
return false; const needCtrl = normalized.includes('ctrl') || normalized.includes('mod');
} const needShift = normalized.includes('shift');
const needAlt = normalized.includes('alt');
let modConflict = false; // Get the main key pressed
if (keys.includes('mod')) { const keyPressed = event.code;
if (!lowerCaseKeys.includes('shift') && event.shiftKey) modConflict = true;
if (!lowerCaseKeys.includes('alt') && event.altKey) modConflict = true;
}
return ( // Check modifiers
!modConflict && if (needShift && !event.shiftKey) return false;
isModPressed &&
isShiftPressed && if (needCtrl && !(event.ctrlKey || event.metaKey)) return false;
isAltPressed && if (!needCtrl && (event.ctrlKey || event.metaKey)) return false;
isCtrlPressed && if (needAlt && !event.altKey) return false;
(event.ctrlKey || event.metaKey) === if (!needAlt && event.altKey) return false;
(lowerCaseKeys.includes('mod') || lowerCaseKeys.includes('ctrl')) &&
event.shiftKey === lowerCaseKeys.includes('shift') && if (mainKeys.length && !mainKeys.includes(keyPressed)) return false;
event.altKey === lowerCaseKeys.includes('alt')
); return true;
}; };
const setupKeyboardShortcuts = () => { const setupKeyboardShortcuts = () => {
document.addEventListener('keydown', async (event) => { document.addEventListener('keydown', async (event) => {
for (const shortcutName in shortcuts) { if (isShortcutMatch(event, shortcuts[Shortcut.SEARCH])) {
const shortcut = shortcuts[shortcutName]; event.preventDefault();
if (checkShortcut(event, shortcut.keys)) { showSearch.set(!$showSearch);
// Here you can map the shortcut name to an action } else if (isShortcutMatch(event, shortcuts[Shortcut.NEW_CHAT])) {
// This is a simple example, you might want a more robust solution event.preventDefault();
switch (shortcutName) { document.getElementById('sidebar-new-chat-button')?.click();
case Shortcut.SEARCH: } else if (isShortcutMatch(event, shortcuts[Shortcut.FOCUS_INPUT])) {
event.preventDefault(); event.preventDefault();
showSearch.set(!$showSearch); document.getElementById('chat-input')?.focus();
break; } else if (isShortcutMatch(event, shortcuts[Shortcut.COPY_LAST_CODE_BLOCK])) {
case Shortcut.NEW_CHAT: event.preventDefault();
event.preventDefault(); [...document.getElementsByClassName('copy-code-button')]?.at(-1)?.click();
document.getElementById('sidebar-new-chat-button')?.click(); } else if (isShortcutMatch(event, shortcuts[Shortcut.COPY_LAST_RESPONSE])) {
break; event.preventDefault();
case Shortcut.FOCUS_INPUT: [...document.getElementsByClassName('copy-response-button')]?.at(-1)?.click();
event.preventDefault(); } else if (isShortcutMatch(event, shortcuts[Shortcut.TOGGLE_SIDEBAR])) {
document.getElementById('chat-input')?.focus(); event.preventDefault();
break; showSidebar.set(!$showSidebar);
case Shortcut.COPY_LAST_CODE_BLOCK: } else if (isShortcutMatch(event, shortcuts[Shortcut.DELETE_CHAT])) {
event.preventDefault(); event.preventDefault();
[...document.getElementsByClassName('copy-code-button')]?.at(-1)?.click(); document.getElementById('delete-chat-button')?.click();
break; } else if (isShortcutMatch(event, shortcuts[Shortcut.OPEN_SETTINGS])) {
case Shortcut.COPY_LAST_RESPONSE: event.preventDefault();
event.preventDefault(); showSettings.set(!$showSettings);
[...document.getElementsByClassName('copy-response-button')]?.at(-1)?.click(); } else if (isShortcutMatch(event, shortcuts[Shortcut.SHOW_SHORTCUTS])) {
break; event.preventDefault();
case Shortcut.TOGGLE_SIDEBAR: showShortcuts.set(!$showShortcuts);
event.preventDefault(); } else if (isShortcutMatch(event, shortcuts[Shortcut.CLOSE_MODAL])) {
showSidebar.set(!$showSidebar); event.preventDefault();
break; showSettings.set(false);
case Shortcut.DELETE_CHAT: showShortcuts.set(false);
event.preventDefault(); } else if (isShortcutMatch(event, shortcuts[Shortcut.NEW_TEMPORARY_CHAT])) {
document.getElementById('delete-chat-button')?.click(); event.preventDefault();
break; if ($user?.role !== 'admin' && $user?.permissions?.chat?.temporary_enforced) {
case Shortcut.OPEN_SETTINGS: temporaryChatEnabled.set(true);
event.preventDefault(); } else {
showSettings.set(!$showSettings); temporaryChatEnabled.set(!$temporaryChatEnabled);
break;
case Shortcut.SHOW_SHORTCUTS:
event.preventDefault();
showShortcuts.set(!$showShortcuts);
break;
case Shortcut.CLOSE_MODAL:
event.preventDefault();
showSettings.set(false);
showShortcuts.set(false);
break;
case Shortcut.NEW_TEMPORARY_CHAT:
event.preventDefault();
if ($user?.role !== 'admin' && $user?.permissions?.chat?.temporary_enforced) {
temporaryChatEnabled.set(true);
} else {
temporaryChatEnabled.set(!$temporaryChatEnabled);
}
await goto('/');
setTimeout(() => {
document.getElementById('new-chat-button')?.click();
}, 0);
break;
case Shortcut.GENERATE_MESSAGE_PAIR:
event.preventDefault();
document.getElementById('generate-message-pair-button')?.click();
break;
case Shortcut.REGENERATE_RESPONSE:
event.preventDefault();
[...document.getElementsByClassName('regenerate-response-button')]?.at(-1)?.click();
break;
case Shortcut.STOP_GENERATING:
// Placeholder for future implementation
break;
case Shortcut.PREVENT_FILE_CREATION:
// This shortcut is handled by the paste event in MessageInput.svelte
break;
}
} }
await goto('/');
setTimeout(() => {
document.getElementById('new-chat-button')?.click();
}, 0);
} else if (isShortcutMatch(event, shortcuts[Shortcut.GENERATE_MESSAGE_PAIR])) {
event.preventDefault();
document.getElementById('generate-message-pair-button')?.click();
} else if (isShortcutMatch(event, shortcuts[Shortcut.REGENERATE_RESPONSE])) {
event.preventDefault();
[...document.getElementsByClassName('regenerate-response-button')]?.at(-1)?.click();
} else if (isShortcutMatch(event, shortcuts[Shortcut.STOP_GENERATING])) {
// This shortcut is handled in Chat.svelte
} else if (isShortcutMatch(event, shortcuts[Shortcut.PREVENT_FILE_CREATION])) {
// This shortcut is handled by the paste event in MessageInput.svelte
} }
}); });
}; };