react-native-voice-ts 1.0.1 → 1.0.3
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.
- package/README.md +287 -77
- package/dist/NativeVoiceAndroid.d.ts +0 -1
- package/dist/NativeVoiceAndroid.js +0 -1
- package/dist/NativeVoiceIOS.d.ts +0 -1
- package/dist/NativeVoiceIOS.js +0 -1
- package/dist/VoiceModuleTypes.d.ts +0 -1
- package/dist/VoiceModuleTypes.js +0 -1
- package/dist/VoiceUtilTypes.d.ts +0 -1
- package/dist/VoiceUtilTypes.js +0 -1
- package/dist/components/MicIcon.d.ts +24 -5
- package/dist/components/MicIcon.js +71 -13
- package/dist/components/VoiceMicrophone.d.ts +12 -1
- package/dist/components/VoiceMicrophone.js +97 -10
- package/dist/components/index.d.ts +1 -2
- package/dist/components/index.js +1 -2
- package/dist/hooks/index.d.ts +0 -1
- package/dist/hooks/index.js +0 -1
- package/dist/hooks/useVoiceRecognition.d.ts +12 -1
- package/dist/hooks/useVoiceRecognition.js +109 -12
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/package.json +4 -8
- package/CONTRIBUTING.md +0 -293
- package/dist/NativeVoiceAndroid.d.ts.map +0 -1
- package/dist/NativeVoiceAndroid.js.map +0 -1
- package/dist/NativeVoiceIOS.d.ts.map +0 -1
- package/dist/NativeVoiceIOS.js.map +0 -1
- package/dist/VoiceModuleTypes.d.ts.map +0 -1
- package/dist/VoiceModuleTypes.js.map +0 -1
- package/dist/VoiceUtilTypes.d.ts.map +0 -1
- package/dist/VoiceUtilTypes.js.map +0 -1
- package/dist/components/MicIcon.d.ts.map +0 -1
- package/dist/components/MicIcon.js.map +0 -1
- package/dist/components/VoiceMicrophone.d.ts.map +0 -1
- package/dist/components/VoiceMicrophone.js.map +0 -1
- package/dist/components/index.d.ts.map +0 -1
- package/dist/components/index.js.map +0 -1
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/index.js.map +0 -1
- package/dist/hooks/useVoiceRecognition.d.ts.map +0 -1
- package/dist/hooks/useVoiceRecognition.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/ios/Voice.xcodeproj/project.xcworkspace/xcuserdata/olumayowadaniel.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/Voice.xcodeproj/project.xcworkspace/xcuserdata/rudie_shahinian.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/plugin/src/withVoice.ts +0 -74
- package/plugin/tsconfig.json +0 -10
- package/plugin/tsconfig.tsbuildinfo +0 -1
- package/src/NativeVoiceAndroid.ts +0 -28
- package/src/NativeVoiceIOS.ts +0 -24
- package/src/VoiceModuleTypes.ts +0 -64
- package/src/VoiceUtilTypes.ts +0 -46
- package/src/components/MicIcon.tsx +0 -72
- package/src/components/VoiceMicrophone.tsx +0 -238
- package/src/components/index.ts +0 -4
- package/src/hooks/index.ts +0 -5
- package/src/hooks/useVoiceRecognition.ts +0 -217
- package/src/images/mic.svg +0 -16
- package/src/index.ts +0 -515
|
@@ -27,33 +27,77 @@ import Voice from '../index';
|
|
|
27
27
|
* </VoiceMicrophone>
|
|
28
28
|
* ```
|
|
29
29
|
*/
|
|
30
|
-
const VoiceMicrophone = ({ onSpeechResult, onPartialResult, onStart, onStop, onError, locale = 'en-US', autoStart = false, enablePartialResults = true, children, }) => {
|
|
30
|
+
const VoiceMicrophone = ({ onSpeechResult, onPartialResult, onStart, onStop, onError, locale = 'en-US', autoStart = false, enablePartialResults = true, continuous = false, maxSilenceDuration = 5000, children, }) => {
|
|
31
31
|
const [isRecording, setIsRecording] = useState(false);
|
|
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);
|
|
36
|
+
const silenceTimerRef = React.useRef(null);
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
// Clear any existing timers on cleanup
|
|
39
|
+
return () => {
|
|
40
|
+
if (silenceTimerRef.current) {
|
|
41
|
+
clearTimeout(silenceTimerRef.current);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}, []);
|
|
35
45
|
useEffect(() => {
|
|
36
46
|
// Set up event listeners
|
|
37
47
|
Voice.onSpeechStart = () => {
|
|
38
48
|
setIsRecording(true);
|
|
39
49
|
setError(null);
|
|
50
|
+
if (silenceTimerRef.current) {
|
|
51
|
+
clearTimeout(silenceTimerRef.current);
|
|
52
|
+
}
|
|
40
53
|
onStart?.();
|
|
41
54
|
};
|
|
42
|
-
Voice.onSpeechEnd = () => {
|
|
55
|
+
Voice.onSpeechEnd = async () => {
|
|
43
56
|
setIsRecording(false);
|
|
44
|
-
|
|
57
|
+
// In continuous mode, restart listening after results
|
|
58
|
+
if (continuous && shouldContinue) {
|
|
59
|
+
// Small delay before restarting
|
|
60
|
+
setTimeout(async () => {
|
|
61
|
+
if (shouldContinue) {
|
|
62
|
+
try {
|
|
63
|
+
await Voice.start(locale, {
|
|
64
|
+
EXTRA_PARTIAL_RESULTS: enablePartialResults,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
console.error('Failed to restart voice recognition:', err);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}, 100);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
onStop?.();
|
|
75
|
+
}
|
|
45
76
|
};
|
|
46
77
|
Voice.onSpeechError = (e) => {
|
|
47
78
|
const errorMessage = e.error?.message || 'Unknown error';
|
|
48
79
|
setError(errorMessage);
|
|
49
80
|
setIsRecording(false);
|
|
81
|
+
setShouldContinue(false);
|
|
82
|
+
if (silenceTimerRef.current) {
|
|
83
|
+
clearTimeout(silenceTimerRef.current);
|
|
84
|
+
}
|
|
50
85
|
onError?.(errorMessage);
|
|
51
86
|
};
|
|
52
87
|
Voice.onSpeechResults = (e) => {
|
|
53
88
|
if (e.value && e.value.length > 0) {
|
|
54
89
|
const text = e.value[0];
|
|
55
|
-
|
|
56
|
-
|
|
90
|
+
// In continuous mode, append new text to existing
|
|
91
|
+
if (continuous && recognizedText) {
|
|
92
|
+
const updatedText = recognizedText + ' ' + text;
|
|
93
|
+
setRecognizedText(updatedText);
|
|
94
|
+
onSpeechResult?.(updatedText);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
setRecognizedText(text);
|
|
98
|
+
onSpeechResult?.(text);
|
|
99
|
+
}
|
|
100
|
+
setPartialText('');
|
|
57
101
|
}
|
|
58
102
|
};
|
|
59
103
|
if (enablePartialResults) {
|
|
@@ -62,6 +106,15 @@ const VoiceMicrophone = ({ onSpeechResult, onPartialResult, onStart, onStop, onE
|
|
|
62
106
|
const text = e.value[0];
|
|
63
107
|
setPartialText(text);
|
|
64
108
|
onPartialResult?.(text);
|
|
109
|
+
// Reset silence timer on partial results (user is speaking)
|
|
110
|
+
if (continuous && silenceTimerRef.current) {
|
|
111
|
+
clearTimeout(silenceTimerRef.current);
|
|
112
|
+
silenceTimerRef.current = setTimeout(() => {
|
|
113
|
+
if (shouldContinue) {
|
|
114
|
+
stop();
|
|
115
|
+
}
|
|
116
|
+
}, maxSilenceDuration);
|
|
117
|
+
}
|
|
65
118
|
}
|
|
66
119
|
};
|
|
67
120
|
}
|
|
@@ -76,6 +129,11 @@ const VoiceMicrophone = ({ onSpeechResult, onPartialResult, onStart, onStop, onE
|
|
|
76
129
|
onStop,
|
|
77
130
|
onError,
|
|
78
131
|
enablePartialResults,
|
|
132
|
+
continuous,
|
|
133
|
+
shouldContinue,
|
|
134
|
+
recognizedText,
|
|
135
|
+
locale,
|
|
136
|
+
maxSilenceDuration,
|
|
79
137
|
]);
|
|
80
138
|
// Auto-start if enabled
|
|
81
139
|
useEffect(() => {
|
|
@@ -87,8 +145,11 @@ const VoiceMicrophone = ({ onSpeechResult, onPartialResult, onStart, onStop, onE
|
|
|
87
145
|
const start = useCallback(async () => {
|
|
88
146
|
try {
|
|
89
147
|
setError(null);
|
|
90
|
-
|
|
91
|
-
|
|
148
|
+
if (!continuous) {
|
|
149
|
+
setRecognizedText('');
|
|
150
|
+
setPartialText('');
|
|
151
|
+
}
|
|
152
|
+
setShouldContinue(true);
|
|
92
153
|
// Check permission (Android only)
|
|
93
154
|
const hasPermission = await Voice.checkMicrophonePermission();
|
|
94
155
|
if (!hasPermission) {
|
|
@@ -101,25 +162,52 @@ const VoiceMicrophone = ({ onSpeechResult, onPartialResult, onStart, onStop, onE
|
|
|
101
162
|
await Voice.start(locale, {
|
|
102
163
|
EXTRA_PARTIAL_RESULTS: enablePartialResults,
|
|
103
164
|
});
|
|
165
|
+
// Start silence timer if in continuous mode
|
|
166
|
+
if (continuous) {
|
|
167
|
+
silenceTimerRef.current = setTimeout(() => {
|
|
168
|
+
if (shouldContinue) {
|
|
169
|
+
stop();
|
|
170
|
+
}
|
|
171
|
+
}, maxSilenceDuration);
|
|
172
|
+
}
|
|
104
173
|
}
|
|
105
174
|
catch (e) {
|
|
106
175
|
const errorMessage = e instanceof Error ? e.message : 'Failed to start recording';
|
|
107
176
|
setError(errorMessage);
|
|
177
|
+
setShouldContinue(false);
|
|
108
178
|
onError?.(errorMessage);
|
|
109
179
|
}
|
|
110
|
-
}, [
|
|
180
|
+
}, [
|
|
181
|
+
locale,
|
|
182
|
+
enablePartialResults,
|
|
183
|
+
onError,
|
|
184
|
+
continuous,
|
|
185
|
+
maxSilenceDuration,
|
|
186
|
+
shouldContinue,
|
|
187
|
+
]);
|
|
111
188
|
const stop = useCallback(async () => {
|
|
112
189
|
try {
|
|
190
|
+
setShouldContinue(false);
|
|
191
|
+
if (silenceTimerRef.current) {
|
|
192
|
+
clearTimeout(silenceTimerRef.current);
|
|
193
|
+
silenceTimerRef.current = null;
|
|
194
|
+
}
|
|
113
195
|
await Voice.stop();
|
|
196
|
+
onStop?.();
|
|
114
197
|
}
|
|
115
198
|
catch (e) {
|
|
116
199
|
const errorMessage = e instanceof Error ? e.message : 'Failed to stop recording';
|
|
117
200
|
setError(errorMessage);
|
|
118
201
|
onError?.(errorMessage);
|
|
119
202
|
}
|
|
120
|
-
}, [onError]);
|
|
203
|
+
}, [onError, onStop]);
|
|
121
204
|
const cancel = useCallback(async () => {
|
|
122
205
|
try {
|
|
206
|
+
setShouldContinue(false);
|
|
207
|
+
if (silenceTimerRef.current) {
|
|
208
|
+
clearTimeout(silenceTimerRef.current);
|
|
209
|
+
silenceTimerRef.current = null;
|
|
210
|
+
}
|
|
123
211
|
await Voice.cancel();
|
|
124
212
|
setRecognizedText('');
|
|
125
213
|
setPartialText('');
|
|
@@ -148,4 +236,3 @@ const VoiceMicrophone = ({ onSpeechResult, onPartialResult, onStart, onStop, onE
|
|
|
148
236
|
return null;
|
|
149
237
|
};
|
|
150
238
|
export default VoiceMicrophone;
|
|
151
|
-
//# sourceMappingURL=VoiceMicrophone.js.map
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export { default as VoiceMicrophone } from './VoiceMicrophone';
|
|
2
2
|
export type { VoiceMicrophoneProps } from './VoiceMicrophone';
|
|
3
|
-
export { MicIcon, MicOffIcon } from './MicIcon';
|
|
3
|
+
export { MicIcon, MicOffIcon, MicIconFilled, MicOffIconFilled, MicIconWave, MicOffIconWave, } from './MicIcon';
|
|
4
4
|
export type { MicIconProps, MicOffIconProps } from './MicIcon';
|
|
5
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/components/index.js
CHANGED
package/dist/hooks/index.d.ts
CHANGED
package/dist/hooks/index.js
CHANGED
|
@@ -9,6 +9,18 @@ export interface UseVoiceRecognitionOptions {
|
|
|
9
9
|
* @default true
|
|
10
10
|
*/
|
|
11
11
|
enablePartialResults?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Whether to continue listening after getting results (continuous mode)
|
|
14
|
+
* When enabled, the microphone will automatically restart after getting results
|
|
15
|
+
* @default false
|
|
16
|
+
*/
|
|
17
|
+
continuous?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Maximum silence duration in milliseconds before stopping (continuous mode)
|
|
20
|
+
* Only applies when continuous mode is enabled
|
|
21
|
+
* @default 5000 (5 seconds)
|
|
22
|
+
*/
|
|
23
|
+
maxSilenceDuration?: number;
|
|
12
24
|
/**
|
|
13
25
|
* Callback fired when speech is recognized
|
|
14
26
|
*/
|
|
@@ -74,4 +86,3 @@ export interface UseVoiceRecognitionReturn {
|
|
|
74
86
|
* ```
|
|
75
87
|
*/
|
|
76
88
|
export declare const useVoiceRecognition: (options?: UseVoiceRecognitionOptions) => UseVoiceRecognitionReturn;
|
|
77
|
-
//# sourceMappingURL=useVoiceRecognition.d.ts.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect, useState, useCallback } from 'react';
|
|
1
|
+
import React, { useEffect, useState, useCallback } from 'react';
|
|
2
2
|
import Voice from '../index';
|
|
3
3
|
/**
|
|
4
4
|
* Custom hook for voice recognition
|
|
@@ -22,32 +22,76 @@ import Voice from '../index';
|
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
24
|
export const useVoiceRecognition = (options = {}) => {
|
|
25
|
-
const { locale = 'en-US', enablePartialResults = true, onResult, onError, } = options;
|
|
25
|
+
const { locale = 'en-US', enablePartialResults = true, continuous = false, maxSilenceDuration = 5000, onResult, onError, } = options;
|
|
26
26
|
const [isRecording, setIsRecording] = useState(false);
|
|
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);
|
|
31
|
+
const silenceTimerRef = React.useRef(null);
|
|
32
|
+
const accumulatedTextRef = React.useRef('');
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
// Clear any existing timers on cleanup
|
|
35
|
+
return () => {
|
|
36
|
+
if (silenceTimerRef.current) {
|
|
37
|
+
clearTimeout(silenceTimerRef.current);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}, []);
|
|
30
41
|
useEffect(() => {
|
|
31
42
|
// Set up event listeners
|
|
32
43
|
Voice.onSpeechStart = () => {
|
|
33
44
|
setIsRecording(true);
|
|
34
45
|
setError(null);
|
|
46
|
+
if (silenceTimerRef.current) {
|
|
47
|
+
clearTimeout(silenceTimerRef.current);
|
|
48
|
+
}
|
|
35
49
|
};
|
|
36
|
-
Voice.onSpeechEnd = () => {
|
|
50
|
+
Voice.onSpeechEnd = async () => {
|
|
37
51
|
setIsRecording(false);
|
|
52
|
+
// In continuous mode, restart listening after results
|
|
53
|
+
if (continuous && shouldContinue) {
|
|
54
|
+
setTimeout(async () => {
|
|
55
|
+
if (shouldContinue) {
|
|
56
|
+
try {
|
|
57
|
+
await Voice.start(locale, {
|
|
58
|
+
EXTRA_PARTIAL_RESULTS: enablePartialResults,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
console.error('Failed to restart voice recognition:', err);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}, 100);
|
|
66
|
+
}
|
|
38
67
|
};
|
|
39
68
|
Voice.onSpeechError = (e) => {
|
|
40
69
|
const errorMessage = e.error?.message || 'Unknown error';
|
|
41
70
|
setError(errorMessage);
|
|
42
71
|
setIsRecording(false);
|
|
72
|
+
setShouldContinue(false);
|
|
73
|
+
if (silenceTimerRef.current) {
|
|
74
|
+
clearTimeout(silenceTimerRef.current);
|
|
75
|
+
}
|
|
43
76
|
onError?.(errorMessage);
|
|
44
77
|
};
|
|
45
78
|
Voice.onSpeechResults = (e) => {
|
|
46
79
|
if (e.value && e.value.length > 0) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
80
|
+
if (continuous) {
|
|
81
|
+
// Append new text to accumulated text
|
|
82
|
+
const newText = e.value[0];
|
|
83
|
+
accumulatedTextRef.current = accumulatedTextRef.current
|
|
84
|
+
? accumulatedTextRef.current + ' ' + newText
|
|
85
|
+
: newText;
|
|
86
|
+
setResults([accumulatedTextRef.current, ...e.value.slice(1)]);
|
|
87
|
+
onResult?.(accumulatedTextRef.current);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
setResults(e.value);
|
|
91
|
+
const firstResult = e.value[0];
|
|
92
|
+
if (firstResult) {
|
|
93
|
+
onResult?.(firstResult);
|
|
94
|
+
}
|
|
51
95
|
}
|
|
52
96
|
}
|
|
53
97
|
};
|
|
@@ -55,6 +99,15 @@ export const useVoiceRecognition = (options = {}) => {
|
|
|
55
99
|
Voice.onSpeechPartialResults = (e) => {
|
|
56
100
|
if (e.value && e.value.length > 0) {
|
|
57
101
|
setPartialResults(e.value);
|
|
102
|
+
// Reset silence timer on partial results (user is speaking)
|
|
103
|
+
if (continuous && silenceTimerRef.current) {
|
|
104
|
+
clearTimeout(silenceTimerRef.current);
|
|
105
|
+
silenceTimerRef.current = setTimeout(() => {
|
|
106
|
+
if (shouldContinue) {
|
|
107
|
+
stop();
|
|
108
|
+
}
|
|
109
|
+
}, maxSilenceDuration);
|
|
110
|
+
}
|
|
58
111
|
}
|
|
59
112
|
};
|
|
60
113
|
}
|
|
@@ -62,12 +115,24 @@ export const useVoiceRecognition = (options = {}) => {
|
|
|
62
115
|
return () => {
|
|
63
116
|
Voice.destroy().then(Voice.removeAllListeners);
|
|
64
117
|
};
|
|
65
|
-
}, [
|
|
118
|
+
}, [
|
|
119
|
+
enablePartialResults,
|
|
120
|
+
onResult,
|
|
121
|
+
onError,
|
|
122
|
+
continuous,
|
|
123
|
+
shouldContinue,
|
|
124
|
+
locale,
|
|
125
|
+
maxSilenceDuration,
|
|
126
|
+
]);
|
|
66
127
|
const start = useCallback(async () => {
|
|
67
128
|
try {
|
|
68
129
|
setError(null);
|
|
69
|
-
|
|
70
|
-
|
|
130
|
+
if (!continuous) {
|
|
131
|
+
setResults([]);
|
|
132
|
+
setPartialResults([]);
|
|
133
|
+
accumulatedTextRef.current = '';
|
|
134
|
+
}
|
|
135
|
+
setShouldContinue(true);
|
|
71
136
|
// Check permission (Android only)
|
|
72
137
|
const hasPermission = await Voice.checkMicrophonePermission();
|
|
73
138
|
if (!hasPermission) {
|
|
@@ -80,15 +145,36 @@ export const useVoiceRecognition = (options = {}) => {
|
|
|
80
145
|
await Voice.start(locale, {
|
|
81
146
|
EXTRA_PARTIAL_RESULTS: enablePartialResults,
|
|
82
147
|
});
|
|
148
|
+
// Start silence timer if in continuous mode
|
|
149
|
+
if (continuous) {
|
|
150
|
+
silenceTimerRef.current = setTimeout(() => {
|
|
151
|
+
if (shouldContinue) {
|
|
152
|
+
stop();
|
|
153
|
+
}
|
|
154
|
+
}, maxSilenceDuration);
|
|
155
|
+
}
|
|
83
156
|
}
|
|
84
157
|
catch (e) {
|
|
85
158
|
const errorMessage = e instanceof Error ? e.message : 'Failed to start recording';
|
|
86
159
|
setError(errorMessage);
|
|
160
|
+
setShouldContinue(false);
|
|
87
161
|
onError?.(errorMessage);
|
|
88
162
|
}
|
|
89
|
-
}, [
|
|
163
|
+
}, [
|
|
164
|
+
locale,
|
|
165
|
+
enablePartialResults,
|
|
166
|
+
onError,
|
|
167
|
+
continuous,
|
|
168
|
+
maxSilenceDuration,
|
|
169
|
+
shouldContinue,
|
|
170
|
+
]);
|
|
90
171
|
const stop = useCallback(async () => {
|
|
91
172
|
try {
|
|
173
|
+
setShouldContinue(false);
|
|
174
|
+
if (silenceTimerRef.current) {
|
|
175
|
+
clearTimeout(silenceTimerRef.current);
|
|
176
|
+
silenceTimerRef.current = null;
|
|
177
|
+
}
|
|
92
178
|
await Voice.stop();
|
|
93
179
|
}
|
|
94
180
|
catch (e) {
|
|
@@ -99,9 +185,15 @@ export const useVoiceRecognition = (options = {}) => {
|
|
|
99
185
|
}, [onError]);
|
|
100
186
|
const cancel = useCallback(async () => {
|
|
101
187
|
try {
|
|
188
|
+
setShouldContinue(false);
|
|
189
|
+
if (silenceTimerRef.current) {
|
|
190
|
+
clearTimeout(silenceTimerRef.current);
|
|
191
|
+
silenceTimerRef.current = null;
|
|
192
|
+
}
|
|
102
193
|
await Voice.cancel();
|
|
103
194
|
setResults([]);
|
|
104
195
|
setPartialResults([]);
|
|
196
|
+
accumulatedTextRef.current = '';
|
|
105
197
|
}
|
|
106
198
|
catch (e) {
|
|
107
199
|
const errorMessage = e instanceof Error ? e.message : 'Failed to cancel recording';
|
|
@@ -114,6 +206,12 @@ export const useVoiceRecognition = (options = {}) => {
|
|
|
114
206
|
setPartialResults([]);
|
|
115
207
|
setError(null);
|
|
116
208
|
setIsRecording(false);
|
|
209
|
+
accumulatedTextRef.current = '';
|
|
210
|
+
setShouldContinue(false);
|
|
211
|
+
if (silenceTimerRef.current) {
|
|
212
|
+
clearTimeout(silenceTimerRef.current);
|
|
213
|
+
silenceTimerRef.current = null;
|
|
214
|
+
}
|
|
117
215
|
}, []);
|
|
118
216
|
return {
|
|
119
217
|
isRecording,
|
|
@@ -126,4 +224,3 @@ export const useVoiceRecognition = (options = {}) => {
|
|
|
126
224
|
reset,
|
|
127
225
|
};
|
|
128
226
|
};
|
|
129
|
-
//# sourceMappingURL=useVoiceRecognition.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -67,10 +67,9 @@ declare class RCTVoice {
|
|
|
67
67
|
}
|
|
68
68
|
export type { SpeechEndEvent, SpeechErrorEvent, SpeechEvents, SpeechStartEvent, SpeechRecognizedEvent, SpeechResultsEvent, SpeechVolumeChangeEvent, TranscriptionEndEvent, TranscriptionErrorEvent, TranscriptionEvents, TranscriptionStartEvent, TranscriptionResultsEvent, };
|
|
69
69
|
export type { VoiceOptions, RecognitionStats, PermissionResult, Language, } from './VoiceUtilTypes';
|
|
70
|
-
export { VoiceMicrophone, MicIcon, MicOffIcon } from './components';
|
|
70
|
+
export { VoiceMicrophone, MicIcon, MicOffIcon, MicIconFilled, MicOffIconFilled, MicIconWave, MicOffIconWave, } from './components';
|
|
71
71
|
export type { VoiceMicrophoneProps, MicIconProps, MicOffIconProps, } from './components';
|
|
72
72
|
export { useVoiceRecognition } from './hooks';
|
|
73
73
|
export type { UseVoiceRecognitionOptions, UseVoiceRecognitionReturn, } from './hooks';
|
|
74
74
|
declare const _default: RCTVoice;
|
|
75
75
|
export default _default;
|
|
76
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -392,8 +392,7 @@ class RCTVoice {
|
|
|
392
392
|
}
|
|
393
393
|
}
|
|
394
394
|
// Export components
|
|
395
|
-
export { VoiceMicrophone, MicIcon, MicOffIcon } from './components';
|
|
395
|
+
export { VoiceMicrophone, MicIcon, MicOffIcon, MicIconFilled, MicOffIconFilled, MicIconWave, MicOffIconWave, } from './components';
|
|
396
396
|
// Export hooks
|
|
397
397
|
export { useVoiceRecognition } from './hooks';
|
|
398
398
|
export default new RCTVoice();
|
|
399
|
-
//# sourceMappingURL=index.js.map
|
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.
|
|
4
|
+
"version": "1.0.3",
|
|
5
5
|
"author": "Noor Mohammad <noor.jsdivs@gmail.com>",
|
|
6
6
|
"private": false,
|
|
7
7
|
"homepage": "https://github.com/noorjsdivs/react-native-voice-ts",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"react": "^19.2.1",
|
|
23
23
|
"react-native": "^0.83.0",
|
|
24
24
|
"react-native-svg": "^15.15.1",
|
|
25
|
-
"semantic-release": "^
|
|
25
|
+
"semantic-release": "^23.0.0",
|
|
26
26
|
"typescript": "5.9.3"
|
|
27
27
|
},
|
|
28
28
|
"keywords": [
|
|
@@ -46,17 +46,13 @@
|
|
|
46
46
|
"types": "dist/index.d.ts",
|
|
47
47
|
"files": [
|
|
48
48
|
"dist",
|
|
49
|
-
"src",
|
|
50
49
|
"android",
|
|
51
50
|
"ios",
|
|
52
|
-
"plugin",
|
|
51
|
+
"plugin/build",
|
|
53
52
|
"app.plugin.js",
|
|
54
53
|
"react-native-voice.podspec",
|
|
55
54
|
"README.md",
|
|
56
|
-
"LICENSE"
|
|
57
|
-
"COMPONENT_USAGE.md",
|
|
58
|
-
"CONTRIBUTING.md",
|
|
59
|
-
"MIGRATION_SUMMARY.md"
|
|
55
|
+
"LICENSE"
|
|
60
56
|
],
|
|
61
57
|
"peerDependencies": {
|
|
62
58
|
"expo": ">=48.0.0",
|