diff --git a/src/renderer/components/ChatPane.tsx b/src/renderer/components/ChatPane.tsx index adbbe4f..46b74de 100644 --- a/src/renderer/components/ChatPane.tsx +++ b/src/renderer/components/ChatPane.tsx @@ -1,7 +1,8 @@ -import { type KeyboardEvent, useEffect, useMemo, useRef, useState } from 'react'; +import { useEffect, useMemo, useRef, useState } from 'react'; import { AlertCircle, ArrowUp, Bot, Check, ChevronDown, Circle, GitBranch, Loader2, RotateCcw, Server, ShieldAlert, ShieldCheck, Sparkles, User, X } from 'lucide-react'; import { MarkdownContent } from '@renderer/components/MarkdownContent'; +import { MarkdownComposer, type MarkdownComposerHandle } from '@renderer/components/MarkdownComposer'; import { getAssistantMessagePhase } from '@renderer/lib/messagePhase'; import { ProviderIcon } from '@renderer/components/ProviderIcons'; import type { ApprovalDecision, PendingApprovalRecord } from '@shared/domain/approval'; @@ -16,7 +17,6 @@ import { import { reasoningEffortOptions, type PatternDefinition, type ReasoningEffort } from '@shared/domain/pattern'; import { isScratchpadProject, type ProjectRecord } from '@shared/domain/project'; import { resolveSessionToolingSelection, type SessionRecord } from '@shared/domain/session'; -import { hasMeaningfulChatMessageContent, prepareChatMessageContent } from '@shared/utils/chatMessage'; import { listApprovalToolDefinitions, type ApprovalToolDefinition, @@ -677,13 +677,13 @@ export function ChatPane({ onUpdateSessionTooling, onUpdateSessionApprovalSettings, }: ChatPaneProps) { - const [input, setInput] = useState(''); + const [hasComposerContent, setHasComposerContent] = useState(false); const [configError, setConfigError] = useState(); const [approvalError, setApprovalError] = useState(); const [isResolvingApproval, setIsResolvingApproval] = useState(false); const [isUpdatingScratchpadConfig, setIsUpdatingScratchpadConfig] = useState(false); const transcriptRef = useRef(null); - const textareaRef = useRef(null); + const composerRef = useRef(null); const isSessionBusy = session.status === 'running'; const pendingApproval = session.pendingApproval?.status === 'pending' ? session.pendingApproval : undefined; @@ -695,7 +695,7 @@ export function ChatPane({ const supportedEfforts = getSupportedReasoningEfforts(selectedModel); const scratchpadReasoningEffort = resolveReasoningEffort(selectedModel, primaryAgent?.reasoningEffort); const isComposerDisabled = isSessionBusy || isUpdatingScratchpadConfig; - const canSubmitInput = hasMeaningfulChatMessageContent(input) && !isComposerDisabled; + const canSubmitInput = hasComposerContent && !isComposerDisabled; const toolSelection = useMemo(() => resolveSessionToolingSelection(session), [session]); const mcpServers = toolingSettings.mcpServers; @@ -730,11 +730,8 @@ export function ChatPane({ setIsUpdatingScratchpadConfig(false); }, [session.id]); - async function handleSubmit() { - const text = prepareChatMessageContent(input); - if (!text || isComposerDisabled) return; - setInput(''); - await onSend(text); + function handleComposerSubmit(content: string) { + void onSend(content); } async function handleScratchpadConfigChange(config: { @@ -779,13 +776,6 @@ export function ChatPane({ } } - function handleKeyDown(event: KeyboardEvent) { - if (event.key === 'Enter' && !event.shiftKey) { - event.preventDefault(); - void handleSubmit(); - } - } - return (
{/* Header — extra top padding clears the title bar overlay zone */} @@ -1024,11 +1014,11 @@ export function ChatPane({ )}
-