From 1b9cf7a30c4a5f60729f37ef9591f175c3a85f3a Mon Sep 17 00:00:00 2001 From: claude code agent 227 Date: Sun, 21 Jun 2026 20:47:45 +0300 Subject: [PATCH] fix(dictation): drop the under-input interim preview in chat MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The live partial transcript was shown as a dimmed line under the chat textarea, but each segment only flickers there for an instant before its final lands in the draft — the preview was unreadable noise. Remove it: realtime partials are no longer rendered separately; finalized segments are appended straight into the draft (where the user actually reads them). Editor dictation (inline ghost at the caret) is unaffected. Co-Authored-By: Claude Opus 4.8 --- .../ai-chat/components/chat-input.tsx | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/apps/client/src/features/ai-chat/components/chat-input.tsx b/apps/client/src/features/ai-chat/components/chat-input.tsx index 1bbb689a..e0892635 100644 --- a/apps/client/src/features/ai-chat/components/chat-input.tsx +++ b/apps/client/src/features/ai-chat/components/chat-input.tsx @@ -1,9 +1,8 @@ -import { KeyboardEvent, useState } from "react"; +import { KeyboardEvent } from "react"; import { ActionIcon, Group, Stack, - Text, Textarea, Tooltip, } from "@mantine/core"; @@ -48,16 +47,12 @@ export default function ChatInput({ const workspace = useAtomValue(workspaceAtom); const isDictationEnabled = workspace?.settings?.ai?.dictation === true; const isRealtime = workspace?.settings?.ai?.dictationRealtime === true; - // Live interim (partial) transcript shown as a dimmed tail under the input. - const [interim, setInterim] = useState(""); const send = (): void => { const text = value.trim(); if (!text || isStreaming || disabled) return; onSend(text); setValue(""); - // Drop any leftover partial when a message is sent. - setInterim(""); }; const handleKeyDown = (e: KeyboardEvent): void => { @@ -90,11 +85,11 @@ export default function ChatInput({ setInterim(text)} - onFinal={(text) => { - setValue((v) => appendFinalToDraft(v, text)); - setInterim(""); - }} + // No separate interim preview in the chat: partials are not shown + // under the input (they only flicker before the final lands in the + // draft). Each finalized segment is appended straight into the draft. + onInterim={() => {}} + onFinal={(text) => setValue((v) => appendFinalToDraft(v, text))} /> ) : ( )} - {interim && ( - - {interim} - - )} ); }