From b948b8d3d09515c11becdba13c74208b5ee3aebc Mon Sep 17 00:00:00 2001 From: Thomas Brugman Date: Sat, 14 Mar 2026 16:01:38 +0100 Subject: [PATCH] fix(web): preserve composer input when planning question appears When a planning question pops up while the user is typing in the composer, their typed text was being cleared. This was caused by the sync effect that copies pending user input to the composer - it would overwrite user content with the empty pending answer. The fix adds a check to skip syncing when the user has already typed content in the composer, keeping the pending question input independent from the main composer draft. Fixes #808 --- apps/web/src/components/ChatView.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/web/src/components/ChatView.tsx b/apps/web/src/components/ChatView.tsx index 9f625762c..c4cfd5567 100644 --- a/apps/web/src/components/ChatView.tsx +++ b/apps/web/src/components/ChatView.tsx @@ -665,17 +665,29 @@ export default function ChatView({ threadId }: ChatViewProps) { const questionChanged = lastSyncedPendingInputRef.current?.requestId !== nextRequestId || lastSyncedPendingInputRef.current?.questionId !== nextQuestionId; - const textChangedExternally = promptRef.current !== nextCustomAnswer; lastSyncedPendingInputRef.current = { requestId: nextRequestId, questionId: nextQuestionId, }; - if (!questionChanged && !textChangedExternally) { + // Don't sync when there's user-typed content in the composer. + // This keeps the pending question input independent from the main composer draft. + // Previously, this would overwrite user-typed text when a planning question appeared. + const hasUserTypedInComposer = promptRef.current.length > 0; + if (hasUserTypedInComposer) { return; } + // For new questions (questionChanged), always sync to show the question's placeholder. + if (!questionChanged) { + // For same question: only sync if text actually changed externally. + const textChangedExternally = promptRef.current !== nextCustomAnswer; + if (!textChangedExternally) { + return; + } + } + promptRef.current = nextCustomAnswer; const nextCursor = collapseExpandedComposerCursor(nextCustomAnswer, nextCustomAnswer.length); setComposerCursor(nextCursor);