@onairos/react-native 3.0.57 → 3.0.58

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.
Files changed (29) hide show
  1. package/lib/commonjs/components/DataRequestModal.js +87 -35
  2. package/lib/commonjs/components/DataRequestModal.js.map +1 -1
  3. package/lib/commonjs/components/OnairosButton.js +2 -0
  4. package/lib/commonjs/components/OnairosButton.js.map +1 -1
  5. package/lib/commonjs/components/Overlay.js.map +1 -1
  6. package/lib/commonjs/components/UniversalOnboarding.js +19 -25
  7. package/lib/commonjs/components/UniversalOnboarding.js.map +1 -1
  8. package/lib/module/components/DataRequestModal.js +88 -36
  9. package/lib/module/components/DataRequestModal.js.map +1 -1
  10. package/lib/module/components/OnairosButton.js +2 -0
  11. package/lib/module/components/OnairosButton.js.map +1 -1
  12. package/lib/module/components/Overlay.js.map +1 -1
  13. package/lib/module/components/UniversalOnboarding.js +19 -25
  14. package/lib/module/components/UniversalOnboarding.js.map +1 -1
  15. package/lib/typescript/components/DataRequestModal.d.ts +1 -1
  16. package/lib/typescript/components/DataRequestModal.d.ts.map +1 -1
  17. package/lib/typescript/components/OnairosButton.d.ts +1 -1
  18. package/lib/typescript/components/OnairosButton.d.ts.map +1 -1
  19. package/lib/typescript/components/Overlay.d.ts +1 -20
  20. package/lib/typescript/components/Overlay.d.ts.map +1 -1
  21. package/lib/typescript/components/UniversalOnboarding.d.ts.map +1 -1
  22. package/lib/typescript/types.d.ts +32 -11
  23. package/lib/typescript/types.d.ts.map +1 -1
  24. package/package.json +1 -1
  25. package/src/components/DataRequestModal.tsx +226 -186
  26. package/src/components/OnairosButton.tsx +3 -1
  27. package/src/components/Overlay.tsx +1 -15
  28. package/src/components/UniversalOnboarding.tsx +21 -22
  29. package/src/types.ts +35 -11
