react-native-voice-ts 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -32,7 +32,7 @@ const VoiceMicrophone = ({ onSpeechResult, onPartialResult, onStart, onStop, onE
32
32
  const [recognizedText, setRecognizedText] = useState('');
33
33
  const [partialText, setPartialText] = useState('');
34
34
  const [error, setError] = useState(null);
35
- const [shouldContinue, setShouldContinue] = useState(false);
35
+ const shouldContinueRef = React.useRef(false);
36
36
  const silenceTimerRef = React.useRef(null);
37
37
  useEffect(() => {
38
38
  // Clear any existing timers on cleanup
@@ -55,10 +55,10 @@ const VoiceMicrophone = ({ onSpeechResult, onPartialResult, onStart, onStop, onE
55
55
  Voice.onSpeechEnd = async () => {
56
56
  setIsRecording(false);
57
57
  // In continuous mode, restart listening after results
58
- if (continuous && shouldContinue) {
58
+ if (continuous && shouldContinueRef.current) {
59
59
  // Small delay before restarting
60
60
  setTimeout(async () => {
61
- if (shouldContinue) {
61
+ if (shouldContinueRef.current) {
62
62
  try {
63
63
  await Voice.start(locale, {
64
64
  EXTRA_PARTIAL_RESULTS: enablePartialResults,
@@ -78,7 +78,7 @@ const VoiceMicrophone = ({ onSpeechResult, onPartialResult, onStart, onStop, onE
78
78
  const errorMessage = e.error?.message || 'Unknown error';
79
79
  setError(errorMessage);
80
80
  setIsRecording(false);
81
- setShouldContinue(false);
81
+ shouldContinueRef.current = false;
82
82
  if (silenceTimerRef.current) {
83
83
  clearTimeout(silenceTimerRef.current);
84
84
  }
@@ -109,9 +109,15 @@ const VoiceMicrophone = ({ onSpeechResult, onPartialResult, onStart, onStop, onE
109
109
  // Reset silence timer on partial results (user is speaking)
110
110
  if (continuous && silenceTimerRef.current) {
111
111
  clearTimeout(silenceTimerRef.current);
112
- silenceTimerRef.current = setTimeout(() => {
113
- if (shouldContinue) {
114
- stop();
112
+ silenceTimerRef.current = setTimeout(async () => {
113
+ if (shouldContinueRef.current) {
114
+ shouldContinueRef.current = false;
115
+ if (silenceTimerRef.current) {
116
+ clearTimeout(silenceTimerRef.current);
117
+ silenceTimerRef.current = null;
118
+ }
119
+ await Voice.stop();
120
+ onStop?.();
115
121
  }
116
122
  }, maxSilenceDuration);
117
123
  }
@@ -130,7 +136,6 @@ const VoiceMicrophone = ({ onSpeechResult, onPartialResult, onStart, onStop, onE
130
136
  onError,
131
137
  enablePartialResults,
132
138
  continuous,
133
- shouldContinue,
134
139
  recognizedText,
135
140
  locale,
136
141
  maxSilenceDuration,
@@ -149,7 +154,7 @@ const VoiceMicrophone = ({ onSpeechResult, onPartialResult, onStart, onStop, onE
149
154
  setRecognizedText('');
150
155
  setPartialText('');
151
156
  }
152
- setShouldContinue(true);
157
+ shouldContinueRef.current = true;
153
158
  // Check permission (Android only)
154
159
  const hasPermission = await Voice.checkMicrophonePermission();
155
160
  if (!hasPermission) {
@@ -164,9 +169,15 @@ const VoiceMicrophone = ({ onSpeechResult, onPartialResult, onStart, onStop, onE
164
169
  });
165
170
  // Start silence timer if in continuous mode
166
171
  if (continuous) {
167
- silenceTimerRef.current = setTimeout(() => {
168
- if (shouldContinue) {
169
- stop();
172
+ silenceTimerRef.current = setTimeout(async () => {
173
+ if (shouldContinueRef.current) {
174
+ shouldContinueRef.current = false;
175
+ if (silenceTimerRef.current) {
176
+ clearTimeout(silenceTimerRef.current);
177
+ silenceTimerRef.current = null;
178
+ }
179
+ await Voice.stop();
180
+ onStop?.();
170
181
  }
171
182
  }, maxSilenceDuration);
172
183
  }
@@ -174,7 +185,7 @@ const VoiceMicrophone = ({ onSpeechResult, onPartialResult, onStart, onStop, onE
174
185
  catch (e) {
175
186
  const errorMessage = e instanceof Error ? e.message : 'Failed to start recording';
176
187
  setError(errorMessage);
177
- setShouldContinue(false);
188
+ shouldContinueRef.current = false;
178
189
  onError?.(errorMessage);
179
190
  }
180
191
  }, [
@@ -183,11 +194,11 @@ const VoiceMicrophone = ({ onSpeechResult, onPartialResult, onStart, onStop, onE
183
194
  onError,
184
195
  continuous,
185
196
  maxSilenceDuration,
186
- shouldContinue,
197
+ onStop,
187
198
  ]);
188
199
  const stop = useCallback(async () => {
189
200
  try {
190
- setShouldContinue(false);
201
+ shouldContinueRef.current = false;
191
202
  if (silenceTimerRef.current) {
192
203
  clearTimeout(silenceTimerRef.current);
193
204
  silenceTimerRef.current = null;
@@ -203,7 +214,7 @@ const VoiceMicrophone = ({ onSpeechResult, onPartialResult, onStart, onStop, onE
203
214
  }, [onError, onStop]);
204
215
  const cancel = useCallback(async () => {
205
216
  try {
206
- setShouldContinue(false);
217
+ shouldContinueRef.current = false;
207
218
  if (silenceTimerRef.current) {
208
219
  clearTimeout(silenceTimerRef.current);
209
220
  silenceTimerRef.current = null;
@@ -27,7 +27,7 @@ export const useVoiceRecognition = (options = {}) => {
27
27
  const [results, setResults] = useState([]);
28
28
  const [partialResults, setPartialResults] = useState([]);
29
29
  const [error, setError] = useState(null);
30
- const [shouldContinue, setShouldContinue] = useState(false);
30
+ const shouldContinueRef = React.useRef(false);
31
31
  const silenceTimerRef = React.useRef(null);
32
32
  const accumulatedTextRef = React.useRef('');
33
33
  useEffect(() => {
@@ -50,9 +50,9 @@ export const useVoiceRecognition = (options = {}) => {
50
50
  Voice.onSpeechEnd = async () => {
51
51
  setIsRecording(false);
52
52
  // In continuous mode, restart listening after results
53
- if (continuous && shouldContinue) {
53
+ if (continuous && shouldContinueRef.current) {
54
54
  setTimeout(async () => {
55
- if (shouldContinue) {
55
+ if (shouldContinueRef.current) {
56
56
  try {
57
57
  await Voice.start(locale, {
58
58
  EXTRA_PARTIAL_RESULTS: enablePartialResults,
@@ -69,7 +69,7 @@ export const useVoiceRecognition = (options = {}) => {
69
69
  const errorMessage = e.error?.message || 'Unknown error';
70
70
  setError(errorMessage);
71
71
  setIsRecording(false);
72
- setShouldContinue(false);
72
+ shouldContinueRef.current = false;
73
73
  if (silenceTimerRef.current) {
74
74
  clearTimeout(silenceTimerRef.current);
75
75
  }
@@ -102,9 +102,14 @@ export const useVoiceRecognition = (options = {}) => {
102
102
  // Reset silence timer on partial results (user is speaking)
103
103
  if (continuous && silenceTimerRef.current) {
104
104
  clearTimeout(silenceTimerRef.current);
105
- silenceTimerRef.current = setTimeout(() => {
106
- if (shouldContinue) {
107
- stop();
105
+ silenceTimerRef.current = setTimeout(async () => {
106
+ if (shouldContinueRef.current) {
107
+ shouldContinueRef.current = false;
108
+ if (silenceTimerRef.current) {
109
+ clearTimeout(silenceTimerRef.current);
110
+ silenceTimerRef.current = null;
111
+ }
112
+ await Voice.stop();
108
113
  }
109
114
  }, maxSilenceDuration);
110
115
  }
@@ -120,7 +125,6 @@ export const useVoiceRecognition = (options = {}) => {
120
125
  onResult,
121
126
  onError,
122
127
  continuous,
123
- shouldContinue,
124
128
  locale,
125
129
  maxSilenceDuration,
126
130
  ]);
@@ -132,7 +136,7 @@ export const useVoiceRecognition = (options = {}) => {
132
136
  setPartialResults([]);
133
137
  accumulatedTextRef.current = '';
134
138
  }
135
- setShouldContinue(true);
139
+ shouldContinueRef.current = true;
136
140
  // Check permission (Android only)
137
141
  const hasPermission = await Voice.checkMicrophonePermission();
138
142
  if (!hasPermission) {
@@ -147,9 +151,14 @@ export const useVoiceRecognition = (options = {}) => {
147
151
  });
148
152
  // Start silence timer if in continuous mode
149
153
  if (continuous) {
150
- silenceTimerRef.current = setTimeout(() => {
151
- if (shouldContinue) {
152
- stop();
154
+ silenceTimerRef.current = setTimeout(async () => {
155
+ if (shouldContinueRef.current) {
156
+ shouldContinueRef.current = false;
157
+ if (silenceTimerRef.current) {
158
+ clearTimeout(silenceTimerRef.current);
159
+ silenceTimerRef.current = null;
160
+ }
161
+ await Voice.stop();
153
162
  }
154
163
  }, maxSilenceDuration);
155
164
  }
@@ -157,20 +166,13 @@ export const useVoiceRecognition = (options = {}) => {
157
166
  catch (e) {
158
167
  const errorMessage = e instanceof Error ? e.message : 'Failed to start recording';
159
168
  setError(errorMessage);
160
- setShouldContinue(false);
169
+ shouldContinueRef.current = false;
161
170
  onError?.(errorMessage);
162
171
  }
163
- }, [
164
- locale,
165
- enablePartialResults,
166
- onError,
167
- continuous,
168
- maxSilenceDuration,
169
- shouldContinue,
170
- ]);
172
+ }, [locale, enablePartialResults, onError, continuous, maxSilenceDuration]);
171
173
  const stop = useCallback(async () => {
172
174
  try {
173
- setShouldContinue(false);
175
+ shouldContinueRef.current = false;
174
176
  if (silenceTimerRef.current) {
175
177
  clearTimeout(silenceTimerRef.current);
176
178
  silenceTimerRef.current = null;
@@ -185,7 +187,7 @@ export const useVoiceRecognition = (options = {}) => {
185
187
  }, [onError]);
186
188
  const cancel = useCallback(async () => {
187
189
  try {
188
- setShouldContinue(false);
190
+ shouldContinueRef.current = false;
189
191
  if (silenceTimerRef.current) {
190
192
  clearTimeout(silenceTimerRef.current);
191
193
  silenceTimerRef.current = null;
@@ -207,7 +209,7 @@ export const useVoiceRecognition = (options = {}) => {
207
209
  setError(null);
208
210
  setIsRecording(false);
209
211
  accumulatedTextRef.current = '';
210
- setShouldContinue(false);
212
+ shouldContinueRef.current = false;
211
213
  if (silenceTimerRef.current) {
212
214
  clearTimeout(silenceTimerRef.current);
213
215
  silenceTimerRef.current = null;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "react-native-voice-ts",
3
3
  "description": "Advanced Speech-to-Text library for React Native with TypeScript support. Features ready-to-use components (VoiceMicrophone), custom hooks (useVoiceRecognition), real-time transcription, multi-language support, and comprehensive voice recognition capabilities for iOS and Android.",
4
- "version": "1.0.3",
4
+ "version": "1.0.4",
5
5
  "author": "Noor Mohammad <noor.jsdivs@gmail.com>",
6
6
  "private": false,
7
7
  "homepage": "https://github.com/noorjsdivs/react-native-voice-ts",
@@ -94,7 +94,7 @@
94
94
  "lint:plugin": "eslint plugin/src/* --fix",
95
95
  "clean": "rm -rf dist && rm -rf plugin/build",
96
96
  "prepack": "yarn clean && yarn build && yarn build:plugin",
97
- "test": "jest",
97
+ "test": "echo \"No tests in library root. Run 'yarn --cwd example test' to test the example app.\"",
98
98
  "validate": "yarn type-check && yarn lint:check && yarn format:check"
99
99
  },
100
100
  "dependencies": {