Skip to content

fix(home): voice input text persistence bugs#3737

Merged
waleedlatif1 merged 4 commits intostagingfrom
waleedlatif1/fix-voice-input-bugs
Mar 24, 2026
Merged

fix(home): voice input text persistence bugs#3737
waleedlatif1 merged 4 commits intostagingfrom
waleedlatif1/fix-voice-input-bugs

Conversation

@waleedlatif1
Copy link
Collaborator

Summary

  • Fix deleted text reappearing when re-speaking after clearing the textarea while mic is active
  • Fix text disappearing after a long pause in speech (recognition auto-restart was losing accumulated text)
  • Extract startRecognition and restartRecognition helpers for cleaner speech lifecycle management
  • Add try/catch on initial recognition.start() for robustness

Type of Change

  • Bug fix

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@cursor
Copy link

cursor bot commented Mar 24, 2026

PR Summary

Medium Risk
Touches the chat input’s speech-recognition lifecycle and how it mutates the textarea value, which can regress voice input behavior across browsers despite being UI-scoped.

Overview
Fixes voice-input text persistence in UserInput by making speech recognition restarts preserve the latest typed/cleared textarea state instead of reusing stale prefixes.

This extracts startRecognition/restartRecognition, tracks the current message in a ref, restarts recognition on submit and on manual text edits (including the special @ handling), and adds guarded try/catch around recognition.start() plus safer onend/onerror handling.

Written by Cursor Bugbot for commit 8549d3c. Configure here.

@vercel
Copy link

vercel bot commented Mar 24, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Mar 24, 2026 4:43pm

Request Review

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 24, 2026

Greptile Summary

This PR fixes two speech-recognition persistence bugs in the UserInput component: accumulated text being lost after recognition auto-restarts on a long pause, and cleared/deleted text reappearing when the user speaks again. Both are solved by extracting startRecognition/restartRecognition helpers and introducing a valueRef to give async Web Speech API callbacks reliable access to the latest textarea value without stale closure issues.

Key changes:

  • valueRef (useRef) shadows the value state and is kept in sync by a useEffect plus a direct write inside onresult, ensuring onend's auto-restart reads the correct accumulated text when it updates prefixRef.current.
  • startRecognition returns a boolean so toggleListening and restartRecognition can gate setIsListening(true) on actual start success — resolving the previously reported setIsListening(true) race on start failure.
  • restartRecognition(newPrefix) is called from handleInputChange (every textarea edit) and handleSubmit (on send), keeping prefixRef in sync with user edits so stale prefixes can never cause old text to reappear.
  • Old recognition instances are guarded in onerror and onend via reference equality (recognitionRef.current !== recognition) so aborted sessions cannot mistakenly clear isListening or trigger spurious restarts.
  • SPEECH_RECOGNITION_LANG extracted as a module-level constant (minor hygiene).

Confidence Score: 4/5

  • This PR is safe to merge; the bug fixes are logically sound and the previously reported setIsListening race is correctly resolved.
  • The core implementation is correct: valueRef prevents stale reads in the async onend handler, reference-equality guards on onerror/onend prevent ghost-restart side effects, and the boolean return from startRecognition properly gates the listening state. The one remaining non-blocking item is that restartRecognition is called on every keystroke, which may cause noticeable churn under rapid editing; a debounce would be a cleaner approach but is not required for correctness.
  • No files require special attention beyond the single changed component.

Important Files Changed

Filename Overview
apps/sim/app/workspace/[workspaceId]/home/components/user-input/user-input.tsx Refactors speech recognition into startRecognition/restartRecognition helpers; adds valueRef to avoid stale closure in onend; fixes prefix persistence bugs on clear and post-submit; gates setIsListening(true) on start success per previous review feedback.

Sequence Diagram

sequenceDiagram
    participant U as User
    participant TC as toggleListening
    participant SR as startRecognition
    participant RR as restartRecognition
    participant WA as Web Speech API
    participant RS as React State

    U->>TC: clicks mic button (start)
    TC->>SR: startRecognition()
    SR->>WA: new SpeechRecognitionAPI()
    SR->>WA: recognition.start()
    WA-->>SR: success → returns true
    SR-->>TC: true
    TC->>RS: setIsListening(true)

    WA-->>SR: onresult(event)
    SR->>RS: setValue(prefix + transcript)
    SR->>SR: valueRef.current = newVal

    note over WA: Long pause / natural end
    WA-->>SR: onend()
    SR->>SR: prefixRef.current = valueRef.current
    SR->>WA: recognition.start() (same instance)

    U->>U: types in textarea
    U->>RR: handleInputChange → restartRecognition(newValue)
    RR->>RR: prefixRef.current = newValue
    RR->>WA: recognitionRef.current.abort()
    WA-->>SR: onerror('aborted') → guard fails → early exit
    WA-->>SR: onend() → guard fails → early exit
    RR->>SR: startRecognition()
    SR->>WA: new instance + start()
    WA-->>SR: success

    U->>U: submits message
    U->>RR: handleSubmit → restartRecognition('')
    RR->>RR: prefixRef.current = ''
    RR->>WA: abort old instance
    RR->>SR: startRecognition()
    SR->>WA: new instance + start()

    U->>TC: clicks mic button (stop)
    TC->>WA: recognitionRef.current.stop()
    TC->>RS: setIsListening(false)
Loading

Reviews (3): Last reviewed commit: "fix(home): reset speech prefix on submit..." | Re-trigger Greptile

@waleedlatif1
Copy link
Collaborator Author

@greptile

@waleedlatif1
Copy link
Collaborator Author

@cursor review

@waleedlatif1
Copy link
Collaborator Author

@greptile

@waleedlatif1
Copy link
Collaborator Author

@cursor review

@waleedlatif1
Copy link
Collaborator Author

@greptile

@waleedlatif1
Copy link
Collaborator Author

@cursor review

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

@waleedlatif1 waleedlatif1 merged commit 83eb3ed into staging Mar 24, 2026
12 checks passed
@waleedlatif1 waleedlatif1 deleted the waleedlatif1/fix-voice-input-bugs branch March 24, 2026 16:55
Sg312 pushed a commit that referenced this pull request Mar 24, 2026
* fix(home): voice input text persistence bugs

* fix(home): gate setIsListening on startRecognition success

* fix(home): handle startRecognition failure in restartRecognition

* fix(home): reset speech prefix on submit while mic is active
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant