react-native-srschat 0.1.27 → 0.1.28

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 CHANGED
@@ -6,3 +6,147 @@
6
6
  Installing the package:
7
7
  `npm i react-native-srschat`
8
8
 
9
+ ###Setup
10
+
11
+ iOS
12
+ By default, no permissions are available. First, require the setup script in your Podfile:
13
+
14
+
15
+ ```
16
+ + def node_require(script)
17
+ + # Resolve script with node to allow for hoisting
18
+ + require Pod::Executable.execute_command('node', ['-p',
19
+ + "require.resolve(
20
+ + '#{script}',
21
+ + {paths: [process.argv[1]]},
22
+ + )", __dir__]).strip
23
+ + end
24
+
25
+ # Use it to require both react-native's and this package's scripts:
26
+ + node_require('react-native/scripts/react_native_pods.rb')
27
+ + node_require('react-native-permissions/scripts/setup.rb')
28
+ ```
29
+ In the same Podfile, call setup_permissions with the permissions you need. Only the permissions specified here will be added:
30
+ ```
31
+ # …
32
+
33
+ platform :ios, min_ios_version_supported
34
+ prepare_react_native_project!
35
+
36
+ setup_permissions([
37
+ 'Microphone',
38
+ 'SpeechRecognition',
39
+ ])
40
+ ```
41
+ Then execute pod install in your ios directory (📌 Note that it must be re-executed each time you update this config).
42
+
43
+ Finally, add the corresponding permissions usage descriptions to your Info.plist. For example:
44
+ ```
45
+ <?xml version="1.0" encoding="UTF-8"?>
46
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
47
+ <plist version="1.0">
48
+ <dict>
49
+
50
+ <!-- 🚨 Keep only the permissions specified in `setup_permissions` 🚨 -->
51
+
52
+ <key>NSAppleMusicUsageDescription</key>
53
+ <string>[REASON]</string>
54
+ <key>NSBluetoothAlwaysUsageDescription</key>
55
+ <string>[REASON]</string>
56
+ <key>NSBluetoothPeripheralUsageDescription</key>
57
+ <string>[REASON]</string>
58
+ <key>NSCalendarsFullAccessUsageDescription</key>
59
+ <string>[REASON]</string>
60
+ <key>NSCalendarsWriteOnlyAccessUsageDescription</key>
61
+ <string>[REASON]</string>
62
+ <key>NSCameraUsageDescription</key>
63
+ <string>[REASON]</string>
64
+ <key>NSContactsUsageDescription</key>
65
+ <string>[REASON]</string>
66
+ <key>NSFaceIDUsageDescription</key>
67
+ <string>[REASON]</string>
68
+ <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
69
+ <string>[REASON]</string>
70
+ <key>NSLocationTemporaryUsageDescriptionDictionary</key>
71
+ <dict>
72
+ <key>YOUR-PURPOSE-KEY</key>
73
+ <string>[REASON]</string>
74
+ </dict>
75
+ <key>NSLocationWhenInUseUsageDescription</key>
76
+ <string>[REASON]</string>
77
+ <key>NSMicrophoneUsageDescription</key>
78
+ <string>[REASON]</string>
79
+ <key>NSMotionUsageDescription</key>
80
+ <string>[REASON]</string>
81
+ <key>NSPhotoLibraryUsageDescription</key>
82
+ <string>[REASON]</string>
83
+ <key>NSPhotoLibraryAddUsageDescription</key>
84
+ <string>[REASON]</string>
85
+ <key>NSRemindersFullAccessUsageDescription</key>
86
+ <string>[REASON]</string>
87
+ <key>NSSpeechRecognitionUsageDescription</key>
88
+ <string>[REASON]</string>
89
+ <key>NSSiriUsageDescription</key>
90
+ <string>[REASON]</string>
91
+ <key>NSUserTrackingUsageDescription</key>
92
+ <string>[REASON]</string>
93
+
94
+ <!-- … -->
95
+
96
+ </dict>
97
+ </plist>
98
+ ```
99
+ Android
100
+ Add all wanted permissions to your app android/app/src/main/AndroidManifest.xml file:
101
+ ```
102
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
103
+
104
+ <!-- 🚨 Keep only the permissions used in your app 🚨 -->
105
+
106
+ <uses-permission android:name="android.permission.ACCEPT_HANDOVER" />
107
+ <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
108
+ <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
109
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
110
+ <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
111
+ <uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
112
+ <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" />
113
+ <uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
114
+ <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
115
+ <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
116
+ <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
117
+ <uses-permission android:name="android.permission.BODY_SENSORS" />
118
+ <uses-permission android:name="android.permission.BODY_SENSORS_BACKGROUND" />
119
+ <uses-permission android:name="android.permission.CALL_PHONE" />
120
+ <uses-permission android:name="android.permission.CAMERA" />
121
+ <uses-permission android:name="android.permission.GET_ACCOUNTS" />
122
+ <uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" />
123
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
124
+ <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
125
+ <uses-permission android:name="android.permission.READ_CALENDAR" />
126
+ <uses-permission android:name="android.permission.READ_CALL_LOG" />
127
+ <uses-permission android:name="android.permission.READ_CONTACTS" />
128
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
129
+ <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
130
+ <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
131
+ <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
132
+ <uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
133
+ <uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
134
+ <uses-permission android:name="android.permission.READ_PHONE_STATE" />
135
+ <uses-permission android:name="android.permission.READ_SMS" />
136
+ <uses-permission android:name="android.permission.RECEIVE_MMS" />
137
+ <uses-permission android:name="android.permission.RECEIVE_SMS" />
138
+ <uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" />
139
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
140
+ <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
141
+ <uses-permission android:name="android.permission.SEND_SMS" />
142
+ <uses-permission android:name="android.permission.USE_SIP" />
143
+ <uses-permission android:name="android.permission.UWB_RANGING" />
144
+ <uses-permission android:name="android.permission.WRITE_CALENDAR" />
145
+ <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
146
+ <uses-permission android:name="android.permission.WRITE_CONTACTS" />
147
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
148
+
149
+ <!-- … -->
150
+
151
+ </manifest>
152
+ ```
@@ -7,6 +7,7 @@ exports.VoiceButton = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
9
  var _Ionicons = _interopRequireDefault(require("react-native-vector-icons/Ionicons"));
10
+ var _useAsyncStorage = _interopRequireDefault(require("../hooks/useAsyncStorage"));
10
11
  var _audioRecorder = require("../utils/audioRecorder");
11
12
  var _AppContext = require("../contexts/AppContext");
12
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
@@ -14,49 +15,105 @@ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return
14
15
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
15
16
  // VoiceButton.js
16
17
 
