diff --git a/src/renderer/src/components/native-chat/NativeChatComposer.tsx b/src/renderer/src/components/native-chat/NativeChatComposer.tsx index b11da6676f9..9081f6adf65 100644 --- a/src/renderer/src/components/native-chat/NativeChatComposer.tsx +++ b/src/renderer/src/components/native-chat/NativeChatComposer.tsx @@ -1,4 +1,4 @@ -import { forwardRef, useCallback, useImperativeHandle, useMemo, useRef, useState } from 'react' +import { forwardRef, useCallback, useImperativeHandle, useMemo, useState } from 'react' import { useAppStore } from '../../store' import { sendRuntimePtyInput } from '@/runtime/runtime-terminal-inspection' import { getSettingsForAgentTabRuntimeOwner } from '@/lib/agent-paste-draft' @@ -37,6 +37,7 @@ import type { import { dispatchNativeChatStructuredComposerText } from './native-chat-structured-composer-dispatch' import { useNativeChatPtyComposerSend } from './use-native-chat-pty-composer-send' import { useImeEnterGestureOwnership } from '@/lib/ime-composition-keyboard-event' +import { useNativeChatComposerAppMenuSelection } from './use-native-chat-composer-app-menu-selection' export type { NativeChatComposerHandle, @@ -97,8 +98,8 @@ const NativeChatComposerPane = forwardRef(null) const [dictationPressed, setDictationPressed] = useState(false) - const textareaRef = useRef(null) const imeEnterGesture = useImeEnterGestureOwnership() + const { textareaRef } = useNativeChatComposerAppMenuSelection(imeEnterGesture.isComposing) const { cancelPendingSends, trackPendingSend } = useNativeChatSendLifecycle( terminalTabId, targetPtyId, diff --git a/src/renderer/src/components/native-chat/use-native-chat-composer-app-menu-selection.test.tsx b/src/renderer/src/components/native-chat/use-native-chat-composer-app-menu-selection.test.tsx new file mode 100644 index 00000000000..9fca062e058 --- /dev/null +++ b/src/renderer/src/components/native-chat/use-native-chat-composer-app-menu-selection.test.tsx @@ -0,0 +1,147 @@ +// @vitest-environment happy-dom + +import { act, cleanup, fireEvent, render } from '@testing-library/react' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { + APP_MENU_SELECTION_ACTION_EVENT, + type AppMenuSelectionAction +} from '@/lib/app-menu-selection-actions' +import { useAppMenuSelectionActions } from '@/hooks/useAppMenuSelectionActions' +import { useNativeChatComposerAppMenuSelection } from './use-native-chat-composer-app-menu-selection' + +let appMenuListener: ((action: AppMenuSelectionAction) => void) | null = null +const performNativeSelectionAction = vi.fn() + +function AppMenuBoundary(): null { + useAppMenuSelectionActions() + return null +} + +function ComposerHarness(): React.JSX.Element { + const { textareaRef, isComposingRef } = useNativeChatComposerAppMenuSelection() + return ( +
+