()
| 540 | // after FOCUS_SILENCE_TIMEOUT_MS of no speech. Called when a session |
| 541 | // starts and after each flushed transcript. |
| 542 | function armFocusSilenceTimer(): void { |
| 543 | if (focusSilenceTimerRef.current) { |
| 544 | clearTimeout(focusSilenceTimerRef.current) |
| 545 | } |
| 546 | focusSilenceTimerRef.current = setTimeout( |
| 547 | ( |
| 548 | focusSilenceTimerRef, |
| 549 | stateRef, |
| 550 | focusTriggeredRef, |
| 551 | silenceTimedOutRef, |
| 552 | finishRecording, |
| 553 | ) => { |
| 554 | focusSilenceTimerRef.current = null |
| 555 | if (stateRef.current === 'recording' && focusTriggeredRef.current) { |
| 556 | logForDebugging( |
| 557 | '[voice] Focus silence timeout — tearing down session', |
| 558 | ) |
| 559 | silenceTimedOutRef.current = true |
| 560 | finishRecording() |
| 561 | } |
| 562 | }, |
| 563 | FOCUS_SILENCE_TIMEOUT_MS, |
| 564 | focusSilenceTimerRef, |
| 565 | stateRef, |
| 566 | focusTriggeredRef, |
| 567 | silenceTimedOutRef, |
| 568 | finishRecording, |
| 569 | ) |
| 570 | } |
| 571 | |
| 572 | // ── Focus-driven recording ────────────────────────────────────────── |
| 573 | // In focus mode, start recording when the terminal gains focus and |
no test coverage detected