From d8830b5a8e0b4c35e1b58a2eb91d4debffa59136 Mon Sep 17 00:00:00 2001 From: Marcel Date: Sun, 5 Apr 2026 21:47:00 +0200 Subject: [PATCH] fix(transcription): use local state for textarea to prevent flicker on save The textarea value was bound directly to the text prop from the parent. When auto-save completed and updated the blocks array, Svelte re-rendered the textarea with the prop value, causing the text to disappear briefly. Fix: use localText state initialized from prop, synced only when blockId changes (not on save responses). Typing updates localText immediately, parent re-renders from save don't overwrite the local value. Co-Authored-By: Claude Sonnet 4.6 --- .../lib/components/TranscriptionBlock.svelte | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/frontend/src/lib/components/TranscriptionBlock.svelte b/frontend/src/lib/components/TranscriptionBlock.svelte index 0b370561..6c11626e 100644 --- a/frontend/src/lib/components/TranscriptionBlock.svelte +++ b/frontend/src/lib/components/TranscriptionBlock.svelte @@ -36,10 +36,20 @@ let { onRetry }: Props = $props(); +let localText = $state(text); let commentOpen = $state(false); let selectedQuote = $state(null); let textareaEl = $state(null); +// Sync from prop only when switching to a different block (not on save responses) +let prevBlockId = $state(blockId); +$effect(() => { + if (blockId !== prevBlockId) { + localText = text; + prevBlockId = blockId; + } +}); + let leftBorderClass = $derived( saveState === 'error' ? 'border-l-2 border-error' : active ? 'border-l-2 border-turquoise' : '' ); @@ -65,6 +75,7 @@ function autoresize(node: HTMLTextAreaElement) { function handleInput(event: Event) { const target = event.target as HTMLTextAreaElement; + localText = target.value; onTextChange(target.value); } @@ -79,7 +90,7 @@ function captureSelectionAndOpenComments() { const start = textareaEl.selectionStart; const end = textareaEl.selectionEnd; if (start !== end) { - selectedQuote = textareaEl.value.substring(start, end); + selectedQuote = localText.substring(start, end); } else { selectedQuote = null; } @@ -110,11 +121,11 @@ function captureSelectionAndOpenComments() {