MCPcopy Create free account
hub / github.com/adobe/react-spectrum / useVoiceInput

Function useVoiceInput

packages/@react-spectrum/ai/src/useVoiceInput.ts:230–312  ·  view source on GitHub ↗
(options: VoiceInputProps)

Source from the content-addressed store, hash-verified

228};
229
230export const useVoiceInput = (options: VoiceInputProps): VoiceInputResult => {
231 const {lang, onError, onListeningChange} = options;
232
233 // Resolve support once — it cannot change for the lifetime of the page.
234 const ctor = useMemo(() => (isSecureVoiceContext() ? getRecognitionCtor() : null), []);
235 const isSupported = ctor !== null;
236
237 const [isListening, setIsListening] = useState(false);
238 const [errorCode, setErrorCode] = useState<VoiceInputErrorCode | null>(null);
239 const [interimTranscript, setInterimTranscript] = useState('');
240 const [finalTranscript, setFinalTranscript] = useState('');
241 const transcript = finalTranscript + interimTranscript;
242
243 const recognitionRef = useRef<SpeechRecognition | null>(null);
244 const startingRef = useRef(false);
245 const handleError = useEffectEvent((code: VoiceInputErrorCode) => {
246 onError?.(code);
247 });
248 const handleListeningChange = useEffectEvent((v: boolean) => {
249 onListeningChange?.(v);
250 });
251
252 const stop = useCallback(() => {
253 recognitionRef.current?.stop();
254 }, []);
255
256 const start = useCallback(() => {
257 // Guard against double-start (a started recognizer throws InvalidStateError)
258 // and against re-entry while the permission prompt is open.
259 if (!ctor || recognitionRef.current || startingRef.current) {
260 return;
261 }
262 startingRef.current = true;
263 setErrorCode(null);
264 setInterimTranscript('');
265 setFinalTranscript('');
266
267 // Request mic access first so the browser permission prompt reliably opens
268 // and a denial is reported before recognition starts.
269 void requestMicrophone().then(micError => {
270 startingRef.current = false;
271 if (micError) {
272 setErrorCode(micError);
273 handleError(micError);
274 return;
275 }
276 // Bail if already started while the permission prompt was open.
277 if (recognitionRef.current) {
278 return;
279 }
280
281 const recognition = createRecognizer(ctor, lang ?? navigator.language ?? 'en-US', {
282 recognitionRef,
283 setListening: setIsListening,
284 onListeningChange: handleListeningChange,
285 onError: handleError,
286 setError: setErrorCode,
287 setInterim: setInterimTranscript,

Callers 1

PromptFieldVoiceButtonFunction · 0.90

Calls 11

useEffectEventFunction · 0.90
isSecureVoiceContextFunction · 0.85
getRecognitionCtorFunction · 0.85
onErrorFunction · 0.85
requestMicrophoneFunction · 0.85
createRecognizerFunction · 0.85
startMethod · 0.80
abortMethod · 0.80
stopFunction · 0.70
stopMethod · 0.65
startFunction · 0.50

Tested by

no test coverage detected