18
+ const PERMISSION_STORAGE_KEY = '@voice_permission_status';
17
19
  const VoiceButton = () => {
18
20
  const {
19
21
  handleVoiceSend
20
22
  } = (0, _react.useContext)(_AppContext.AppContext);
21
23
  const [isListening, setIsListening] = (0, _react.useState)(false);
22
24
  const [loading, setLoading] = (0, _react.useState)(false);
25
+ const [permissionChecked, setPermissionChecked] = (0, _react.useState)(false);
26
+ const [hasPermission, setHasPermission] = (0, _react.useState)(null);
27
+
28
+ // Use your custom AsyncStorage hook
29
+ const [permissionStatus, setPermissionStatus] = (0, _useAsyncStorage.default)(PERMISSION_STORAGE_KEY, null);
23
30
  (0, _react.useEffect)(() => {
31
+ // Register our permission handlers
32
+ (0, _audioRecorder.setPermissionStatusHandlers)(() => permissionStatus, setPermissionStatus);
24
33
  const setupVoice = async () => {
25
- const initialized = await (0, _audioRecorder.initVoice)((result, error) => {
26
- if (error) {
27
- _reactNative.Alert.alert('Error', error);
28
- setIsListening(false);
29
- setLoading(false);
34
+ try {
35
+ // Check stored permission first
36
+ if (permissionStatus === 'denied') {
37
+ // We already know permission was denied, don't show alert again
38
+ setHasPermission(false);
39
+ setPermissionChecked(true);
30
40
  return;
31
41
  }
32
- if (result) {
33
- handleVoiceSend(null, result);
34
- setIsListening(false);
35
- setLoading(false);
42
+
43
+ // Only request permission if not already denied
44
+ const permissionResult = await (0, _audioRecorder.requestAudioPermission)();
45
+ setHasPermission(permissionResult);
46
+ if (permissionResult) {
47
+ const initialized = await (0, _audioRecorder.initVoice)((result, error) => {
48
+ if (error) {
49
+ // Don't show alert for permission errors since we handle that elsewhere
50
+ if (!error.includes('permission')) {
51
+ _reactNative.Alert.alert('Error', error);
52
+ }
53
+ setIsListening(false);
54
+ setLoading(false);
55
+ return;
56
+ }
57
+ if (result) {
58
+ handleVoiceSend(null, result);
59
+ }
60
+ // Always reset states when the recognition ends
61
+ setIsListening(false);
62
+ setLoading(false);
63
+ });
64
+ if (!initialized) {
65
+ // Only show this alert once per session
66
+ if (!permissionChecked) {
67
+ _reactNative.Alert.alert('Error', 'Speech recognition is not available on this device');
68
+ }
69
+ }
36
70
  }
37
- });
38
- if (!initialized) {
39
- _reactNative.Alert.alert('Error', 'Speech recognition is not available on this device');
71
+ } catch (error) {
72
+ console.error('Error in setupVoice:', error);
73
+ } finally {
74
+ setPermissionChecked(true);
40
75
  }
41
76
  };
42
- setupVoice();
77
+ if (!permissionChecked) {
78
+ setupVoice();
79
+ }
43
80
  return () => {
44
81
  (0, _audioRecorder.cleanup)();
45
82
  };
46
- }, []);
83
+ }, [permissionStatus, permissionChecked]);
47
84
  const toggleRecording = async () => {
48
85
  try {
49
86
  if (!isListening) {
50
- const hasPermission = await (0, _audioRecorder.requestAudioPermission)();
51
- if (!hasPermission) {
52
- _reactNative.Alert.alert('Permission Denied', 'Microphone permission is required for voice recognition');
87
+ // If we already know we don't have permission, show a better message
88
+ if (hasPermission === false) {
89
+ _reactNative.Alert.alert('Permission Required', 'Voice recognition requires microphone permission. Would you like to update your settings?', [{
90
+ text: 'Cancel',
91
+ style: 'cancel'
92
+ }, {
93
+ text: 'Settings',
94
+ onPress: () => {
95
+ // Reset stored permission so we can check again
96
+ setPermissionStatus(null);
97
+ // Open device settings
98
+ openAppSettings();
99
+ // Reset our permission check
100
+ setPermissionChecked(false);
101
+ }
102
+ }]);
53
103
  return;
54
104
  }
55
105
  setLoading(true);
106
+ const checkPermission = await (0, _audioRecorder.requestAudioPermission)();
107
+ if (!checkPermission) {
108
+ setHasPermission(false);
109
+ setLoading(false);
110
+ return;
111
+ }
56
112
  const started = await (0, _audioRecorder.startRecording)();
57
113
  if (started) {
58
114
  setIsListening(true);
59
115
  } else {
116
+ // Only show error if not permission related
60
117
  _reactNative.Alert.alert('Error', 'Failed to start voice recognition');
61
118
  }
62
119
  } else {
@@ -73,6 +130,20 @@ const VoiceButton = () => {
73
130
  setLoading(false);
74
131
  }
75
132
  };
133
+ const openAppSettings = async () => {
134
+ try {
135
+ if (_reactNative.Platform.OS === 'ios') {
136
+ // For iOS
137
+ await _reactNative.Linking.openURL('app-settings://');
138
+ } else {
139
+ // For Android
140
+ await _reactNative.Linking.openSettings();
141
+ }
142
+ } catch (error) {
143
+ console.error('Cannot open settings', error);
144
+ _reactNative.Alert.alert('Error', 'Unable to open settings. Please open settings manually.');
145
+ }
146
+ };
76
147
  return /*#__PURE__*/_react.default.createElement(_reactNative.TouchableOpacity, {
77
148
  style: styles.button,
78
149
  onPress: toggleRecording,
@@ -1 +1 @@
1
- {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_Ionicons","_interopRequireDefault","_audioRecorder","_AppContext","e","__esModule","default","_getRequireWildcardCache","WeakMap","r","t","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set","VoiceButton","handleVoiceSend","useContext","AppContext","isListening","setIsListening","useState","loading","setLoading","useEffect","setupVoice","initialized","initVoice","result","error","Alert","alert","cleanup","toggleRecording","hasPermission","requestAudioPermission","started","startRecording","stopRecording","console","createElement","TouchableOpacity","style","styles","button","onPress","disabled","ActivityIndicator","size","color","name","exports","StyleSheet","create","justifyContent","alignItems"],"sourceRoot":"../../../src","sources":["components/voice.js"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_Ionicons","_interopRequireDefault","_useAsyncStorage","_audioRecorder","_AppContext","e","__esModule","default","_getRequireWildcardCache","WeakMap","r","t","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set","PERMISSION_STORAGE_KEY","VoiceButton","handleVoiceSend","useContext","AppContext","isListening","setIsListening","useState","loading","setLoading","permissionChecked","setPermissionChecked","hasPermission","setHasPermission","permissionStatus","setPermissionStatus","useAsyncStorage","useEffect","setPermissionStatusHandlers","setupVoice","permissionResult","requestAudioPermission","initialized","initVoice","result","error","includes","Alert","alert","console","cleanup","toggleRecording","text","style","onPress","openAppSettings","checkPermission","started","startRecording","stopRecording","Platform","OS","Linking","openURL","openSettings","createElement","TouchableOpacity","styles","button","disabled","ActivityIndicator","size","color","name","exports","StyleSheet","create","justifyContent","alignItems"],"sourceRoot":"../../../src","sources":["components/voice.js"],"mappings":"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","ignoreList":[]}
@@ -7,11 +7,14 @@ exports.cancelRecording = cancelRecording;
7
7
  exports.cleanup = cleanup;
8
8
  exports.initVoice = initVoice;
9
9
  exports.requestAudioPermission = requestAudioPermission;
10
+ exports.resetStoredPermission = resetStoredPermission;
11
+ exports.setPermissionStatusHandlers = setPermissionStatusHandlers;
10
12
  exports.startRecording = startRecording;
11
13
  exports.stopRecording = stopRecording;
12
14
  var _reactNative = require("react-native");
13
15
  var _voice = _interopRequireDefault(require("@react-native-community/voice"));
14
16
  var _reactNativePermissions = require("react-native-permissions");
17
+ var _useAsyncStorage = _interopRequireDefault(require("../hooks/useAsyncStorage"));
15
18
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
19
  // audioRecorder.js
17
20
 
@@ -21,6 +24,18 @@ let isCurrentlyRecording = false;
21
24
  let finalResult = '';
22
25
  const SILENCE_DURATION = 1500; // 1.5 seconds of silence before stopping
23
26
 
27
+ // Add this constant for AsyncStorage key
28
+ const PERMISSION_STORAGE_KEY = '@voice_permission_status';
29
+
30
+ // Create a function that can be called to get permission status
31
+ // This needs to be outside the React component lifecycle
32
+ let permissionStatusGetter = null;
33
+ let permissionStatusSetter = null;
34
+ function setPermissionStatusHandlers(getter, setter) {
35
+ permissionStatusGetter = getter;
36
+ permissionStatusSetter = setter;
37
+ }
38
+
24
39
  // Initialize Voice handlers
25
40
  async function initVoice(onResult) {
26
41
  try {
@@ -64,14 +79,26 @@ async function initVoice(onResult) {
64
79
  }
65
80
  };
66
81
  _voice.default.onSpeechError = async e => {
67
- var _e$error;
82
+ var _e$error, _e$error2;
68
83
  console.error('onSpeechError: ', e);
69
84
  if (silenceTimer) {
70
85
  clearTimeout(silenceTimer);
71
86
  silenceTimer = null;
72
87
  }
88
+
89
+ // Check for "No speech detected" error
90
+ const isNoSpeechError = ((_e$error = e.error) === null || _e$error === void 0 ? void 0 : _e$error.code) === "recognition_fail" && ((_e$error2 = e.error) === null || _e$error2 === void 0 || (_e$error2 = _e$error2.message) === null || _e$error2 === void 0 ? void 0 : _e$error2.includes("No speech detected"));
73
91
  await cleanupVoiceSession();
74
- resultCallback(null, ((_e$error = e.error) === null || _e$error === void 0 ? void 0 : _e$error.message) || 'Speech recognition error');
92
+
93
+ // Only send error to callback if it's not a "No speech detected" error
94
+ if (!isNoSpeechError) {
95
+ var _e$error3;
96
+ resultCallback(null, ((_e$error3 = e.error) === null || _e$error3 === void 0 ? void 0 : _e$error3.message) || 'Speech recognition error');
97
+ } else {
98
+ console.log('No speech detected, ignoring error');
99
+ // Optionally, call the callback with null parameters or a special indicator
100
+ resultCallback(null, null); // This won't trigger an error alert in the component
101
+ }
75
102
  };
76
103
  _voice.default.onSpeechResults = e => {
77
104
  console.log('onSpeechResults: ', e);
@@ -226,12 +253,29 @@ async function cancelRecording() {
226
253
  }
227
254
  }
228
255
  async function requestAudioPermission() {
229
- if (_reactNative.Platform.OS === 'android') {
230
- return await requestAndroidPermission();
231
- } else if (_reactNative.Platform.OS === 'ios') {
232
- return await requestIOSPermission();
256
+ try {
257
+ // Get stored permission if available
258
+ const storedPermission = permissionStatusGetter ? permissionStatusGetter() : null;
259
+ if (storedPermission === 'denied') {
260
+ console.log('Permission previously denied by user');
261
+ return false;
262
+ }
263
+ let permissionResult = false;
264
+ if (_reactNative.Platform.OS === 'android') {
265
+ permissionResult = await requestAndroidPermission();
266
+ } else if (_reactNative.Platform.OS === 'ios') {
267
+ permissionResult = await requestIOSPermission();
268
+ }
269
+
270
+ // Store the result
271
+ if (permissionStatusSetter) {
272
+ permissionStatusSetter(permissionResult ? 'granted' : 'denied');
273
+ }
274
+ return permissionResult;
275
+ } catch (error) {
276
+ console.error('Error checking stored permission:', error);
277
+ return false;
233
278
  }
234
- return false;
235
279
  }
236
280
  async function requestAndroidPermission() {
237
281
  try {
@@ -274,6 +318,13 @@ async function requestIOSPermission() {
274
318
  return false;
275
319
  }
276
320
  }
321
+ function resetStoredPermission() {
322
+ if (permissionStatusSetter) {
323
+ permissionStatusSetter(null);
324
+ return true;
325
+ }
326
+ return false;
327
+ }
277
328
  function cleanup() {
278
329
  _voice.default.destroy().then(() => {
279
330
  _voice.default.removeAllListeners();
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","_voice","_interopRequireDefault","_reactNativePermissions","e","__esModule","default","resultCallback","silenceTimer","isCurrentlyRecording","finalResult","SILENCE_DURATION","initVoice","onResult","isAvailable","Voice","console","error","onSpeechStart","log","clearTimeout","onSpeechRecognized","isFinal","handleFinalResult","onSpeechEnd","onSpeechError","_e$error","cleanupVoiceSession","message","onSpeechResults","value","length","handleSilenceDetection","onSpeechPartialResults","Platform","OS","onSpeechVolumeChanged","setTimeout","stopRecording","isRecognizing","stop","Promise","resolve","destroy","stillRecognizing","startRecording","hasPermission","requestAudioPermission","start","cancelRecording","cancel","requestAndroidPermission","requestIOSPermission","services","getSpeechRecognitionServices","granted","PermissionsAndroid","request","PERMISSIONS","RECORD_AUDIO","title","buttonPositive","buttonNegative","RESULTS","GRANTED","micPermission","IOS","MICROPHONE","speechPermission","SPEECH_RECOGNITION","cleanup","then","removeAllListeners","catch"],"sourceRoot":"../../../src","sources":["utils/audioRecorder.js"],"mappings":";;;;;;;;;;;AAEA,IAAAA,YAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAC,sBAAA,CAAAF,OAAA;AACA,IAAAG,uBAAA,GAAAH,OAAA;AAAgF,SAAAE,uBAAAE,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AAJhF;;AAMA,IAAIG,cAAc,GAAG,IAAI;AACzB,IAAIC,YAAY,GAAG,IAAI;AACvB,IAAIC,oBAAoB,GAAG,KAAK;AAChC,IAAIC,WAAW,GAAG,EAAE;AACpB,MAAMC,gBAAgB,GAAG,IAAI,CAAC,CAAC;;AAE/B;AACO,eAAeC,SAASA,CAACC,QAAQ,EAAE;EACxC,IAAI;IACFN,cAAc,GAAGM,QAAQ;IACzBH,WAAW,GAAG,EAAE;;IAEhB;IACA,MAAMI,WAAW,GAAG,MAAMC,cAAK,CAACD,WAAW,CAAC,CAAC;IAC7C,IAAI,CAACA,WAAW,EAAE;MAChBE,OAAO,CAACC,KAAK,CAAC,oDAAoD,CAAC;MACnE,OAAO,KAAK;IACd;;IAEA;IACAF,cAAK,CAACG,aAAa,GAAId,CAAC,IAAK;MAC3BY,OAAO,CAACG,GAAG,CAAC,iBAAiB,EAAEf,CAAC,CAAC;MACjCK,oBAAoB,GAAG,IAAI;MAC3BC,WAAW,GAAG,EAAE;MAEhB,IAAIF,YAAY,EAAE;QAChBY,YAAY,CAACZ,YAAY,CAAC;QAC1BA,YAAY,GAAG,IAAI;MACrB;IACF,CAAC;IAEDO,cAAK,CAACM,kBAAkB,GAAIjB,CAAC,IAAK;MAChCY,OAAO,CAACG,GAAG,CAAC,sBAAsB,EAAEf,CAAC,CAAC;MACtC,IAAIA,CAAC,CAACkB,OAAO,EAAE;QACbN,OAAO,CAACG,GAAG,CAAC,0BAA0B,CAAC;QACvCI,iBAAiB,CAAC,CAAC;MACrB;IACF,CAAC;IAEDR,cAAK,CAACS,WAAW,GAAG,MAAOpB,CAAC,IAAK;MAC/BY,OAAO,CAACG,GAAG,CAAC,eAAe,EAAEf,CAAC,CAAC;MAE/B,IAAII,YAAY,EAAE;QAChBY,YAAY,CAACZ,YAAY,CAAC;QAC1BA,YAAY,GAAG,IAAI;MACrB;;MAEA;MACA,IAAIC,oBAAoB,EAAE;QACxB,MAAMc,iBAAiB,CAAC,CAAC;MAC3B;IACF,CAAC;IAEDR,cAAK,CAACU,aAAa,GAAG,MAAOrB,CAAC,IAAK;MAAA,IAAAsB,QAAA;MACjCV,OAAO,CAACC,KAAK,CAAC,iBAAiB,EAAEb,CAAC,CAAC;MAGnC,IAAII,YAAY,EAAE;QAChBY,YAAY,CAACZ,YAAY,CAAC;QAC1BA,YAAY,GAAG,IAAI;MACrB;MAGA,MAAMmB,mBAAmB,CAAC,CAAC;MAC3BpB,cAAc,CAAC,IAAI,EAAE,EAAAmB,QAAA,GAAAtB,CAAC,CAACa,KAAK,cAAAS,QAAA,uBAAPA,QAAA,CAASE,OAAO,KAAI,0BAA0B,CAAC;IACtE,CAAC;IAEDb,cAAK,CAACc,eAAe,GAAIzB,CAAC,IAAK;MAC7BY,OAAO,CAACG,GAAG,CAAC,mBAAmB,EAAEf,CAAC,CAAC;MACnC,IAAIA,CAAC,CAAC0B,KAAK,IAAI1B,CAAC,CAAC0B,KAAK,CAACC,MAAM,GAAG,CAAC,EAAE;QACjCrB,WAAW,GAAGN,CAAC,CAAC0B,KAAK,CAAC,CAAC,CAAC;QACxBE,sBAAsB,CAAC,CAAC;MAC1B;IACF,CAAC;IAEDjB,cAAK,CAACkB,sBAAsB,GAAI7B,CAAC,IAAK;MACpCY,OAAO,CAACG,GAAG,CAAC,0BAA0B,EAAEf,CAAC,CAAC;MAE1C,IAAII,YAAY,EAAE;QAChBY,YAAY,CAACZ,YAAY,CAAC;MAC5B;MAEA,IAAIJ,CAAC,CAAC0B,KAAK,IAAI1B,CAAC,CAAC0B,KAAK,CAACC,MAAM,GAAG,CAAC,EAAE;QACjCrB,WAAW,GAAGN,CAAC,CAAC0B,KAAK,CAAC,CAAC,CAAC;QACxBE,sBAAsB,CAAC,CAAC;MAC1B;IACF,CAAC;IAED,IAAIE,qBAAQ,CAACC,EAAE,KAAK,SAAS,EAAE;MAC7BpB,cAAK,CAACqB,qBAAqB,GAAIhC,CAAC,IAAK;QACnCY,OAAO,CAACG,GAAG,CAAC,yBAAyB,EAAEf,CAAC,CAAC;MAC3C,CAAC;IACH;IAEA,OAAO,IAAI;EACb,CAAC,CAAC,OAAOa,KAAK,EAAE;IACdD,OAAO,CAACC,KAAK,CAAC,2BAA2B,EAAEA,KAAK,CAAC;IACjD,OAAO,KAAK;EACd;AACF;AAEA,MAAMe,sBAAsB,GAAGA,CAAA,KAAM;EACnC,IAAIxB,YAAY,EAAE;IAChBY,YAAY,CAACZ,YAAY,CAAC;EAC5B;EAEAA,YAAY,GAAG6B,UAAU,CAAC,YAAY;IACpC,IAAI5B,oBAAoB,EAAE;MACxB,MAAMc,iBAAiB,CAAC,CAAC;IAC3B;EACF,CAAC,EAAEZ,gBAAgB,CAAC;AACtB,CAAC;AAED,MAAMY,iBAAiB,GAAG,MAAAA,CAAA,KAAY;EACpC,IAAI,CAACd,oBAAoB,EAAE;EAE3B,IAAIC,WAAW,EAAE;IACfH,cAAc,CAACG,WAAW,CAAC;EAC7B;;EAEA;EACA,MAAM4B,aAAa,CAAC,CAAC;;EAErB;EACA,MAAMX,mBAAmB,CAAC,CAAC;AAC7B,CAAC;AAED,MAAMA,mBAAmB,GAAG,MAAAA,CAAA,KAAY;EACtClB,oBAAoB,GAAG,KAAK;EAE5B,IAAID,YAAY,EAAE;IAChBY,YAAY,CAACZ,YAAY,CAAC;IAC1BA,YAAY,GAAG,IAAI;EACrB;EAEA,IAAI;IACF;IACA,MAAM+B,aAAa,GAAG,MAAMxB,cAAK,CAACwB,aAAa,CAAC,CAAC;IACjD,IAAIA,aAAa,EAAE;MACjB,IAAI;QACF,MAAMxB,cAAK,CAACyB,IAAI,CAAC,CAAC;QAClB,MAAM,IAAIC,OAAO,CAACC,OAAO,IAAIL,UAAU,CAACK,OAAO,EAAE,GAAG,CAAC,CAAC;MACxD,CAAC,CAAC,OAAOtC,CAAC,EAAE;QACVY,OAAO,CAACC,KAAK,CAAC,4BAA4B,EAAEb,CAAC,CAAC;MAChD;IACF;;IAEA;IACA,MAAMW,cAAK,CAAC4B,OAAO,CAAC,CAAC;IACrB,MAAM,IAAIF,OAAO,CAACC,OAAO,IAAIL,UAAU,CAACK,OAAO,EAAE,GAAG,CAAC,CAAC;;IAEtD;IACA,MAAME,gBAAgB,GAAG,MAAM7B,cAAK,CAACwB,aAAa,CAAC,CAAC;IACpD,IAAIK,gBAAgB,EAAE;MACpB,MAAM7B,cAAK,CAAC4B,OAAO,CAAC,CAAC;MACrB,MAAM,IAAIF,OAAO,CAACC,OAAO,IAAIL,UAAU,CAACK,OAAO,EAAE,GAAG,CAAC,CAAC;IACxD;EACF,CAAC,CAAC,OAAOzB,KAAK,EAAE;IACdD,OAAO,CAACC,KAAK,CAAC,+BAA+B,EAAEA,KAAK,CAAC;IACrD;IACA,IAAI;MACF,MAAMF,cAAK,CAAC4B,OAAO,CAAC,CAAC;IACvB,CAAC,CAAC,OAAOvC,CAAC,EAAE;MACVY,OAAO,CAACC,KAAK,CAAC,+BAA+B,EAAEb,CAAC,CAAC;IACnD;EACF;EAEAM,WAAW,GAAG,EAAE;AAClB,CAAC;AAEM,eAAemC,cAAcA,CAAA,EAAG;EACrC,IAAI;IACF;IACA,MAAMlB,mBAAmB,CAAC,CAAC;IAE3B,MAAMmB,aAAa,GAAG,MAAMC,sBAAsB,CAAC,CAAC;IACpD,IAAI,CAACD,aAAa,EAAE;MAClB9B,OAAO,CAACC,KAAK,CAAC,+BAA+B,CAAC;MAC9C,OAAO,KAAK;IACd;IAEA,MAAMF,cAAK,CAACiC,KAAK,CAAC,OAAO,CAAC;IAC1BvC,oBAAoB,GAAG,IAAI;IAC3B,OAAO,IAAI;EACb,CAAC,CAAC,OAAOQ,KAAK,EAAE;IACdD,OAAO,CAACC,KAAK,CAAC,mCAAmC,EAAEA,KAAK,CAAC;IACzD,MAAMU,mBAAmB,CAAC,CAAC;IAC3B,OAAO,KAAK;EACd;AACF;AAEO,eAAeW,aAAaA,CAAA,EAAG;EACpC,IAAI;IACF,IAAI,CAAC7B,oBAAoB,EAAE;;IAE3B;IACAA,oBAAoB,GAAG,KAAK;IAE5B,IAAID,YAAY,EAAE;MAChBY,YAAY,CAACZ,YAAY,CAAC;MAC1BA,YAAY,GAAG,IAAI;IACrB;;IAEA;IACA,IAAI;MACF,MAAMO,cAAK,CAACyB,IAAI,CAAC,CAAC;MAClB;MACA,MAAM,IAAIC,OAAO,CAACC,OAAO,IAAIL,UAAU,CAACK,OAAO,EAAE,GAAG,CAAC,CAAC;IACxD,CAAC,CAAC,OAAOzB,KAAK,EAAE;MACdD,OAAO,CAACC,KAAK,CAAC,uBAAuB,EAAEA,KAAK,CAAC;IAC/C;;IAEA;IACA,IAAI;MACF,MAAMF,cAAK,CAAC4B,OAAO,CAAC,CAAC;MACrB,MAAM,IAAIF,OAAO,CAACC,OAAO,IAAIL,UAAU,CAACK,OAAO,EAAE,GAAG,CAAC,CAAC;IACxD,CAAC,CAAC,OAAOzB,KAAK,EAAE;MACdD,OAAO,CAACC,KAAK,CAAC,yBAAyB,EAAEA,KAAK,CAAC;IACjD;;IAEA;IACA,MAAMU,mBAAmB,CAAC,CAAC;EAC7B,CAAC,CAAC,OAAOV,KAAK,EAAE;IACdD,OAAO,CAACC,KAAK,CAAC,yBAAyB,EAAEA,KAAK,CAAC;IAC/C;IACA,MAAMU,mBAAmB,CAAC,CAAC;EAC7B;AACF;AAEO,eAAesB,eAAeA,CAAA,EAAG;EACtC,IAAI;IACF,MAAMlC,cAAK,CAACmC,MAAM,CAAC,CAAC;IACpB,MAAMvB,mBAAmB,CAAC,CAAC;EAC7B,CAAC,CAAC,OAAOV,KAAK,EAAE;IACdD,OAAO,CAACC,KAAK,CAAC,oCAAoC,EAAEA,KAAK,CAAC;IAC1D,MAAMU,mBAAmB,CAAC,CAAC;EAC7B;AAEF;AAEO,eAAeoB,sBAAsBA,CAAA,EAAG;EAC7C,IAAIb,qBAAQ,CAACC,EAAE,KAAK,SAAS,EAAE;IAC7B,OAAO,MAAMgB,wBAAwB,CAAC,CAAC;EACzC,CAAC,MAAM,IAAIjB,qBAAQ,CAACC,EAAE,KAAK,KAAK,EAAE;IAChC,OAAO,MAAMiB,oBAAoB,CAAC,CAAC;EACrC;EAEA,OAAO,KAAK;AACd;AAEA,eAAeD,wBAAwBA,CAAA,EAAG;EACxC,IAAI;IACF;IACA,MAAME,QAAQ,GAAG,MAAMtC,cAAK,CAACuC,4BAA4B,CAAC,CAAC;IAC3D,IAAI,CAACD,QAAQ,IAAIA,QAAQ,CAACtB,MAAM,KAAK,CAAC,EAAE;MACtCf,OAAO,CAACC,KAAK,CAAC,0CAA0C,CAAC;MACzD,OAAO,KAAK;IACd;IAEA,MAAMsC,OAAO,GAAG,MAAMC,+BAAkB,CAACC,OAAO,CAC9CD,+BAAkB,CAACE,WAAW,CAACC,YAAY,EAC3C;MACEC,KAAK,EAAE,uBAAuB;MAE9BhC,OAAO,EAAE,iEAAiE;MAE1EiC,cAAc,EAAE,IAAI;MACpBC,cAAc,EAAE;IAClB,CACF,CAAC;IAED,OAAOP,OAAO,KAAKC,+BAAkB,CAACO,OAAO,CAACC,OAAO;EACvD,CAAC,CAAC,OAAO/C,KAAK,EAAE;IACdD,OAAO,CAACC,KAAK,CAAC,sCAAsC,EAAEA,KAAK,CAAC;IAE5D,OAAO,KAAK;EACd;AACF;AAGA,eAAemC,oBAAoBA,CAAA,EAAG;EACpC,IAAI;IACF;IACA,MAAMa,aAAa,GAAG,MAAM,IAAAR,+BAAO,EAACC,mCAAW,CAACQ,GAAG,CAACC,UAAU,CAAC;IAC/D,IAAIF,aAAa,KAAKF,+BAAO,CAACC,OAAO,EAAE;MACrChD,OAAO,CAACG,GAAG,CAAC,8BAA8B,CAAC;MAC3C,OAAO,KAAK;IACd;;IAEA;IACA,MAAMiD,gBAAgB,GAAG,MAAM,IAAAX,+BAAO,EAACC,mCAAW,CAACQ,GAAG,CAACG,kBAAkB,CAAC;IAC1E,IAAID,gBAAgB,KAAKL,+BAAO,CAACC,OAAO,EAAE;MACxChD,OAAO,CAACG,GAAG,CAAC,sCAAsC,CAAC;MACnD,OAAO,KAAK;IACd;IAEA,OAAO,IAAI;EACb,CAAC,CAAC,OAAOF,KAAK,EAAE;IACdD,OAAO,CAACC,KAAK,CAAC,mCAAmC,EAAEA,KAAK,CAAC;IACzD,OAAO,KAAK;EACd;AACF;AAEO,SAASqD,OAAOA,CAAA,EAAG;EACxBvD,cAAK,CAAC4B,OAAO,CAAC,CAAC,CAAC4B,IAAI,CAAC,MAAM;IACzBxD,cAAK,CAACyD,kBAAkB,CAAC,CAAC;IAC1B7C,mBAAmB,CAAC,CAAC;EACvB,CAAC,CAAC,CAAC8C,KAAK,CAACxD,KAAK,IAAI;IAChBD,OAAO,CAACC,KAAK,CAAC,mBAAmB,EAAEA,KAAK,CAAC;IACzC;IACAF,cAAK,CAAC4B,OAAO,CAAC,CAAC,CAAC8B,KAAK,CAACrE,CAAC,IAAIY,OAAO,CAACC,KAAK,CAAC,+BAA+B,EAAEb,CAAC,CAAC,CAAC;EAC/E,CAAC,CAAC;AACJ","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","_voice","_interopRequireDefault","_reactNativePermissions","_useAsyncStorage","e","__esModule","default","resultCallback","silenceTimer","isCurrentlyRecording","finalResult","SILENCE_DURATION","PERMISSION_STORAGE_KEY","permissionStatusGetter","permissionStatusSetter","setPermissionStatusHandlers","getter","setter","initVoice","onResult","isAvailable","Voice","console","error","onSpeechStart","log","clearTimeout","onSpeechRecognized","isFinal","handleFinalResult","onSpeechEnd","onSpeechError","_e$error","_e$error2","isNoSpeechError","code","message","includes","cleanupVoiceSession","_e$error3","onSpeechResults","value","length","handleSilenceDetection","onSpeechPartialResults","Platform","OS","onSpeechVolumeChanged","setTimeout","stopRecording","isRecognizing","stop","Promise","resolve","destroy","stillRecognizing","startRecording","hasPermission","requestAudioPermission","start","cancelRecording","cancel","storedPermission","permissionResult","requestAndroidPermission","requestIOSPermission","services","getSpeechRecognitionServices","granted","PermissionsAndroid","request","PERMISSIONS","RECORD_AUDIO","title","buttonPositive","buttonNegative","RESULTS","GRANTED","micPermission","IOS","MICROPHONE","speechPermission","SPEECH_RECOGNITION","resetStoredPermission","cleanup","then","removeAllListeners","catch"],"sourceRoot":"../../../src","sources":["utils/audioRecorder.js"],"mappings":"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","ignoreList":[]}
@@ -1,53 +1,110 @@
1
1
  // VoiceButton.js
2
2
 
3
3
  import React, { useState, useContext, useEffect } from 'react';
4
- import { TouchableOpacity, ActivityIndicator, StyleSheet, Alert } from 'react-native';
4
+ import { TouchableOpacity, ActivityIndicator, StyleSheet, Alert, Linking, Platform } from 'react-native';
5
5
  import Ionicons from 'react-native-vector-icons/Ionicons';
6
- import { startRecording, stopRecording, cancelRecording, requestAudioPermission, cleanup, initVoice } from '../utils/audioRecorder';
6
+ import useAsyncStorage from '../hooks/useAsyncStorage';
7
+ import { startRecording, stopRecording, cancelRecording, requestAudioPermission, cleanup, initVoice, resetStoredPermission, setPermissionStatusHandlers } from '../utils/audioRecorder';
7
8
  import { AppContext } from '../contexts/AppContext';
9
+ const PERMISSION_STORAGE_KEY = '@voice_permission_status';
8
10
  export const VoiceButton = () => {
9
11
  const {
10
12
  handleVoiceSend
11
13
  } = useContext(AppContext);
12
14
  const [isListening, setIsListening] = useState(false);
13
15
  const [loading, setLoading] = useState(false);
16
+ const [permissionChecked, setPermissionChecked] = useState(false);
17
+ const [hasPermission, setHasPermission] = useState(null);
18
+
19
+ // Use your custom AsyncStorage hook
20
+ const [permissionStatus, setPermissionStatus] = useAsyncStorage(PERMISSION_STORAGE_KEY, null);
14
21
  useEffect(() => {
22
+ // Register our permission handlers
23
+ setPermissionStatusHandlers(() => permissionStatus, setPermissionStatus);
15
24
  const setupVoice = async () => {
16
- const initialized = await initVoice((result, error) => {
17
- if (error) {
18
- Alert.alert('Error', error);
19
- setIsListening(false);
20
- setLoading(false);
25
+ try {
26
+ // Check stored permission first
27
+ if (permissionStatus === 'denied') {
28
+ // We already know permission was denied, don't show alert again
29
+ setHasPermission(false);
30
+ setPermissionChecked(true);
21
31
  return;
22
32
  }
23
- if (result) {
24
- handleVoiceSend(null, result);
25
- setIsListening(false);
26
- setLoading(false);
33
+
34
+ // Only request permission if not already denied
35
+ const permissionResult = await requestAudioPermission();
36
+ setHasPermission(permissionResult);
37
+ if (permissionResult) {
38
+ const initialized = await initVoice((result, error) => {
39
+ if (error) {
40
+ // Don't show alert for permission errors since we handle that elsewhere
41
+ if (!error.includes('permission')) {
42
+ Alert.alert('Error', error);
43
+ }
44
+ setIsListening(false);
45
+ setLoading(false);
46
+ return;
47
+ }
48
+ if (result) {
49
+ handleVoiceSend(null, result);
50
+ }
51
+ // Always reset states when the recognition ends
52
+ setIsListening(false);
53
+ setLoading(false);
54
+ });
55
+ if (!initialized) {
56
+ // Only show this alert once per session
57
+ if (!permissionChecked) {
58
+ Alert.alert('Error', 'Speech recognition is not available on this device');
59
+ }
60
+ }
27
61
  }
28
- });
29
- if (!initialized) {
30
- Alert.alert('Error', 'Speech recognition is not available on this device');
62
+ } catch (error) {
63
+ console.error('Error in setupVoice:', error);
64
+ } finally {
65
+ setPermissionChecked(true);
31
66
  }
32
67
  };
33
- setupVoice();
68
+ if (!permissionChecked) {
69
+ setupVoice();
70
+ }
34
71
  return () => {
35
72
  cleanup();
36
73
  };
37
- }, []);
74
+ }, [permissionStatus, permissionChecked]);
38
75
  const toggleRecording = async () => {
39
76
  try {
40
77
  if (!isListening) {
41
- const hasPermission = await requestAudioPermission();
42
- if (!hasPermission) {
43
- Alert.alert('Permission Denied', 'Microphone permission is required for voice recognition');
78
+ // If we already know we don't have permission, show a better message
79
+ if (hasPermission === false) {
80
+ Alert.alert('Permission Required', 'Voice recognition requires microphone permission. Would you like to update your settings?', [{
81
+ text: 'Cancel',
82
+ style: 'cancel'
83
+ }, {
84
+ text: 'Settings',
85
+ onPress: () => {
86
+ // Reset stored permission so we can check again
87
+ setPermissionStatus(null);
88
+ // Open device settings
89
+ openAppSettings();
90
+ // Reset our permission check
91
+ setPermissionChecked(false);
92
+ }
93
+ }]);
44
94
  return;
45
95
  }
46
96
  setLoading(true);
97
+ const checkPermission = await requestAudioPermission();
98
+ if (!checkPermission) {
99
+ setHasPermission(false);
100
+ setLoading(false);
101
+ return;
102
+ }
47
103
  const started = await startRecording();
48
104
  if (started) {
49
105
  setIsListening(true);
50
106
  } else {
107
+ // Only show error if not permission related
51
108
  Alert.alert('Error', 'Failed to start voice recognition');
52
109
  }
53
110
  } else {
@@ -64,6 +121,20 @@ export const VoiceButton = () => {
64
121
  setLoading(false);
65
122
  }
66
123
  };
124
+ const openAppSettings = async () => {
125
+ try {
126
+ if (Platform.OS === 'ios') {
127
+ // For iOS
128
+ await Linking.openURL('app-settings://');
129
+ } else {
130
+ // For Android
131
+ await Linking.openSettings();
132
+ }
133
+ } catch (error) {
134
+ console.error('Cannot open settings', error);
135
+ Alert.alert('Error', 'Unable to open settings. Please open settings manually.');
136
+ }
137
+ };
67
138
  return /*#__PURE__*/React.createElement(TouchableOpacity, {
68
139
  style: styles.button,
69
140
  onPress: toggleRecording,
@@ -1 +1 @@
1
- {"version":3,"names":["React","useState","useContext","useEffect","TouchableOpacity","ActivityIndicator","StyleSheet","Alert","Ionicons","startRecording","stopRecording","cancelRecording","requestAudioPermission","cleanup","initVoice","AppContext","VoiceButton","handleVoiceSend","isListening","setIsListening","loading","setLoading","setupVoice","initialized","result","error","alert","toggleRecording","hasPermission","started","console","createElement","style","styles","button","onPress","disabled","size","color","name","create","justifyContent","alignItems"],"sourceRoot":"../../../src","sources":["components/voice.js"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["React","useState","useContext","useEffect","TouchableOpacity","ActivityIndicator","StyleSheet","Alert","Linking","Platform","Ionicons","useAsyncStorage","startRecording","stopRecording","cancelRecording","requestAudioPermission","cleanup","initVoice","resetStoredPermission","setPermissionStatusHandlers","AppContext","PERMISSION_STORAGE_KEY","VoiceButton","handleVoiceSend","isListening","setIsListening","loading","setLoading","permissionChecked","setPermissionChecked","hasPermission","setHasPermission","permissionStatus","setPermissionStatus","setupVoice","permissionResult","initialized","result","error","includes","alert","console","toggleRecording","text","style","onPress","openAppSettings","checkPermission","started","OS","openURL","openSettings","createElement","styles","button","disabled","size","color","name","create","justifyContent","alignItems"],"sourceRoot":"../../../src","sources":["components/voice.js"],"mappings":"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","ignoreList":[]}
@@ -3,12 +3,25 @@
3
3
  import { Platform, PermissionsAndroid } from 'react-native';
4
4
  import Voice from '@react-native-community/voice';
5
5
  import { check, PERMISSIONS, request, RESULTS } from 'react-native-permissions';
6
+ import useAsyncStorage from '../hooks/useAsyncStorage';
6
7
  let resultCallback = null;
7
8
  let silenceTimer = null;
8
9
  let isCurrentlyRecording = false;
9
10
  let finalResult = '';
10
11
  const SILENCE_DURATION = 1500; // 1.5 seconds of silence before stopping
11
12
 
13
+ // Add this constant for AsyncStorage key
14
+ const PERMISSION_STORAGE_KEY = '@voice_permission_status';
15
+
16
+ // Create a function that can be called to get permission status
17
+ // This needs to be outside the React component lifecycle
18
+ let permissionStatusGetter = null;
19
+ let permissionStatusSetter = null;
20
+ export function setPermissionStatusHandlers(getter, setter) {
21
+ permissionStatusGetter = getter;
22
+ permissionStatusSetter = setter;
23
+ }
24
+
12
25
  // Initialize Voice handlers
13
26
  export async function initVoice(onResult) {
14
27
  try {
@@ -52,14 +65,26 @@ export async function initVoice(onResult) {
52
65
  }
53
66
  };
54
67
  Voice.onSpeechError = async e => {
55
- var _e$error;
68
+ var _e$error, _e$error2;
56
69
  console.error('onSpeechError: ', e);
57
70
  if (silenceTimer) {
58
71
  clearTimeout(silenceTimer);
59
72
  silenceTimer = null;
60
73
  }
74
+
75
+ // Check for "No speech detected" error
76
+ const isNoSpeechError = ((_e$error = e.error) === null || _e$error === void 0 ? void 0 : _e$error.code) === "recognition_fail" && ((_e$error2 = e.error) === null || _e$error2 === void 0 || (_e$error2 = _e$error2.message) === null || _e$error2 === void 0 ? void 0 : _e$error2.includes("No speech detected"));
61
77
  await cleanupVoiceSession();
62
- resultCallback(null, ((_e$error = e.error) === null || _e$error === void 0 ? void 0 : _e$error.message) || 'Speech recognition error');
78
+
79
+ // Only send error to callback if it's not a "No speech detected" error
80
+ if (!isNoSpeechError) {
81
+ var _e$error3;
82
+ resultCallback(null, ((_e$error3 = e.error) === null || _e$error3 === void 0 ? void 0 : _e$error3.message) || 'Speech recognition error');
83
+ } else {
84
+ console.log('No speech detected, ignoring error');
85
+ // Optionally, call the callback with null parameters or a special indicator
86
+ resultCallback(null, null); // This won't trigger an error alert in the component
87
+ }
63
88
  };
64
89
  Voice.onSpeechResults = e => {
65
90
  console.log('onSpeechResults: ', e);
@@ -214,12 +239,29 @@ export async function cancelRecording() {
214
239
  }
215
240
  }
216
241
  export async function requestAudioPermission() {
217
- if (Platform.OS === 'android') {
218
- return await requestAndroidPermission();
219
- } else if (Platform.OS === 'ios') {
220
- return await requestIOSPermission();
242
+ try {
243
+ // Get stored permission if available
244
+ const storedPermission = permissionStatusGetter ? permissionStatusGetter() : null;
245
+ if (storedPermission === 'denied') {
246
+ console.log('Permission previously denied by user');
247
+ return false;
248
+ }
249
+ let permissionResult = false;
250
+ if (Platform.OS === 'android') {
251
+ permissionResult = await requestAndroidPermission();
252
+ } else if (Platform.OS === 'ios') {
253
+ permissionResult = await requestIOSPermission();
254
+ }
255
+
256
+ // Store the result
257
+ if (permissionStatusSetter) {
258
+ permissionStatusSetter(permissionResult ? 'granted' : 'denied');
259
+ }
260
+ return permissionResult;
261
+ } catch (error) {
262
+ console.error('Error checking stored permission:', error);
263
+ return false;
221
264
  }
222
- return false;
223
265
  }
224
266
  async function requestAndroidPermission() {
225
267
  try {
@@ -262,6 +304,13 @@ async function requestIOSPermission() {
262
304
  return false;
263
305
  }
264
306
  }
307
+ export function resetStoredPermission() {
308
+ if (permissionStatusSetter) {
309
+ permissionStatusSetter(null);
310
+ return true;
311
+ }
312
+ return false;
313
+ }
265
314
  export function cleanup() {
266
315
  Voice.destroy().then(() => {
267
316
  Voice.removeAllListeners();
@@ -1 +1 @@
1
- {"version":3,"names":["Platform","PermissionsAndroid","Voice","check","PERMISSIONS","request","RESULTS","resultCallback","silenceTimer","isCurrentlyRecording","finalResult","SILENCE_DURATION","initVoice","onResult","isAvailable","console","error","onSpeechStart","e","log","clearTimeout","onSpeechRecognized","isFinal","handleFinalResult","onSpeechEnd","onSpeechError","_e$error","cleanupVoiceSession","message","onSpeechResults","value","length","handleSilenceDetection","onSpeechPartialResults","OS","onSpeechVolumeChanged","setTimeout","stopRecording","isRecognizing","stop","Promise","resolve","destroy","stillRecognizing","startRecording","hasPermission","requestAudioPermission","start","cancelRecording","cancel","requestAndroidPermission","requestIOSPermission","services","getSpeechRecognitionServices","granted","RECORD_AUDIO","title","buttonPositive","buttonNegative","GRANTED","micPermission","IOS","MICROPHONE","speechPermission","SPEECH_RECOGNITION","cleanup","then","removeAllListeners","catch"],"sourceRoot":"../../../src","sources":["utils/audioRecorder.js"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["Platform","PermissionsAndroid","Voice","check","PERMISSIONS","request","RESULTS","useAsyncStorage","resultCallback","silenceTimer","isCurrentlyRecording","finalResult","SILENCE_DURATION","PERMISSION_STORAGE_KEY","permissionStatusGetter","permissionStatusSetter","setPermissionStatusHandlers","getter","setter","initVoice","onResult","isAvailable","console","error","onSpeechStart","e","log","clearTimeout","onSpeechRecognized","isFinal","handleFinalResult","onSpeechEnd","onSpeechError","_e$error","_e$error2","isNoSpeechError","code","message","includes","cleanupVoiceSession","_e$error3","onSpeechResults","value","length","handleSilenceDetection","onSpeechPartialResults","OS","onSpeechVolumeChanged","setTimeout","stopRecording","isRecognizing","stop","Promise","resolve","destroy","stillRecognizing","startRecording","hasPermission","requestAudioPermission","start","cancelRecording","cancel","storedPermission","permissionResult","requestAndroidPermission","requestIOSPermission","services","getSpeechRecognitionServices","granted","RECORD_AUDIO","title","buttonPositive","buttonNegative","GRANTED","micPermission","IOS","MICROPHONE","speechPermission","SPEECH_RECOGNITION","resetStoredPermission","cleanup","then","removeAllListeners","catch"],"sourceRoot":"../../../src","sources":["utils/audioRecorder.js"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"voice.d.ts","sourceRoot":"","sources":["../../../src/components/voice.js"],"names":[],"mappings":"AAgBO,iDAsFN;kBApGsD,OAAO"}
1
+ {"version":3,"file":"voice.d.ts","sourceRoot":"","sources":["../../../src/components/voice.js"],"names":[],"mappings":"AAqBO,iDAqKN;kBAxLsD,OAAO"}
@@ -1,7 +1,9 @@
1
+ export function setPermissionStatusHandlers(getter: any, setter: any): void;
1
2
  export function initVoice(onResult: any): Promise<boolean>;
2
3
  export function startRecording(): Promise<boolean>;
3
4
  export function stopRecording(): Promise<void>;
4
5
  export function cancelRecording(): Promise<void>;
5
6
  export function requestAudioPermission(): Promise<boolean>;
7
+ export function resetStoredPermission(): boolean;
6
8
  export function cleanup(): void;
7
9
  //# sourceMappingURL=audioRecorder.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"audioRecorder.d.ts","sourceRoot":"","sources":["../../../src/utils/audioRecorder.js"],"names":[],"mappings":"AAaA,2DA4FC;AAuED,mDAmBC;AAED,+CAoCC;AAED,iDASC;AAED,2DAQC;AAuDD,gCASC"}
1
+ {"version":3,"file":"audioRecorder.d.ts","sourceRoot":"","sources":["../../../src/utils/audioRecorder.js"],"names":[],"mappings":"AAqBA,4EAGC;AAGD,2DAsGC;AAuED,mDAmBC;AAED,+CAoCC;AAED,iDASC;AAED,2DA2BC;AAmDD,iDAMC;AAED,gCASC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-srschat",
3
- "version": "0.1.27",
3
+ "version": "0.1.28",
4
4
  "private": false,
5
5
  "description": "A modern, sophisticated chat interface for React Native",
6
6
  "main": "lib/commonjs/index",
@@ -1,8 +1,9 @@
1
1
  // VoiceButton.js
2
2
 
3
3
  import React, { useState, useContext, useEffect } from 'react';
4
- import { TouchableOpacity, ActivityIndicator, StyleSheet, Alert } from 'react-native';
4
+ import { TouchableOpacity, ActivityIndicator, StyleSheet, Alert, Linking, Platform } from 'react-native';
5
5
  import Ionicons from 'react-native-vector-icons/Ionicons';
6
+ import useAsyncStorage from '../hooks/useAsyncStorage';
6
7
 
7
8
  import {
8
9
  startRecording,
@@ -10,60 +11,129 @@ import {
10
11
  cancelRecording,
11
12
  requestAudioPermission,
12
13
  cleanup,
13
- initVoice
14
+ initVoice,
15
+ resetStoredPermission,
16
+ setPermissionStatusHandlers
14
17
  } from '../utils/audioRecorder';
15
18
  import { AppContext } from '../contexts/AppContext';
16
19
 
20
+ const PERMISSION_STORAGE_KEY = '@voice_permission_status';
21
+
17
22
  export const VoiceButton = () => {
18
23
  const { handleVoiceSend } = useContext(AppContext);
19
24
  const [isListening, setIsListening] = useState(false);
20
25
  const [loading, setLoading] = useState(false);
26
+ const [permissionChecked, setPermissionChecked] = useState(false);
27
+ const [hasPermission, setHasPermission] = useState(null);
28
+
29
+ // Use your custom AsyncStorage hook
30
+ const [permissionStatus, setPermissionStatus] = useAsyncStorage(PERMISSION_STORAGE_KEY, null);
21
31
 
22
32
  useEffect(() => {
33
+ // Register our permission handlers
34
+ setPermissionStatusHandlers(() => permissionStatus, setPermissionStatus);
35
+
23
36
  const setupVoice = async () => {
24
- const initialized = await initVoice((result, error) => {
25
- if (error) {
26
- Alert.alert('Error', error);
27
- setIsListening(false);
28
- setLoading(false);
37
+ try {
38
+ // Check stored permission first
39
+ if (permissionStatus === 'denied') {
40
+ // We already know permission was denied, don't show alert again
41
+ setHasPermission(false);
42
+ setPermissionChecked(true);
29
43
  return;
30
44
  }
31
- if (result) {
32
- handleVoiceSend(null, result);
33
- setIsListening(false);
34
- setLoading(false);
35
- }
36
- });
45
+
46
+ // Only request permission if not already denied
47
+ const permissionResult = await requestAudioPermission();
48
+ setHasPermission(permissionResult);
49
+
50
+ if (permissionResult) {
51
+ const initialized = await initVoice((result, error) => {
52
+ if (error) {
53
+ // Don't show alert for permission errors since we handle that elsewhere
54
+ if (!error.includes('permission')) {
55
+ Alert.alert('Error', error);
56
+ }
57
+ setIsListening(false);
58
+ setLoading(false);
59
+ return;
60
+ }
61
+ if (result) {
62
+ handleVoiceSend(null, result);
63
+ }
64
+ // Always reset states when the recognition ends
65
+ setIsListening(false);
66
+ setLoading(false);
67
+ });
37
68
 
38
- if (!initialized) {
39
- Alert.alert(
40
- 'Error',
41
- 'Speech recognition is not available on this device'
42
- );
69
+ if (!initialized) {
70
+ // Only show this alert once per session
71
+ if (!permissionChecked) {
72
+ Alert.alert(
73
+ 'Error',
74
+ 'Speech recognition is not available on this device'
75
+ );
76
+ }
77
+ }
78
+ }
79
+ } catch (error) {
80
+ console.error('Error in setupVoice:', error);
81
+ } finally {
82
+ setPermissionChecked(true);
43
83
  }
44
84
  };
45
85
 
46
- setupVoice();
86
+ if (!permissionChecked) {
87
+ setupVoice();
88
+ }
47
89
 
48
90
  return () => {
49
91
  cleanup();
50
92
  };
51
- }, []);
93
+ }, [permissionStatus, permissionChecked]);
52
94
 
53
95
  const toggleRecording = async () => {
54
96
  try {
55
97
  if (!isListening) {
56
- const hasPermission = await requestAudioPermission();
57
- if (!hasPermission) {
58
- Alert.alert('Permission Denied', 'Microphone permission is required for voice recognition');
98
+ // If we already know we don't have permission, show a better message
99
+ if (hasPermission === false) {
100
+ Alert.alert(
101
+ 'Permission Required',
102
+ 'Voice recognition requires microphone permission. Would you like to update your settings?',
103
+ [
104
+ {
105
+ text: 'Cancel',
106
+ style: 'cancel'
107
+ },
108
+ {
109
+ text: 'Settings',
110
+ onPress: () => {
111
+ // Reset stored permission so we can check again
112
+ setPermissionStatus(null);
113
+ // Open device settings
114
+ openAppSettings();
115
+ // Reset our permission check
116
+ setPermissionChecked(false);
117
+ }
118
+ }
119
+ ]
120
+ );
59
121
  return;
60
122
  }
61
123
 
62
124
  setLoading(true);
125
+ const checkPermission = await requestAudioPermission();
126
+ if (!checkPermission) {
127
+ setHasPermission(false);
128
+ setLoading(false);
129
+ return;
130
+ }
131
+
63
132
  const started = await startRecording();
64
133
  if (started) {
65
134
  setIsListening(true);
66
135
  } else {
136
+ // Only show error if not permission related
67
137
  Alert.alert('Error', 'Failed to start voice recognition');
68
138
  }
69
139
  } else {
@@ -78,7 +148,21 @@ export const VoiceButton = () => {
78
148
  await cleanup();
79
149
  } finally {
80
150
  setLoading(false);
151
+ }
152
+ };
81
153
 
154
+ const openAppSettings = async () => {
155
+ try {
156
+ if (Platform.OS === 'ios') {
157
+ // For iOS
158
+ await Linking.openURL('app-settings://');
159
+ } else {
160
+ // For Android
161
+ await Linking.openSettings();
162
+ }
163
+ } catch (error) {
164
+ console.error('Cannot open settings', error);
165
+ Alert.alert('Error', 'Unable to open settings. Please open settings manually.');
82
166
  }
83
167
  };
84
168
 
@@ -3,6 +3,7 @@
3
3
  import { Platform, PermissionsAndroid } from 'react-native';
4
4
  import Voice from '@react-native-community/voice';
5
5
  import { check, PERMISSIONS, request, RESULTS } from 'react-native-permissions';
6
+ import useAsyncStorage from '../hooks/useAsyncStorage';
6
7
 
7
8
  let resultCallback = null;
8
9
  let silenceTimer = null;
@@ -10,6 +11,19 @@ let isCurrentlyRecording = false;
10
11
  let finalResult = '';
11
12
  const SILENCE_DURATION = 1500; // 1.5 seconds of silence before stopping
12
13
 
14
+ // Add this constant for AsyncStorage key
15
+ const PERMISSION_STORAGE_KEY = '@voice_permission_status';
16
+
17
+ // Create a function that can be called to get permission status
18
+ // This needs to be outside the React component lifecycle
19
+ let permissionStatusGetter = null;
20
+ let permissionStatusSetter = null;
21
+
22
+ export function setPermissionStatusHandlers(getter, setter) {
23
+ permissionStatusGetter = getter;
24
+ permissionStatusSetter = setter;
25
+ }
26
+
13
27
  // Initialize Voice handlers
14
28
  export async function initVoice(onResult) {
15
29
  try {
@@ -60,15 +74,25 @@ export async function initVoice(onResult) {
60
74
  Voice.onSpeechError = async (e) => {
61
75
  console.error('onSpeechError: ', e);
62
76
 
63
-
64
77
  if (silenceTimer) {
65
78
  clearTimeout(silenceTimer);
66
79
  silenceTimer = null;
67
80
  }
68
81
 
82
+ // Check for "No speech detected" error
83
+ const isNoSpeechError = e.error?.code === "recognition_fail" &&
84
+ e.error?.message?.includes("No speech detected");
69
85
 
70
86
  await cleanupVoiceSession();
71
- resultCallback(null, e.error?.message || 'Speech recognition error');
87
+
88
+ // Only send error to callback if it's not a "No speech detected" error
89
+ if (!isNoSpeechError) {
90
+ resultCallback(null, e.error?.message || 'Speech recognition error');
91
+ } else {
92
+ console.log('No speech detected, ignoring error');
93
+ // Optionally, call the callback with null parameters or a special indicator
94
+ resultCallback(null, null); // This won't trigger an error alert in the component
95
+ }
72
96
  };
73
97
 
74
98
  Voice.onSpeechResults = (e) => {
@@ -245,13 +269,32 @@ export async function cancelRecording() {
245
269
  }
246
270
 
247
271
  export async function requestAudioPermission() {
248
- if (Platform.OS === 'android') {
249
- return await requestAndroidPermission();
250
- } else if (Platform.OS === 'ios') {
251
- return await requestIOSPermission();
272
+ try {
273
+ // Get stored permission if available
274
+ const storedPermission = permissionStatusGetter ? permissionStatusGetter() : null;
275
+
276
+ if (storedPermission === 'denied') {
277
+ console.log('Permission previously denied by user');
278
+ return false;
279
+ }
280
+
281
+ let permissionResult = false;
282
+ if (Platform.OS === 'android') {
283
+ permissionResult = await requestAndroidPermission();
284
+ } else if (Platform.OS === 'ios') {
285
+ permissionResult = await requestIOSPermission();
286
+ }
287
+
288
+ // Store the result
289
+ if (permissionStatusSetter) {
290
+ permissionStatusSetter(permissionResult ? 'granted' : 'denied');
291
+ }
292
+
293
+ return permissionResult;
294
+ } catch (error) {
295
+ console.error('Error checking stored permission:', error);
296
+ return false;
252
297
  }
253
-
254
- return false;
255
298
  }
256
299
 
257
300
  async function requestAndroidPermission() {
@@ -267,23 +310,19 @@ async function requestAndroidPermission() {
267
310
  PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
268
311
  {
269
312
  title: 'Microphone Permission',
270
-
271
313
  message: 'This app needs access to your microphone for voice recognition.',
272
-
273
314
  buttonPositive: 'OK',
274
315
  buttonNegative: 'Cancel',
275
316
  }
276
317
  );
277
-
318
+
278
319
  return granted === PermissionsAndroid.RESULTS.GRANTED;
279
320
  } catch (error) {
280
321
  console.error('Error requesting Android permission:', error);
281
-
282
322
  return false;
283
323
  }
284
324
  }
285
325
 
286
-
287
326
  async function requestIOSPermission() {
288
327
  try {
289
328
  // Request microphone permission
@@ -307,6 +346,14 @@ async function requestIOSPermission() {
307
346
  }
308
347
  }
309
348
 
349
+ export function resetStoredPermission() {
350
+ if (permissionStatusSetter) {
351
+ permissionStatusSetter(null);
352
+ return true;
353
+ }
354
+ return false;
355
+ }
356
+
310
357
  export function cleanup() {
311
358
  Voice.destroy().then(() => {
312
359
  Voice.removeAllListeners();