From 6678f81283ceb2ed9e91ba5b7ebb30bdcf0d56ae Mon Sep 17 00:00:00 2001 From: Woody Date: Mon, 18 May 2026 16:04:14 +0800 Subject: [PATCH] fix: keep textarea editable during half-question API call Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- ..._2026-05-18_half_question_textarea_lock.md | 133 ++++++++++++++++++ frontend/src/components/QueryInput.tsx | 3 +- .../src/test/components/QueryInput.test.tsx | 4 +- 3 files changed, 136 insertions(+), 4 deletions(-) create mode 100644 .plans/debug_2026-05-18_half_question_textarea_lock.md diff --git a/.plans/debug_2026-05-18_half_question_textarea_lock.md b/.plans/debug_2026-05-18_half_question_textarea_lock.md new file mode 100644 index 0000000..fba42f1 --- /dev/null +++ b/.plans/debug_2026-05-18_half_question_textarea_lock.md @@ -0,0 +1,133 @@ +# Debug Plan: Half Question Button Locks QueryBox + +**Date:** 2026-05-18 +**Symptom:** After clicking "Half Question", the textarea appears locked (grayed out, cursor-not-allowed), raising concern that incoming ASR text chunks won't accumulate. + +--- + +## Root Cause Analysis + +### The Disable Chain + +``` +User clicks "Half Question" + → QueryInput.onClick: onHalfQuestion(trimmed) + → LTTPage.handleHalfQuestion: queryStream.decomposeOnly({ question }) + → queries.tsx decomposeOnly: setState({ phase: 'decomposing' }) [IMMEDIATE] + → LTTPage: isLoading = true (phase !== 'idle' && !== 'completed' && !== 'error') + → QueryInput.textarea: disabled={isLoading} = true ← TEXTAREA LOCKS + → QueryInput.buttons: disabled={isDisabled} = true ← BUTTONS LOCK +``` + +### What ACTUALLY Happens vs What User Perceives + +| Concern | Reality | +|---------|---------| +| Text accumulation stops? | **No.** React controlled `value={displayValue}` updates even when `disabled`. ASR text continues to display. Playwright confirmed: 250→421 chars during Half Question processing. | +| Buttons permanently locked? | **No.** When SSE `completed` event arrives, phase→`completed`, `isLoading`→`false`, all re-enabled. | +| Textarea editable during wait? | **No.** This IS the issue. Textarea is `disabled={isLoading}`, so user cannot edit/select text during the 5-30s LLM decomposition call. | + +### The Real Bug + +The textarea should NOT be disabled during half-question processing. The half-question feature is meant to be non-blocking — users should be able to: + +1. **Continue seeing ASR text accumulate** ✅ (works via controlled component) +2. **Edit the accumulating text** ❌ (textarea disabled prevents typing/selection) +3. **Click "Final Submit" later** ❌ (button disabled during API call) +4. **Click "Half Question" again** ❌ (button disabled during API call) + +**But** #2 is the primary concern. Users physically cannot interact with the textarea while the LLM decomposes the question — and they can't even see that text IS still accumulating because the grayed-out disabled style makes it look frozen. + +--- + +## Where Every Prop Wires + +``` +frontend/src/pages/LTTPage.tsx + line 73: handleHalfQuestion → queryStream.decomposeOnly({ question }) + line 81: isLoading = phase !== 'idle' && !== 'completed' && !== 'error' + line 166: ← shared isLoading + +frontend/src/components/QueryInput.tsx + line 52: isDisabled = isLoading || displayValue.trim() === '' + line 66: