Przeglądaj źródła

refac: shortcuts

Timothy Jaeryang Baek 3 miesięcy temu
rodzic
commit
dc3d704800
1 zmienionych plików z 72 dodań i 103 usunięć
  1. 72 103
      src/routes/(app)/+layout.svelte

+ 72 - 103
src/routes/(app)/+layout.svelte

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