react-native-srschat 0.1.42 → 0.1.44

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.
@@ -1,13 +1,11 @@
1
1
  // Welcome.js
2
2
  import React, { useContext } from 'react';
3
- import { View, Text, Image, TouchableOpacity, ScrollView, StyleSheet } from 'react-native';
3
+ import { View, Text, TouchableOpacity, ScrollView, StyleSheet } from 'react-native';
4
4
  import Ionicons from 'react-native-vector-icons/Ionicons';
5
5
  import { AppContext } from '../contexts/AppContext';
6
6
  import { WelcomeInput } from '../components/welcomeInput';
7
7
  import ButtonComponent from '../components/welcomeButton';
8
- import { Testing } from '../components/testing';
9
8
  import CloudinaryImage from '../utils/cloudinary';
10
- // import { PoseidonLogo } from '../components/PoseidonLogo';
11
9
 
12
10
  export const Welcome = ({ panHandlers }) => {
13
11
  const { setShowModal, uiConfig, onProductCardClick, onAddToCartClick } = useContext(AppContext);
@@ -19,30 +17,25 @@ export const Welcome = ({ panHandlers }) => {
19
17
  setShowModal("Icon");
20
18
  }
21
19
 
22
- // Reset toggleChat in the parent component
23
20
  if (typeof uiConfig.setToggleChat === 'function') {
24
21
  uiConfig.setToggleChat(false);
25
22
  }
26
23
  };
27
24
 
