diff --git a/webview-ui/src/components/chat/AutoApproveKeyboardShortcuts.tsx b/webview-ui/src/components/chat/AutoApproveKeyboardShortcuts.tsx index ada19a8fe9..8b6f8c2fc7 100644 --- a/webview-ui/src/components/chat/AutoApproveKeyboardShortcuts.tsx +++ b/webview-ui/src/components/chat/AutoApproveKeyboardShortcuts.tsx @@ -1,22 +1,9 @@ -import { useEffect, useCallback, useMemo } from "react" +import { useEffect, useCallback, useMemo, useRef } from "react" import { useExtensionState } from "@src/context/ExtensionStateContext" import { vscode } from "@src/utils/vscode" import { AutoApproveSetting } from "../settings/AutoApproveToggle" import { useAutoApprovalToggles } from "@src/hooks/useAutoApprovalToggles" - -// Keyboard shortcuts mapping for auto-approve options -const KEYBOARD_SHORTCUTS: Record = { - "1": "alwaysAllowReadOnly", - "2": "alwaysAllowWrite", - "3": "alwaysAllowBrowser", - "4": "alwaysAllowExecute", - "5": "alwaysAllowMcp", - "6": "alwaysAllowModeSwitch", - "7": "alwaysAllowSubtasks", - "8": "alwaysAllowFollowupQuestions", - "9": "alwaysAllowUpdateTodoList", - "0": "alwaysApproveResubmit", -} +import { KEYBOARD_SHORTCUTS, DEFAULT_KEYBOARD_CONFIG } from "@src/constants/autoApproveConstants" export const AutoApproveKeyboardShortcuts = () => { const { @@ -99,23 +86,39 @@ export const AutoApproveKeyboardShortcuts = () => { ], ) + // Store the handleToggle function in a ref to avoid re-registrations + const handleToggleRef = useRef(handleToggle) useEffect(() => { - const handleKeyDown = (event: KeyboardEvent) => { - // Check if Alt/Option key is pressed along with a number key - if (event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) { - const shortcut = KEYBOARD_SHORTCUTS[event.key] - if (shortcut) { - event.preventDefault() - handleToggle(shortcut) - } - } + handleToggleRef.current = handleToggle + }, [handleToggle]) + + // Stable event handler that uses the ref + const handleKeyDown = useCallback((event: KeyboardEvent) => { + // Check if keyboard shortcuts are enabled + if (!DEFAULT_KEYBOARD_CONFIG.enabled) { + return } + // Support both Alt key and Ctrl+Shift key combinations based on configuration + const isValidModifier = DEFAULT_KEYBOARD_CONFIG.useCtrlShiftKey + ? event.ctrlKey && event.shiftKey && !event.altKey && !event.metaKey + : event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey + + if (isValidModifier) { + const shortcut = KEYBOARD_SHORTCUTS[event.key] + if (shortcut) { + event.preventDefault() + handleToggleRef.current(shortcut) + } + } + }, []) + + useEffect(() => { window.addEventListener("keydown", handleKeyDown) return () => { window.removeEventListener("keydown", handleKeyDown) } - }, [handleToggle]) + }, [handleKeyDown]) return null // This component doesn't render anything } diff --git a/webview-ui/src/components/chat/AutoApproveToggleDropdown.tsx b/webview-ui/src/components/chat/AutoApproveToggleDropdown.tsx index 4d13846350..21a041f6ec 100644 --- a/webview-ui/src/components/chat/AutoApproveToggleDropdown.tsx +++ b/webview-ui/src/components/chat/AutoApproveToggleDropdown.tsx @@ -3,6 +3,7 @@ import { useAppTranslation } from "@/i18n/TranslationContext" import { cn } from "@/lib/utils" import { StandardTooltip } from "@/components/ui" import { autoApproveSettingsConfig, AutoApproveSetting } from "../settings/AutoApproveToggle" +import { KEYBOARD_SHORTCUTS_DISPLAY, DEFAULT_KEYBOARD_CONFIG } from "@/constants/autoApproveConstants" type AutoApproveToggles = Pick< GlobalSettings, @@ -22,20 +23,6 @@ type AutoApproveToggleDropdownProps = AutoApproveToggles & { onToggle: (key: AutoApproveSetting, value: boolean) => void } -// Keyboard shortcuts mapping -const KEYBOARD_SHORTCUTS: Record = { - alwaysAllowReadOnly: "Alt+1", - alwaysAllowWrite: "Alt+2", - alwaysAllowBrowser: "Alt+3", - alwaysAllowExecute: "Alt+4", - alwaysAllowMcp: "Alt+5", - alwaysAllowModeSwitch: "Alt+6", - alwaysAllowSubtasks: "Alt+7", - alwaysAllowFollowupQuestions: "Alt+8", - alwaysAllowUpdateTodoList: "Alt+9", - alwaysApproveResubmit: "Alt+0", -} - export const AutoApproveToggleDropdown = ({ onToggle, ...props }: AutoApproveToggleDropdownProps) => { const { t } = useAppTranslation() @@ -52,7 +39,14 @@ export const AutoApproveToggleDropdown = ({ onToggle, ...props }: AutoApproveTog icon, testId, }: (typeof autoApproveSettingsConfig)[AutoApproveSetting]) => { - const tooltipContent = `${t(descriptionKey || "")} (${KEYBOARD_SHORTCUTS[key]})` + // Get the appropriate keyboard shortcut display based on configuration + const shortcutDisplay = DEFAULT_KEYBOARD_CONFIG.useCtrlShiftKey + ? KEYBOARD_SHORTCUTS_DISPLAY[key].replace("Alt+", "Ctrl+Shift+") + : KEYBOARD_SHORTCUTS_DISPLAY[key] + + const tooltipContent = DEFAULT_KEYBOARD_CONFIG.enabled + ? `${t(descriptionKey || "")} (${shortcutDisplay})` + : t(descriptionKey || "") return (