Skip to content

Commit 23d69fe

Browse files
committed
fix(voice): stop microphone capture during startup
1 parent ba6157d commit 23d69fe

1 file changed

Lines changed: 17 additions & 9 deletions

File tree

‎apps/sim/hooks/use-speech-to-text.ts‎

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ export function useSpeechToText({
223223
if (startingRef.current) return false
224224
startingRef.current = true
225225
const generation = ++generationRef.current
226+
setIsListening(true)
226227

227228
try {
228229
let tokenData: Awaited<ReturnType<typeof requestJson<typeof speechTokenContract>>>
@@ -236,6 +237,7 @@ export function useSpeechToText({
236237
if (!mountedRef.current || generation !== generationRef.current) return false
237238
if (isApiClientError(err) && err.status === 402) {
238239
const isMemberLimit = (err.body as { scope?: string } | null)?.scope === 'member'
240+
setIsListening(false)
239241
onUsageLimitExceededRef.current?.(err.message, isMemberLimit)
240242
return false
241243
}
@@ -262,6 +264,10 @@ export function useSpeechToText({
262264
}
263265

264266
streamRef.current = stream
267+
sessionTimerRef.current = setTimeout(() => {
268+
logger.info('Voice input session reached max duration, stopping')
269+
stopStreamingRef.current()
270+
}, MAX_SESSION_MS)
265271

266272
const params = new URLSearchParams({
267273
token,
@@ -349,19 +355,13 @@ export function useSpeechToText({
349355

350356
sendIntervalRef.current = setInterval(flushAudioBuffer, CHUNK_SEND_INTERVAL_MS)
351357

352-
setIsListening(true)
353-
354-
sessionTimerRef.current = setTimeout(() => {
355-
logger.info('Voice input session reached max duration, stopping')
356-
stopStreamingRef.current()
357-
}, MAX_SESSION_MS)
358-
359358
return true
360359
} catch (error) {
361360
if (generation !== generationRef.current) return false
362361
logger.error('Failed to start speech streaming', error)
363362
cleanup()
364363
if (mountedRef.current) {
364+
setIsListening(false)
365365
onErrorRef.current?.(classifyStartError(error))
366366
}
367367
return false
@@ -371,6 +371,14 @@ export function useSpeechToText({
371371
}, [cleanup, flushAudioBuffer])
372372

373373
const stopStreaming = useCallback(() => {
374+
if (startingRef.current) {
375+
generationRef.current++
376+
startingRef.current = false
377+
cleanup()
378+
setIsListening(false)
379+
return
380+
}
381+
374382
if (sessionTimerRef.current) {
375383
clearTimeout(sessionTimerRef.current)
376384
sessionTimerRef.current = null
@@ -426,7 +434,7 @@ export function useSpeechToText({
426434
}
427435

428436
setIsListening(false)
429-
}, [flushAudioBuffer])
437+
}, [cleanup, flushAudioBuffer])
430438

431439
stopStreamingRef.current = stopStreaming
432440

@@ -439,7 +447,7 @@ export function useSpeechToText({
439447
}, [cleanup])
440448

441449
const toggleListening = useCallback(() => {
442-
if (isListening) {
450+
if (startingRef.current || isListening) {
443451
stopStreaming()
444452
} else {
445453
startStreaming()

0 commit comments

Comments
 (0)