@@ -1,187 +1,227 @@
1
- import React from 'react';
2
- import {
3
- View,
4
- Text,
5
- StyleSheet,
6
- TouchableOpacity,
7
- ScrollView,
8
- Modal,
9
- } from 'react-native';
10
- import Icon from 'react-native-vector-icons/MaterialIcons';
11
- import { COLORS, PLATFORMS } from '../constants';
12
-
13
- interface DataRequestModalProps {
14
- visible: boolean;
15
- onClose: () => void;
16
- onAccept: () => void;
17
- requestData: Record<string, Record<string, string>>;
18
- AppName: string;
19
- }
20
-
21
- export const DataRequestModal: React.FC<DataRequestModalProps> = ({
22
- visible,
23
- onClose,
24
- onAccept,
25
- requestData,
26
- AppName,
27
- }) => {
28
- const renderPermissions = () => {
29
- return Object.entries(requestData).map(([platform, permissions]) => {
30
- const platformConfig = PLATFORMS[platform];
31
- if (!platformConfig) return null;
32
-
33
- return (
34
- <View key={platform} style={styles.platformContainer}>
35
- <View style={styles.platformHeader}>
36
- <Icon name={platformConfig.icon} size={24} color={platformConfig.color} />
37
- <Text style={styles.platformName}>{platformConfig.name}</Text>
38
- </View>
39
- <View style={styles.permissionsContainer}>
40
- {Object.entries(permissions).map(([key, value]) => (
41
- <Text key={key} style={styles.permissionText}>
42
- • {key}: {value}
43
- </Text>
44
- ))}
45
- </View>
46
- </View>
47
- );
48
- });
49
- };
50
-
51
- return (
52
- <Modal
53
- visible={visible}
54
- transparent
55
- animationType="slide"
56
- onRequestClose={onClose}
57
- >
58
- <View style={styles.modalOverlay}>
59
- <View style={styles.modalContent}>
60
- <View style={styles.header}>
61
- <Icon name="auto_awesome" size={24} color={COLORS.primary} />
62
- <Text style={styles.headerTitle}>
63
- {AppName} Data Request
64
- </Text>
65
- <TouchableOpacity onPress={onClose} style={styles.closeButton}>
66
- <Icon name="close" size={24} color="#000" />
67
- </TouchableOpacity>
68
- </View>
69
-
70
- <ScrollView style={styles.scrollContent}>
71
- <Text style={styles.description}>
72
- {AppName} is requesting access to the following data:
73
- </Text>
74
- {renderPermissions()}
75
- </ScrollView>
76
-
77
- <View style={styles.footer}>
78
- <TouchableOpacity
79
- style={[styles.button, styles.cancelButton]}
80
- onPress={onClose}
81
- >
82
- <Text style={styles.cancelButtonText}>Cancel</Text>
83
- </TouchableOpacity>
84
- <TouchableOpacity
85
- style={[styles.button, styles.acceptButton]}
86
- onPress={onAccept}
87
- >
88
- <Text style={styles.acceptButtonText}>Accept</Text>
89
- </TouchableOpacity>
90
- </View>
91
- </View>
92
- </View>
93
- </Modal>
94
- );
95
- };
96
-
97
- const styles = StyleSheet.create({
98
- modalOverlay: {
99
- flex: 1,
100
- backgroundColor: 'rgba(0, 0, 0, 0.5)',
101
- justifyContent: 'center',
102
- alignItems: 'center',
103
- },
104
- modalContent: {
105
- backgroundColor: '#fff',
106
- borderRadius: 16,
107
- width: '90%',
108
- maxHeight: '80%',
109
- overflow: 'hidden',
110
- },
111
- header: {
112
- flexDirection: 'row',
113
- alignItems: 'center',
114
- padding: 16,
115
- backgroundColor: COLORS.headerBg,
116
- },
117
- headerTitle: {
118
- flex: 1,
119
- fontSize: 18,
120
- fontWeight: '600',
121
- marginLeft: 12,
122
- color: '#000',
123
- },
124
- closeButton: {
125
- padding: 8,
126
- },
127
- scrollContent: {
128
- padding: 16,
129
- },
130
- description: {
131
- fontSize: 16,
132
- color: COLORS.text.secondary,
133
- marginBottom: 16,
134
- },
135
- platformContainer: {
136
- marginBottom: 16,
137
- borderWidth: 1,
138
- borderColor: COLORS.border,
139
- borderRadius: 8,
140
- padding: 12,
141
- },
142
- platformHeader: {
143
- flexDirection: 'row',
144
- alignItems: 'center',
145
- marginBottom: 8,
146
- },
147
- platformName: {
148
- fontSize: 16,
149
- fontWeight: '600',
150
- marginLeft: 8,
151
- },
152
- permissionsContainer: {
153
- marginLeft: 32,
154
- },
155
- permissionText: {
156
- fontSize: 14,
157
- color: COLORS.text.secondary,
158
- marginBottom: 4,
159
- },
160
- footer: {
161
- flexDirection: 'row',
162
- padding: 16,
163
- borderTopWidth: 1,
164
- borderTopColor: COLORS.border,
165
- justifyContent: 'flex-end',
166
- },
167
- button: {
168
- paddingHorizontal: 20,
169
- paddingVertical: 10,
170
- borderRadius: 8,
171
- marginLeft: 12,
172
- },
173
- cancelButton: {
174
- backgroundColor: COLORS.border,
175
- },
176
- acceptButton: {
177
- backgroundColor: COLORS.primary,
178
- },
179
- cancelButtonText: {
180
- color: COLORS.text.secondary,
181
- fontWeight: '600',
182
- },
183
- acceptButtonText: {
184
- color: '#fff',
185
- fontWeight: '600',
186
- },
1
+ import React from 'react';
2
+ import {
3
+ View,
4
+ Text,
5
+ StyleSheet,
6
+ TouchableOpacity,
7
+ ScrollView,
8
+ Modal,
9
+ } from 'react-native';
10
+ import Icon from 'react-native-vector-icons/MaterialIcons';
11
+ import { COLORS, PLATFORMS } from '../constants';
12
+
13
+ interface DataRequestModalProps {
14
+ visible: boolean;
15
+ onClose: () => void;
16
+ onAccept: () => void;
17
+ requestData: Record<string, any>;
18
+ AppName: string;
19
+ }
20
+
21
+ export const DataRequestModal: React.FC<DataRequestModalProps> = ({
22
+ visible,
23
+ onClose,
24
+ onAccept,
25
+ requestData,
26
+ AppName,
27
+ }) => {
28
+ const renderDataRequests = () => {
29
+ return Object.entries(requestData).map(([key, data]) => {
30
+ // Skip if data is undefined or doesn't have the expected structure
31
+ if (!data || typeof data !== 'object') return null;
32
+
33
+ // Handle new format (personality_traits, sentiment_analysis)
34
+ if ('name' in data && 'description' in data && 'reward' in data) {
35
+ return (
36
+ <View key={key} style={styles.dataRequestContainer}>
37
+ <View style={styles.dataRequestHeader}>
38
+ <Icon
39
+ name={key === 'personality_traits' ? 'psychology' : 'analytics'}
40
+ size={24}
41
+ color={COLORS.primary}
42
+ />
43
+ <Text style={styles.dataRequestName}>{data.name}</Text>
44
+ </View>
45
+ <Text style={styles.dataRequestDescription}>{data.description}</Text>
46
+ <View style={styles.rewardContainer}>
47
+ <Icon name="star" size={16} color="#FFD700" />
48
+ <Text style={styles.rewardText}>{data.reward}</Text>
49
+ </View>
50
+ </View>
51
+ );
52
+ }
53
+
54
+ // Handle old format (Small, Medium, Large) for backward compatibility
55
+ if ('type' in data && 'descriptions' in data && 'reward' in data) {
56
+ return (
57
+ <View key={key} style={styles.dataRequestContainer}>
58
+ <View style={styles.dataRequestHeader}>
59
+ <Icon name="data_usage" size={24} color={COLORS.primary} />
60
+ <Text style={styles.dataRequestName}>{key} - {data.type}</Text>
61
+ </View>
62
+ <Text style={styles.dataRequestDescription}>{data.descriptions}</Text>
63
+ <View style={styles.rewardContainer}>
64
+ <Icon name="star" size={16} color="#FFD700" />
65
+ <Text style={styles.rewardText}>{data.reward}</Text>
66
+ </View>
67
+ </View>
68
+ );
69
+ }
70
+
71
+ return null;
72
+ });
73
+ };
74
+
75
+ return (
76
+ <Modal
77
+ visible={visible}
78
+ transparent
79
+ animationType="slide"
80
+ onRequestClose={onClose}
81
+ >
82
+ <View style={styles.modalOverlay}>
83
+ <View style={styles.modalContent}>
84
+ <View style={styles.header}>
85
+ <Icon name="auto_awesome" size={24} color={COLORS.primary} />
86
+ <Text style={styles.headerTitle}>
87
+ {AppName} Data Request
88
+ </Text>
89
+ <TouchableOpacity onPress={onClose} style={styles.closeButton}>
90
+ <Icon name="close" size={24} color="#000" />
91
+ </TouchableOpacity>
92
+ </View>
93
+
94
+ <ScrollView style={styles.scrollContent}>
95
+ <Text style={styles.description}>
96
+ {AppName} is requesting access to the following data insights:
97
+ </Text>
98
+ {renderDataRequests()}
99
+ </ScrollView>
100
+
101
+ <View style={styles.footer}>
102
+ <TouchableOpacity
103
+ style={[styles.button, styles.cancelButton]}
104
+ onPress={onClose}
105
+ >
106
+ <Text style={styles.cancelButtonText}>Cancel</Text>
107
+ </TouchableOpacity>
108
+ <TouchableOpacity
109
+ style={[styles.button, styles.acceptButton]}
110
+ onPress={onAccept}
111
+ >
112
+ <Text style={styles.acceptButtonText}>Accept</Text>
113
+ </TouchableOpacity>
114
+ </View>
115
+ </View>
116
+ </View>
117
+ </Modal>
118
+ );
119
+ };
120
+
121
+ const styles = StyleSheet.create({
122
+ modalOverlay: {
123
+ flex: 1,
124
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
125
+ justifyContent: 'center',
126
+ alignItems: 'center',
127
+ },
128
+ modalContent: {
129
+ backgroundColor: '#fff',
130
+ borderRadius: 16,
131
+ width: '90%',
132
+ maxHeight: '80%',
133
+ overflow: 'hidden',
134
+ },
135
+ header: {
136
+ flexDirection: 'row',
137
+ alignItems: 'center',
138
+ padding: 16,
139
+ backgroundColor: COLORS.headerBg,
140
+ },
141
+ headerTitle: {
142
+ flex: 1,
143
+ fontSize: 18,
144
+ fontWeight: '600',
145
+ marginLeft: 12,
146
+ color: '#000',
147
+ },
148
+ closeButton: {
149
+ padding: 8,
150
+ },
151
+ scrollContent: {
152
+ padding: 16,
153
+ },
154
+ description: {
155
+ fontSize: 16,
156
+ color: COLORS.text.secondary,
157
+ marginBottom: 16,
158
+ },
159
+ dataRequestContainer: {
160
+ marginBottom: 16,
161
+ borderWidth: 1,
162
+ borderColor: COLORS.border,
163
+ borderRadius: 12,
164
+ padding: 16,
165
+ backgroundColor: '#f8f9fa',
166
+ },
167
+ dataRequestHeader: {
168
+ flexDirection: 'row',
169
+ alignItems: 'center',
170
+ marginBottom: 12,
171
+ },
172
+ dataRequestName: {
173
+ fontSize: 18,
174
+ fontWeight: '600',
175
+ marginLeft: 12,
176
+ color: '#000',
177
+ },
178
+ dataRequestDescription: {
179
+ fontSize: 14,
180
+ color: COLORS.text.secondary,
181
+ marginBottom: 12,
182
+ lineHeight: 20,
183
+ },
184
+ rewardContainer: {
185
+ flexDirection: 'row',
186
+ alignItems: 'center',
187
+ backgroundColor: '#fff',
188
+ padding: 8,
189
+ borderRadius: 8,
190
+ borderLeftWidth: 3,
191
+ borderLeftColor: '#FFD700',
192
+ },
193
+ rewardText: {
194
+ fontSize: 14,
195
+ fontWeight: '500',
196
+ marginLeft: 6,
197
+ color: '#000',
198
+ flex: 1,
199
+ },
200
+ footer: {
201
+ flexDirection: 'row',
202
+ padding: 16,
203
+ borderTopWidth: 1,
204
+ borderTopColor: COLORS.border,
205
+ justifyContent: 'flex-end',
206
+ },
207
+ button: {
208
+ paddingHorizontal: 20,
209
+ paddingVertical: 10,
210
+ borderRadius: 8,
211
+ marginLeft: 12,
212
+ },
213
+ cancelButton: {
214
+ backgroundColor: COLORS.border,
215
+ },
216
+ acceptButton: {
217
+ backgroundColor: COLORS.primary,
218
+ },
219
+ cancelButtonText: {
220
+ color: COLORS.text.secondary,
221
+ fontWeight: '600',
222
+ },
223
+ acceptButtonText: {
224
+ color: '#fff',
225
+ fontWeight: '600',
226
+ },
187
227
  });
@@ -12,7 +12,7 @@ import {
12
12
  import { UniversalOnboarding } from './UniversalOnboarding';
13
13
  import { Overlay } from './Overlay';
14
14
  import { COLORS } from '../constants';
15
- import type { OnairosButtonProps } from '../types/index';
15
+ import type { OnairosButtonProps } from '../types';
16
16
  import { hasCredentials, getCredentials, deleteCredentials as clearCredentials } from '../utils/secureStorage';
17
17
  import { onairosApi } from '../api';
18
18
 
@@ -26,6 +26,7 @@ export interface OnairosButtonRef {
26
26
  */
27
27
  export const OnairosButton = forwardRef<OnairosButtonRef, OnairosButtonProps>(({
28
28
  AppName,
29
+ appIcon,
29
30
  requestData,
30
31
  returnLink,
31
32
  prefillUrl,
@@ -282,6 +283,7 @@ export const OnairosButton = forwardRef<OnairosButtonRef, OnairosButtonProps>(({
282
283
  onRejection?.('User closed onboarding');
283
284
  }}
284
285
  AppName={AppName}
286
+ appIcon={appIcon}
285
287
  requestData={requestData as any}
286
288
  returnLink={returnLink || ''}
287
289
  onComplete={handleOnboardingComplete}
@@ -22,21 +22,7 @@ import { COLORS } from '../constants';
22
22
 
23
23
  const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get('window');
24
24
 
25
- interface OverlayProps {
26
- data: {
27
- [key: string]: {
28
- type: string;
29
- descriptions: string;
30
- reward: string;
31
- };
32
- };
33
- username: string;
34
- modelKey: string;
35
- onResolved: (apiUrl: string, accessToken: string, loginDetails: any) => void;
36
- appName?: string;
37
- darkMode?: boolean;
38
- platforms?: Array<{id: string, name: string, icon: any}>;
39
- }
25
+ import type { OverlayProps } from '../types';
40
26
 
41
27
  export const Overlay: React.FC<OverlayProps> = ({
42
28
  data,
@@ -50,6 +50,7 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
50
50
  visible,
51
51
  onClose,
52
52
  AppName,
53
+ appIcon,
53
54
  requestData,
54
55
  returnLink,
55
56
  onComplete,
@@ -781,15 +782,9 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
781
782
 
782
783
  {step === 'connect' && (
783
784
  <>
784
- {/* Header with app icon and arrow to Onairos icon */}
785
+ {/* Header with Onairos icon and arrow to app icon */}
785
786
  <View style={styles.header}>
786
787
  <View style={styles.headerContent}>
787
- <View style={styles.appIcon}>
788
- <Text style={styles.appIconText}>
789
- {AppName.charAt(0)}
790
- </Text>
791
- </View>
792
- <Icon name="arrow-forward" size={24} color="#666" style={styles.arrow} />
793
788
  <View style={styles.onairosIcon}>
794
789
  <Image
795
790
  source={require('../assets/images/onairos_logo.png')}
@@ -797,6 +792,20 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
797
792
  resizeMode="contain"
798
793
  />
799
794
  </View>
795
+ <Icon name="arrow-forward" size={24} color="#666" style={styles.arrow} />
796
+ <View style={styles.appIcon}>
797
+ {appIcon ? (
798
+ <Image
799
+ source={appIcon}
800
+ style={styles.appIconImage}
801
+ resizeMode="contain"
802
+ />
803
+ ) : (
804
+ <Text style={styles.appIconText}>
805
+ {AppName.charAt(0)}
806
+ </Text>
807
+ )}
808
+ </View>
800
809
  </View>
801
810
 
802
811
 
@@ -959,21 +968,7 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
959
968
  visible={showDataRequestModal}
960
969
  onClose={handleDataRequestDecline}
961
970
  onAccept={handleDataRequestAccept}
962
- requestData={{
963
- // Convert DataTier format to expected format
964
- Small: {
965
- description: requestData.Small?.descriptions || 'Basic data access',
966
- type: requestData.Small?.type || 'basic'
967
- },
968
- Medium: {
969
- description: requestData.Medium?.descriptions || 'Standard data access',
970
- type: requestData.Medium?.type || 'standard'
971
- },
972
- Large: {
973
- description: requestData.Large?.descriptions || 'Full data access',
974
- type: requestData.Large?.type || 'full'
975
- }
976
- }}
971
+ requestData={requestData}
977
972
  AppName={AppName}
978
973
  />
979
974
  )}
@@ -1034,6 +1029,10 @@ const styles = StyleSheet.create({
1034
1029
  fontSize: 24,
1035
1030
  color: '#000',
1036
1031
  },
1032
+ appIconImage: {
1033
+ width: 32,
1034
+ height: 32,
1035
+ },
1037
1036
  arrow: {
1038
1037
  marginHorizontal: 16,
1039
1038
  },
package/src/types.ts CHANGED
@@ -4,14 +4,26 @@ export interface DataTier {
4
4
  reward: string;
5
5
  }
6
6
 
7
+ export interface DataRequest {
8
+ name: string;
9
+ description: string;
10
+ reward: string;
11
+ }
12
+
7
13
  export interface UniversalOnboardingProps {
8
14
  visible: boolean;
9
15
  onClose: () => void;
10
16
  AppName: string;
17
+ appIcon?: any; // Optional app icon (React Native ImageSourcePropType)
11
18
  requestData: {
12
- Small: DataTier;
13
- Medium: DataTier;
14
- Large: DataTier;
19
+ // Support both old format (for backward compatibility)
20
+ Small?: DataTier;
21
+ Medium?: DataTier;
22
+ Large?: DataTier;
23
+ // And new format
24
+ personality_traits?: DataRequest;
25
+ sentiment_analysis?: DataRequest;
26
+ [key: string]: DataTier | DataRequest | undefined;
15
27
  };
16
28
  returnLink: string;
17
29
  onComplete: (apiUrl: string, token: string, data: any) => void;
@@ -38,11 +50,17 @@ export interface OnairosButtonProps {
38
50
  returnLink?: string;
39
51
  prefillUrl?: string;
40
52
  AppName: string;
53
+ appIcon?: any; // Optional app icon (React Native ImageSourcePropType)
41
54
  buttonType?: 'normal' | 'pill';
42
55
  requestData?: {
43
- Small: DataTier;
44
- Medium: DataTier;
45
- Large: DataTier;
56
+ // Support both old format (for backward compatibility)
57
+ Small?: DataTier;
58
+ Medium?: DataTier;
59
+ Large?: DataTier;
60
+ // And new format
61
+ personality_traits?: DataRequest;
62
+ sentiment_analysis?: DataRequest;
63
+ [key: string]: DataTier | DataRequest | undefined;
46
64
  };
47
65
  buttonWidth?: number;
48
66
  buttonHeight?: number;
@@ -135,15 +153,21 @@ export interface CredentialsResult {
135
153
 
136
154
  export interface OverlayProps {
137
155
  data: {
138
- [key: string]: {
139
- type: string;
140
- descriptions: string;
141
- reward: string;
142
- };
156
+ // Support both old format (for backward compatibility)
157
+ Small?: DataTier;
158
+ Medium?: DataTier;
159
+ Large?: DataTier;
160
+ // And new format
161
+ personality_traits?: DataRequest;
162
+ sentiment_analysis?: DataRequest;
163
+ [key: string]: DataTier | DataRequest | undefined;
143
164
  };
144
165
  username: string;
145
166
  modelKey: string;
146
167
  onResolved: (apiUrl: string, accessToken: string, loginDetails: any) => void;
168
+ appName?: string;
169
+ darkMode?: boolean;
170
+ platforms?: Array<{id: string, name: string, icon: any}>;
147
171
  }
148
172
 
149
173
  export interface BiometricOptions {