fix: web speech STT repeating previous transcriptions and inserting text on cancel (#26793)
The VoiceRecording component stays mounted (hidden) between recordings, and the web speech engine accumulated every session's transcript into the never-reset transcription variable. Each new recording therefore confirmed all previous utterances again, so the inserted text repeated once per session and previously deleted text reappeared in the input. Additionally, cancelling a recording (X button, Escape or a recognition error) called stopRecording(), which stops the SpeechRecognition instance and fires its onend handler, which unconditionally confirms the transcription. Cancelled recordings therefore still inserted the accumulated transcript. Reset the transcription at the start of each web speech session and detach the onend handler on cancel so cancelled recordings no longer confirm. Fixes #26784
This commit is contained in:
@@ -300,6 +300,9 @@
|
||||
if (transcribe) {
|
||||
if ($config.audio.stt.engine === 'web' || ($settings?.audio?.stt?.engine ?? '') === 'web') {
|
||||
if ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window) {
|
||||
// reset accumulated transcription from previous sessions
|
||||
transcription = '';
|
||||
|
||||
// Create a SpeechRecognition object
|
||||
speechRecognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
|
||||
|
||||
@@ -353,13 +356,21 @@
|
||||
toast.error($i18n.t(`Speech recognition error: {{error}}`, { error: event.error }));
|
||||
onCancel();
|
||||
|
||||
stopRecording();
|
||||
cancelRecording();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const cancelRecording = async () => {
|
||||
if (speechRecognition) {
|
||||
// detach onend so cancelling does not confirm the transcription
|
||||
speechRecognition.onend = null;
|
||||
}
|
||||
await stopRecording();
|
||||
};
|
||||
|
||||
const stopRecording = async () => {
|
||||
if (recording && mediaRecorder) {
|
||||
await mediaRecorder.stop();
|
||||
@@ -411,7 +422,7 @@
|
||||
const handleKeyDown = (e) => {
|
||||
if (e.key === 'Escape') {
|
||||
e.preventDefault();
|
||||
stopRecording();
|
||||
cancelRecording();
|
||||
onCancel();
|
||||
}
|
||||
};
|
||||
@@ -468,7 +479,7 @@
|
||||
|
||||
rounded-full"
|
||||
on:click={async () => {
|
||||
stopRecording();
|
||||
cancelRecording();
|
||||
onCancel();
|
||||
}}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user