Skip to content

Commit 4363a4e

Browse files
committed
[IMPL] useSpeechRecognition hook
1 parent ca0b7d0 commit 4363a4e

3 files changed

Lines changed: 36 additions & 53 deletions

File tree

apps/react-tools-demo/src/components/hooks/useSpeechRecognition/UseSpeechRecognition.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,17 @@ export const UseSpeechRecognition = () => {
1818

1919
const [state, start, stop] = useSpeechRecognition({
2020
onStart: useCallback(() => {
21-
console.log("onStart");
2221
setMessage("Listening...")
2322
}, []),
24-
onSpeechEnd: () => {
25-
console.log("onSpeechEnd");
23+
onEnd: useCallback(() => {
2624
stop();
2725
setMessage("Finish");
2826
perform();
29-
},
27+
}, [perform]),
3028
onNoMatch: useCallback(() => {
31-
console.log("onNoMatch");
3229
setMessage("Color not recognized.")
3330
}, []),
3431
onError: useCallback((ev: SpeechRecognitionErrorEvent) => {
35-
console.log("onError");
3632
setMessage(`Error occurred in recognition: ${ev.message ? ev.message : ev.error}`);
3733
}, []),
3834
});

apps/react-tools-demo/src/markdown/useSpeechRecognition.md

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -8,48 +8,27 @@ export const UseSpeechRecognition = () => {
88
const colors = ['aqua', 'azure', 'beige', 'bisque', 'black', 'blue', 'brown', 'chocolate', 'coral', 'crimson', 'cyan', 'fuchsia', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'indigo', 'ivory', 'khaki', 'lavender', 'lime', 'linen', 'magenta', 'maroon', 'moccasin', 'navy', 'olive', 'orange', 'orchid', 'peru', 'pink', 'plum', 'purple', 'red', 'salmon', 'sienna', 'silver', 'snow', 'tan', 'teal', 'thistle', 'tomato', 'turquoise', 'violet', 'white', 'yellow', 'transparent']
99
const grammar = `#JSGF V1.0; grammar colors; public <color> = ${colors.join(' | ')} ;`
1010

11-
const btnRef = useRef<HTMLButtonElement>();
11+
const btnRef = useRef<HTMLButtonElement>(null);
1212
const perform = usePerformAction(() => btnRef.current?.focus());
1313

1414
const [message, setMessage] = useState("Ready");
15+
const [count, setCount] = useState(0);
1516

1617
const [state, start, stop] = useSpeechRecognition({
1718
onStart: useCallback(() => {
1819
console.log("onStart");
19-
setMessage("Listening...")
20-
}, []),
21-
onEnd: useCallback(() => {
22-
console.log("onEnd");
23-
setMessage("Finish");
24-
}, []),
25-
onAudioEnd: () => {
26-
console.log("onAudioEnd");
27-
},
28-
onAudioStart: () => {
29-
console.log("onAudioStart");
30-
},
31-
onSoundStart: () => {
32-
console.log("onSoundStart");
33-
},
34-
onSoundEnd: () => {
35-
console.log("onSoundEnd");
36-
},
37-
onSpeechStart: () => {
38-
console.log("onSpeechStart");
39-
},
20+
setMessage("Listening... " + count)
21+
}, [count]),
4022
onSpeechEnd: () => {
4123
console.log("onSpeechEnd");
24+
stop();
25+
setMessage("Finish");
26+
perform();
4227
},
4328
onNoMatch: useCallback(() => {
4429
console.log("onNoMatch");
4530
setMessage("Color not recognized.")
4631
}, []),
47-
onResult: useCallback(() => {
48-
console.log("onResult");
49-
stop();
50-
setMessage("Ready");
51-
perform();
52-
}, []),
5332
onError: useCallback((ev: SpeechRecognitionErrorEvent) => {
5433
console.log("onError");
5534
setMessage(`Error occurred in recognition: ${ev.message ? ev.message : ev.error}`);
@@ -61,7 +40,7 @@ export const UseSpeechRecognition = () => {
6140
grammars.addFromString(grammar, 1);
6241
start({
6342
lang: "en-US",
64-
continuous: true,
43+
continuous: false,
6544
interimResults: false,
6645
maxAlternatives: 1,
6746
grammars
@@ -77,7 +56,7 @@ export const UseSpeechRecognition = () => {
7756
}
7857
}
7958
return colr;
80-
}, [state.result, colors]);
59+
}, [state.result.results, colors]);
8160

8261
return <div style={{ display: "flex", flexDirection: "column", justifyContent: "center", gap: 10 }}>
8362
{
@@ -99,6 +78,7 @@ export const UseSpeechRecognition = () => {
9978
</div>
10079
<div style={{ display: 'flex', justifyContent: "center", gap: 10 }}>
10180
<button ref={btnRef} onClick={onStart} disabled={state.isListening}>Start</button>
81+
<button onClick={()=>setCount(c=>c+1)}>Increment</button>
10282
</div>
10383
</>
10484
: <p>Speech Recognition not supported</p>
@@ -113,7 +93,7 @@ export const UseSpeechRecognition = () => {
11393
## API
11494

11595
```tsx
116-
useSpeechRecognition({ defaultConfig, onAudioStart, onAudioEnd, onEnd, onError, onNoMatch, onResult, onSoundStart, onSoundEnd, onSpeechStart, onSpeechEnd, onStart }: { defaultConfig?: SpeechRecognitionConfig, onAudioStart?: SpeechRecognition["onaudiostart"], onAudioEnd?: SpeechRecognition["onaudioend"], onEnd?: SpeechRecognition["onend"], onError?: SpeechRecognition["onerror"], onNoMatch?: SpeechRecognition["onnomatch"], onResult?: SpeechRecognition["onresult"], onSoundStart?: SpeechRecognition["onsoundstart"], onSoundEnd?: SpeechRecognition["onsoundend"], onSpeechStart?: SpeechRecognition["onspeechstart"], onSpeechEnd?: SpeechRecognition["onspeechend"], onStart?: SpeechRecognition["onstart"] }): [{isSupported: boolean, isListening: boolean, result: {results: SpeechRecognitionEvent["results"]|null, resultIndex: SpeechRecognitionEvent["resultIndex"]|null}}, (config?: SpeechRecognitionConfig)=>void, ()=>void]
96+
useSpeechRecognition({ defaultConfig, onAudioStart, onAudioEnd, onEnd, onError, onNoMatch, onResult, onSoundStart, onSoundEnd, onSpeechStart, onSpeechEnd, onStart }: { defaultConfig?: SpeechRecognitionConfig, onAudioStart?: SpeechRecognition["onaudiostart"], onAudioEnd?: SpeechRecognition["onaudioend"], onEnd?: SpeechRecognition["onend"], onError?: SpeechRecognition["onerror"], onNoMatch?: SpeechRecognition["onnomatch"], onResult?: SpeechRecognition["onresult"], onSoundStart?: SpeechRecognition["onsoundstart"], onSoundEnd?: SpeechRecognition["onsoundend"], onSpeechStart?: SpeechRecognition["onspeechstart"], onSpeechEnd?: SpeechRecognition["onspeechend"], onStart?: SpeechRecognition["onstart"] }): [SpeechRecognitionState, (config?: SpeechRecognitionConfig) => void, () => void, (resultAlso?: boolean) => void]
11797
```
11898
11999
> ### Params
@@ -159,16 +139,15 @@ function that will be executed when _start_ event is dispatched.
159139
> ### Returns
160140
>
161141
> __result__: __Array__:
162-
- __Object__:
163-
- __isSupported__ : _boolean_
164-
- __isListening__ : _boolean_
165-
- _result:{results: SpeechRecognitionEvent["results"]|null, resultIndex:SpeechRecognitionEvent["resultIndex"]|null}_
142+
- _SpeechRecognitionState_
166143
- _(config?: SpeechRecognitionConfig)=>void_
167144
- _()=>void_
145+
- _(resultAlso?:boolean)=>void_
168146
> - 1. __state__: object with these properties:
169147
> - _isSupported_: returns a boolean to know if API is available.
170148
> - _isListening_: returns a boolean indicating current SpeechRecognition execution or not.
171149
> - _result_: returns result of SpeechRecognition execution.
172150
> - 2. __start__: function to start SpeechRecognition.
173151
> - 3. __stop__: function to stop SpeechRecognition.
152+
> - 4. __reset__: function to reset SpeechRecognition with optional parameter to reset results also.
174153
>

packages/react-tools/src/models/useSpeechRecognition.model.ts

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ import { LanguageBCP47Tags } from ".";
22

33
/**The interface of state value returned from _useSpeechRecognition_ hook.*/
44
export interface SpeechRecognitionState {
5+
/**Returns a boolean value indicating SpeechRecognition availability.*/
56
isSupported: boolean;
7+
/**Returns a boolean value indicating if SpeechRecognition is listening or not.*/
68
isListening: boolean;
9+
/**Returns an object with _results_ and _resultIndex_ properties of SpeechRecognition execution.*/
710
result: {
811
results: SpeechRecognitionEvent["results"]|null,
912
resultIndex: SpeechRecognitionEvent["resultIndex"]|null
@@ -57,25 +60,30 @@ export interface SpeechRecognition extends EventTarget {
5760
}
5861

5962
export interface SpeechRecognitionConfig {
63+
/**Returns and sets a collection of _SpeechGrammar_ objects that represent the grammars that will be understood by the current SpeechRecognition.*/
6064
grammars?: SpeechGrammarList;
61-
continuous?: boolean;
65+
/**Returns and sets the language of the current SpeechRecognition. If not specified, this defaults to the HTML lang attribute value, or the user agent's language setting if that isn't set either.*/
6266
lang?: LanguageBCP47Tags;
67+
/**Controls whether continuous results are returned for each recognition, or only a single result. Defaults to single (false.)*/
68+
continuous?: boolean;
69+
/**Controls whether interim results should be returned (true) or not (false.) Interim results are results that are not yet final (e.g. the SpeechRecognitionResult.isFinal property is false.)*/
6370
interimResults?: boolean;
71+
/**Sets the maximum number of SpeechRecognitionAlternatives provided per result. The default value is 1.*/
6472
maxAlternatives?: number;
6573
}
6674

6775
interface SpeechRecognitionEventMap {
68-
'audioend': Event
69-
'audiostart': Event
70-
'end': Event
71-
'error': SpeechRecognitionErrorEvent
72-
'nomatch': SpeechRecognitionEvent
73-
'result': SpeechRecognitionEvent
74-
'soundend': Event
75-
'soundstart': Event
76-
'speechend': Event
77-
'speechstart': Event
78-
'start': Event
76+
'audioend': Event;
77+
'audiostart': Event;
78+
'end': Event;
79+
'error': SpeechRecognitionErrorEvent;
80+
'nomatch': SpeechRecognitionEvent;
81+
'result': SpeechRecognitionEvent;
82+
'soundend': Event;
83+
'soundstart': Event;
84+
'speechend': Event;
85+
'speechstart': Event;
86+
'start': Event;
7987
}
8088

8189
export type SpeechRecognitionErrorCode = 'aborted' | 'audio-capture' | 'bad-grammar' | 'language-not-supported' | 'network' | 'no-speech' | 'not-allowed' | 'service-not-allowed'

0 commit comments

Comments
 (0)