Problem
useVoiceInput is a 351-line hook managing 5 distinct concerns:
- Voice session lifecycle — create, start, stop, destroy session
- Press-hold timing — 4 refs (
holdTimerRef, pressStartedAtRef, pressActiveRef, startedFromCurrentPressRef) for detecting long-press
- Keyboard event handling —
handleKeyDown/handleKeyUp with complex space-bar interception
- Intro screen state —
isIntroOpen, introSeenRef, confirmIntro, dismissIntro
- Transcript insertion —
insertIntoTextarea, insertLiteralSpace
The press-hold timing logic alone uses 4 refs and could be a reusable hook.
Location
File: packages/desktop/src/renderer/hooks/useVoiceInput.ts (351 lines)
Fix Approach
Split into focused hooks:
// usePressHoldTiming.ts — reusable, 0 voice-specific logic
export function usePressHoldTiming(delayMs: number) {
// holdTimerRef, pressStartedAtRef, pressActiveRef, startedFromCurrentPressRef
return { pressActive, startPress, endPress, clearHoldTimer };
}
// useVoiceSession.ts — session lifecycle only
export function useVoiceSession(createSession, requestPermission) {
return { isListening, isTranscribing, interimTranscript, errorCode, beginListening, stopListening };
}
// useVoiceInput.ts — thin orchestrator (original, now ~80 lines)
export function useVoiceInput(opts) {
const timing = usePressHoldTiming(opts.pressHoldDelayMs);
const session = useVoiceSession(opts.createSession, opts.requestPermission);
// Wire keyboard events + intro screen + transcript insertion
}
Verification
- Run
pnpm check — must pass
- Test voice input: press-and-hold space, short press space (inserts space), trigger via UI button
Context
- WG: UI & Design System
- Priority: Medium
- Estimated effort: ~1.5 hours
Problem
useVoiceInputis a 351-line hook managing 5 distinct concerns:holdTimerRef,pressStartedAtRef,pressActiveRef,startedFromCurrentPressRef) for detecting long-presshandleKeyDown/handleKeyUpwith complex space-bar interceptionisIntroOpen,introSeenRef,confirmIntro,dismissIntroinsertIntoTextarea,insertLiteralSpaceThe press-hold timing logic alone uses 4 refs and could be a reusable hook.
Location
File:
packages/desktop/src/renderer/hooks/useVoiceInput.ts(351 lines)Fix Approach
Split into focused hooks:
Verification
pnpm check— must passContext