28
25
  return (
29
- <View contentContainerStyle={styles.container}>
26
+ <View style={styles.container}>
30
27
  <View style={styles.parentContainer}>
31
-
32
28
  {/* Top section */}
33
29
  <View style={styles.topContainer}>
34
30
  <View style={styles.topHeader}>
35
- {/* <PoseidonLogo width={150} height={35} color="white" /> */}
36
- {/* <SvgCssUri
37
- uri="https://media.heritageplus.com/image/upload/v1743632330/MobileApp/posiden.svg"
38
- width={150}
39
- height={35}
40
- /> */}
41
- <CloudinaryImage
42
- cldImg="posiden"
43
- imageStyle={{ width: 150, height: 35 }}
44
- />
45
- <TouchableOpacity onPress={() => handleClick()} style={styles.collapseButton}>
31
+ {/* Logo container with absolute positioning */}
32
+ <View style={styles.logoContainer}>
33
+ <CloudinaryImage
34
+ cldImg="posiden"
35
+ imageStyle={{ width: 150, height: 35 }}
36
+ />
37
+ </View>
38
+ <TouchableOpacity onPress={handleClick} style={styles.collapseButton}>
46
39
  <Ionicons name="close" size={26} color="white" />
47
40
  </TouchableOpacity>
48
41
  </View>
@@ -50,8 +43,7 @@ export const Welcome = ({ panHandlers }) => {
50
43
  <View style={styles.blueContainer}>
51
44
  <Text style={styles.welcomeHeader}>Hi 👋</Text>
52
45
  <Text style={styles.welcomeBody2}>
53
- I'm Poseidon, your Heritage Pool+ AI Agent. I can help you during your online
54
- visit with Product and Account information.
46
+ I'm Poseidon, your Heritage Pool+ AI Agent. I can help you during your online visit with Product and Account information.
55
47
  </Text>
56
48
  <WelcomeInput />
57
49
  <Text style={styles.textBeta}>Beta version. Poseidon is learning!</Text>
@@ -75,7 +67,7 @@ const styles = StyleSheet.create({
75
67
  parentContainer: {
76
68
  flexGrow: 1,
77
69
  backgroundColor: '#004687',
78
- paddingTop: 60
70
+ paddingTop: 60,
79
71
  },
80
72
  topContainer: {
81
73
  backgroundColor: '#004687',
@@ -83,14 +75,19 @@ const styles = StyleSheet.create({
83
75
  },
84
76
  topHeader: {
85
77
  flexDirection: 'row',
86
- justifyContent: 'flex-end',
87
78
  alignItems: 'center',
88
79
  paddingHorizontal: 15,
89
80
  paddingTop: 10,
81
+ justifyContent: 'flex-end',
82
+ position: 'relative',
90
83
  },
91
- logo: {
92
- width: 120,
93
- height: 50,
84
+ logoContainer: {
85
+ position: 'absolute',
86
+ left: 15,
87
+ top: 10,
88
+ // left: '50%',
89
+ // transform: [{ translateX: -65 }],
90
+ // top: 10,
94
91
  },
95
92
  collapseButton: {
96
93
  paddingHorizontal: 15,
@@ -121,12 +118,12 @@ const styles = StyleSheet.create({
121
118
  fontSize: 11,
122
119
  color: '#f6f6f6',
123
120
  fontWeight: '400',
124
- marginTop: 5
121
+ marginTop: 5,
125
122
  },
126
123
  bottomContainer: {
127
124
  paddingHorizontal: 25,
128
125
  backgroundColor: "#f6f6f6",
129
- paddingTop: 30
126
+ paddingTop: 30,
130
127
  },
131
128
  welcomeBody: {
132
129
  fontSize: 13,
@@ -137,3 +134,4 @@ const styles = StyleSheet.create({
137
134
  },
138
135
  });
139
136
 
137
+ export default Welcome;
@@ -1,7 +1,7 @@
1
1
  // audioRecorder.js
2
2
 
3
- import { Platform, PermissionsAndroid } from 'react-native';
4
- import Voice from '@react-native-community/voice';
3
+ import { Platform } from 'react-native';
4
+ import Voice from '@react-native-voice/voice';
5
5
  import { check, PERMISSIONS, request, RESULTS } from 'react-native-permissions';
6
6
  import useAsyncStorage from '../hooks/useAsyncStorage';
7
7
 
@@ -30,6 +30,12 @@ export async function initVoice(onResult) {
30
30
  resultCallback = onResult;
31
31
  finalResult = '';
32
32
 
33
+ // Check if Voice module is available
34
+ if (!Voice) {
35
+ console.error('Voice module is not available');
36
+ return false;
37
+ }
38
+
33
39
  // First check if speech recognition is available
34
40
  const isAvailable = await Voice.isAvailable();
35
41
  if (!isAvailable) {
@@ -72,7 +78,7 @@ export async function initVoice(onResult) {
72
78
  };
73
79
 
74
80
  Voice.onSpeechError = async (e) => {
75
- console.error('onSpeechError: ', e);
81
+ // console.error('onSpeechError: ', e);
76
82
 
77
83
  if (silenceTimer) {
78
84
  clearTimeout(silenceTimer);
@@ -86,13 +92,13 @@ export async function initVoice(onResult) {
86
92
  await cleanupVoiceSession();
87
93
 
88
94
  // 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
- }
95
+ // if (!isNoSpeechError) {
96
+ // resultCallback(null, e.error?.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
+ // }
96
102
  };
97
103
 
98
104
  Voice.onSpeechResults = (e) => {
@@ -164,6 +170,12 @@ const cleanupVoiceSession = async () => {
164
170
  }
165
171
 
166
172
  try {
173
+ // Check if Voice module is available
174
+ if (!Voice) {
175
+ console.log('Voice module not available during cleanup');
176
+ return;
177
+ }
178
+
167
179
  // First try to stop if still recognizing
168
180
  const isRecognizing = await Voice.isRecognizing();
169
181
  if (isRecognizing) {
@@ -189,7 +201,9 @@ const cleanupVoiceSession = async () => {
189
201
  console.error('Error in cleanupVoiceSession:', error);
190
202
  // Final attempt to destroy on error
191
203
  try {
192
- await Voice.destroy();
204
+ if (Voice) {
205
+ await Voice.destroy();
206
+ }
193
207
  } catch (e) {
194
208
  console.error('Final destroy attempt failed:', e);
195
209
  }
@@ -200,6 +214,12 @@ const cleanupVoiceSession = async () => {
200
214
 
201
215
  export async function startRecording() {
202
216
  try {
217
+ // Check if Voice module is available
218
+ if (!Voice) {
219
+ console.error('Voice module is not available');
220
+ return false;
221
+ }
222
+
203
223
  // Ensure cleanup of any existing session
204
224
  await cleanupVoiceSession();
205
225
 
@@ -221,7 +241,7 @@ export async function startRecording() {
221
241
 
222
242
  export async function stopRecording() {
223
243
  try {
224
- if (!isCurrentlyRecording) return;
244
+ if (!isCurrentlyRecording || !Voice) return;
225
245
 
226
246
  // Set this first to prevent race conditions
227
247
  isCurrentlyRecording = false;
@@ -259,13 +279,13 @@ export async function stopRecording() {
259
279
 
260
280
  export async function cancelRecording() {
261
281
  try {
282
+ if (!Voice) return;
262
283
  await Voice.cancel();
263
284
  await cleanupVoiceSession();
264
285
  } catch (error) {
265
286
  console.error('Error canceling voice recognition:', error);
266
287
  await cleanupVoiceSession();
267
288
  }
268
-
269
289
  }
270
290
 
271
291
  export async function requestAudioPermission() {
@@ -299,24 +319,22 @@ export async function requestAudioPermission() {
299
319
 
300
320
  async function requestAndroidPermission() {
301
321
  try {
302
- // Check available speech recognition services on Android
322
+
323
+
324
+ // Request microphone permission
325
+ const micPermission = await request(PERMISSIONS.ANDROID.RECORD_AUDIO);
326
+ if (micPermission !== RESULTS.GRANTED) {
327
+ console.log('Microphone permission denied');
328
+ return false;
329
+ }
330
+
331
+ // Skip checking speech recognition services which is causing errors
303
332
  const services = await Voice.getSpeechRecognitionServices();
304
333
  if (!services || services.length === 0) {
305
334
  console.error('No speech recognition services available');
306
335
  return false;
307
336
  }
308
-
309
- const granted = await PermissionsAndroid.request(
310
- PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
311
- {
312
- title: 'Microphone Permission',
313
- message: 'This app needs access to your microphone for voice recognition.',
314
- buttonPositive: 'OK',
315
- buttonNegative: 'Cancel',
316
- }
317
- );
318
-
319
- return granted === PermissionsAndroid.RESULTS.GRANTED;
337
+ return true;
320
338
  } catch (error) {
321
339
  console.error('Error requesting Android permission:', error);
322
340
  return false;
@@ -355,13 +373,20 @@ export function resetStoredPermission() {
355
373
  }
356
374
 
357
375
  export function cleanup() {
376
+ if (!Voice) {
377
+ console.log('Voice module not available during cleanup');
378
+ return;
379
+ }
380
+
358
381
  Voice.destroy().then(() => {
359
382
  Voice.removeAllListeners();
360
383
  cleanupVoiceSession();
361
384
  }).catch(error => {
362
385
  console.error('Error in cleanup:', error);
363
386
  // Try one more time
364
- Voice.destroy().catch(e => console.error('Final cleanup attempt failed:', e));
387
+ if (Voice) {
388
+ Voice.destroy().catch(e => console.error('Final cleanup attempt failed:', e));
389
+ }
365
390
  });
366
391
  }
367
392