@@ -167,28 +167,29 @@ chrome.storage.onChanged.addListener((changes, area) => {
167167 * 3. Compute added text (baseline diff)
168168 * 4. Clear the composer
169169 * 5. Send to background for clipboard copy and history
170+ *
171+ * @param wasInDictationMode - Whether dictation was active when click was detected
172+ * @param savedBaselineText - Baseline text captured at click time
170173 */
171- async function handleManualSubmitClick ( ) : Promise < void > {
174+ async function handleManualSubmitClick (
175+ wasInDictationMode : boolean ,
176+ savedBaselineText : string
177+ ) : Promise < void > {
172178 if ( ! manualSubmitAutoCopyEnabled ) return ;
173179
174- const status = detectStatus ( ) ;
175- // Only capture if we're in recording/listening state
176- if ( status !== 'recording' && status !== 'listening' ) {
177- console . log ( '[EchoType] Manual submit ignored - not in dictation mode:' , status ) ;
180+ // Use the saved state from click time, not current state
181+ if ( ! wasInDictationMode ) {
182+ console . log ( '[EchoType] Manual submit ignored - was not in dictation mode' ) ;
178183 return ;
179184 }
180185
181186 console . log ( '[EchoType] Manual submit detected, starting full capture workflow...' ) ;
187+ console . log ( '[EchoType] Baseline text:' , savedBaselineText . substring ( 0 , 50 ) ) ;
182188
183- // Get baseline text from controller state (captured when dictation started)
184- const controllerState = getControllerState ( ) ;
185- const baselineText = controllerState . baselineText || '' ;
186- console . log ( '[EchoType] Baseline text:' , baselineText . substring ( 0 , 50 ) ) ;
189+ // Wait for ChatGPT to process the submit and show text in composer
190+ await new Promise ( resolve => setTimeout ( resolve , 200 ) ) ;
187191
188- // Wait a moment for the submit click to be processed
189- await new Promise ( resolve => setTimeout ( resolve , 100 ) ) ;
190-
191- // Read pre-submit text (may still be showing waveform)
192+ // Read pre-submit text (may still be showing waveform or transitioning)
192193 const preSubmitText = readComposerText ( ) ;
193194
194195 // Capture stable text after submit (same as popup workflow)
@@ -198,7 +199,7 @@ async function handleManualSubmitClick(): Promise<void> {
198199 } ) ;
199200
200201 const finalText = normalizeText ( capture . text ) ;
201- const addedText = computeAddedText ( baselineText , finalText ) ;
202+ const addedText = computeAddedText ( savedBaselineText , finalText ) ;
202203
203204 console . log ( '[EchoType] Manual submit captured:' , {
204205 finalText : finalText . substring ( 0 , 50 ) ,
@@ -231,6 +232,10 @@ async function handleManualSubmitClick(): Promise<void> {
231232/**
232233 * Set up click listener for submit button.
233234 * Uses event delegation on document body.
235+ *
236+ * IMPORTANT: We capture the dictation state at click time because
237+ * ChatGPT immediately processes the click and changes the UI state.
238+ * If we check state after setTimeout, it will already be 'idle'.
234239 */
235240function setupManualSubmitListener ( ) : void {
236241 document . body . addEventListener ( 'click' , ( event ) => {
@@ -241,9 +246,17 @@ function setupManualSubmitListener(): void {
241246
242247 // Check if clicked element is or is within the submit button
243248 if ( submitBtn && ( target === submitBtn || submitBtn . contains ( target ) ) ) {
244- // Use setTimeout to let the click complete first
249+ // CRITICAL: Capture state NOW, before ChatGPT processes the click
250+ const currentStatus = detectStatus ( ) ;
251+ const wasInDictationMode = currentStatus === 'recording' || currentStatus === 'listening' ;
252+ const controllerState = getControllerState ( ) ;
253+ const savedBaselineText = controllerState . baselineText || '' ;
254+
255+ console . log ( '[EchoType] Submit button clicked, status:' , currentStatus , 'dictation mode:' , wasInDictationMode ) ;
256+
257+ // Use setTimeout to let the click complete first, but pass saved state
245258 setTimeout ( ( ) => {
246- handleManualSubmitClick ( ) . catch ( console . error ) ;
259+ handleManualSubmitClick ( wasInDictationMode , savedBaselineText ) . catch ( console . error ) ;
247260 } , 50 ) ;
248261 }
249262 } , true ) ; // Use capture phase to detect before default handlers
0 commit comments