@onairos/react-native 3.0.57 → 3.0.59
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 +2 -0
- package/lib/commonjs/components/DataRequestModal.js +87 -35
- package/lib/commonjs/components/DataRequestModal.js.map +1 -1
- package/lib/commonjs/components/OnairosButton.js +2 -0
- package/lib/commonjs/components/OnairosButton.js.map +1 -1
- package/lib/commonjs/components/Overlay.js.map +1 -1
- package/lib/commonjs/components/UniversalOnboarding.js +69 -50
- package/lib/commonjs/components/UniversalOnboarding.js.map +1 -1
- package/lib/commonjs/hooks/useConnections.js +28 -22
- package/lib/commonjs/hooks/useConnections.js.map +1 -1
- package/lib/module/components/DataRequestModal.js +88 -36
- package/lib/module/components/DataRequestModal.js.map +1 -1
- package/lib/module/components/OnairosButton.js +2 -0
- package/lib/module/components/OnairosButton.js.map +1 -1
- package/lib/module/components/Overlay.js.map +1 -1
- package/lib/module/components/UniversalOnboarding.js +69 -50
- package/lib/module/components/UniversalOnboarding.js.map +1 -1
- package/lib/module/hooks/useConnections.js +28 -22
- package/lib/module/hooks/useConnections.js.map +1 -1
- package/lib/typescript/components/DataRequestModal.d.ts +1 -1
- package/lib/typescript/components/DataRequestModal.d.ts.map +1 -1
- package/lib/typescript/components/OnairosButton.d.ts +1 -1
- package/lib/typescript/components/OnairosButton.d.ts.map +1 -1
- package/lib/typescript/components/Overlay.d.ts +1 -20
- package/lib/typescript/components/Overlay.d.ts.map +1 -1
- package/lib/typescript/components/UniversalOnboarding.d.ts.map +1 -1
- package/lib/typescript/hooks/useConnections.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +32 -11
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/DataRequestModal.tsx +226 -186
- package/src/components/OnairosButton.tsx +3 -1
- package/src/components/Overlay.tsx +1 -15
- package/src/components/UniversalOnboarding.tsx +73 -49
- package/src/hooks/useConnections.ts +26 -17
- package/src/types.ts +35 -11
|
@@ -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,
|
|
@@ -217,8 +218,16 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
217
218
|
};
|
|
218
219
|
|
|
219
220
|
const loadInitialStatus = useCallback(async () => {
|
|
220
|
-
|
|
221
|
-
|
|
221
|
+
try {
|
|
222
|
+
console.log('🔄 Loading initial connection status...');
|
|
223
|
+
const status = await getConnectionStatus();
|
|
224
|
+
console.log('✅ Connection status loaded:', status);
|
|
225
|
+
setConnections(status || {});
|
|
226
|
+
} catch (error) {
|
|
227
|
+
console.error('❌ Failed to load connection status:', error);
|
|
228
|
+
// Set empty connections to prevent crashes
|
|
229
|
+
setConnections({});
|
|
230
|
+
}
|
|
222
231
|
}, [getConnectionStatus]);
|
|
223
232
|
|
|
224
233
|
const togglePlatform = useCallback(async (platformId: string) => {
|
|
@@ -454,32 +463,38 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
454
463
|
|
|
455
464
|
// Function to handle email submission
|
|
456
465
|
const handleEmailSubmit = useCallback(async () => {
|
|
457
|
-
if (!email.trim()) {
|
|
458
|
-
Alert.alert('Error', 'Please enter your email address');
|
|
459
|
-
return;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
// Basic email validation
|
|
463
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
464
|
-
if (!emailRegex.test(email.trim())) {
|
|
465
|
-
Alert.alert('Error', 'Please enter a valid email address');
|
|
466
|
-
return;
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
console.log('📧 Email submitted:', email.trim());
|
|
470
|
-
|
|
471
|
-
// Request verification code
|
|
472
466
|
try {
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
467
|
+
if (!email || !email.trim()) {
|
|
468
|
+
Alert.alert('Error', 'Please enter your email address');
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// Basic email validation
|
|
473
|
+
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
474
|
+
if (!emailRegex.test(email.trim())) {
|
|
475
|
+
Alert.alert('Error', 'Please enter a valid email address');
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
console.log('📧 Email submitted:', email.trim());
|
|
480
|
+
|
|
481
|
+
// Request verification code
|
|
482
|
+
try {
|
|
483
|
+
const result = await requestEmailVerification(email.trim());
|
|
484
|
+
if (result && result.success) {
|
|
485
|
+
console.log('✅ Verification code requested');
|
|
486
|
+
setStep('verify');
|
|
487
|
+
} else {
|
|
488
|
+
console.warn('⚠️ Email verification request failed:', result);
|
|
489
|
+
Alert.alert('Error', result?.error || 'Failed to send verification code');
|
|
490
|
+
}
|
|
491
|
+
} catch (verificationError) {
|
|
492
|
+
console.error('❌ Error requesting verification:', verificationError);
|
|
493
|
+
Alert.alert('Error', 'Failed to send verification code. Please check your internet connection.');
|
|
479
494
|
}
|
|
480
495
|
} catch (error) {
|
|
481
|
-
console.error('❌
|
|
482
|
-
Alert.alert('Error', '
|
|
496
|
+
console.error('❌ Unexpected error in email submission:', error);
|
|
497
|
+
Alert.alert('Error', 'An unexpected error occurred. Please try again.');
|
|
483
498
|
}
|
|
484
499
|
}, [email]);
|
|
485
500
|
|
|
@@ -508,7 +523,18 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
508
523
|
setShowDataRequestModal(true);
|
|
509
524
|
} else {
|
|
510
525
|
console.log('New user, proceeding to platform connection');
|
|
511
|
-
|
|
526
|
+
// Safely set username from email prefix
|
|
527
|
+
try {
|
|
528
|
+
const emailPrefix = email.trim().split('@')[0];
|
|
529
|
+
if (emailPrefix && emailPrefix.length > 0) {
|
|
530
|
+
setUsername(emailPrefix);
|
|
531
|
+
} else {
|
|
532
|
+
setUsername('User'); // Fallback username
|
|
533
|
+
}
|
|
534
|
+
} catch (usernameError) {
|
|
535
|
+
console.warn('Failed to extract username from email, using fallback:', usernameError);
|
|
536
|
+
setUsername('User');
|
|
537
|
+
}
|
|
512
538
|
setStep('connect');
|
|
513
539
|
}
|
|
514
540
|
} else {
|
|
@@ -520,7 +546,7 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
520
546
|
} finally {
|
|
521
547
|
setIsVerifyingCode(false);
|
|
522
548
|
}
|
|
523
|
-
}, [email, verificationCode
|
|
549
|
+
}, [email, verificationCode]);
|
|
524
550
|
|
|
525
551
|
const handlePinSubmit = useCallback(async (userPin: string) => {
|
|
526
552
|
setPin(userPin);
|
|
@@ -781,15 +807,9 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
781
807
|
|
|
782
808
|
{step === 'connect' && (
|
|
783
809
|
<>
|
|
784
|
-
{/* Header with
|
|
810
|
+
{/* Header with Onairos icon and arrow to app icon */}
|
|
785
811
|
<View style={styles.header}>
|
|
786
812
|
<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
813
|
<View style={styles.onairosIcon}>
|
|
794
814
|
<Image
|
|
795
815
|
source={require('../assets/images/onairos_logo.png')}
|
|
@@ -797,6 +817,20 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
797
817
|
resizeMode="contain"
|
|
798
818
|
/>
|
|
799
819
|
</View>
|
|
820
|
+
<Icon name="arrow-forward" size={24} color="#666" style={styles.arrow} />
|
|
821
|
+
<View style={styles.appIcon}>
|
|
822
|
+
{appIcon ? (
|
|
823
|
+
<Image
|
|
824
|
+
source={appIcon}
|
|
825
|
+
style={styles.appIconImage}
|
|
826
|
+
resizeMode="contain"
|
|
827
|
+
/>
|
|
828
|
+
) : (
|
|
829
|
+
<Text style={styles.appIconText}>
|
|
830
|
+
{AppName.charAt(0)}
|
|
831
|
+
</Text>
|
|
832
|
+
)}
|
|
833
|
+
</View>
|
|
800
834
|
</View>
|
|
801
835
|
|
|
802
836
|
|
|
@@ -959,21 +993,7 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
959
993
|
visible={showDataRequestModal}
|
|
960
994
|
onClose={handleDataRequestDecline}
|
|
961
995
|
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
|
-
}}
|
|
996
|
+
requestData={requestData}
|
|
977
997
|
AppName={AppName}
|
|
978
998
|
/>
|
|
979
999
|
)}
|
|
@@ -1034,6 +1054,10 @@ const styles = StyleSheet.create({
|
|
|
1034
1054
|
fontSize: 24,
|
|
1035
1055
|
color: '#000',
|
|
1036
1056
|
},
|
|
1057
|
+
appIconImage: {
|
|
1058
|
+
width: 32,
|
|
1059
|
+
height: 32,
|
|
1060
|
+
},
|
|
1037
1061
|
arrow: {
|
|
1038
1062
|
marginHorizontal: 16,
|
|
1039
1063
|
},
|
|
@@ -30,28 +30,37 @@ export const useConnections = () => {
|
|
|
30
30
|
const getConnectionStatus = useCallback(async (): Promise<ConnectionStatus> => {
|
|
31
31
|
try {
|
|
32
32
|
if (isKeychainAvailable()) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
try {
|
|
34
|
+
const stored = await Keychain.getGenericPassword({
|
|
35
|
+
service: STORAGE_KEYS.connections
|
|
36
|
+
});
|
|
37
|
+
if (stored && stored.password) {
|
|
38
|
+
const parsed = JSON.parse(stored.password);
|
|
39
|
+
// Validate the parsed data structure
|
|
40
|
+
if (parsed && typeof parsed === 'object') {
|
|
41
|
+
return parsed;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
} catch (keychainError) {
|
|
45
|
+
console.warn('Keychain access failed, using fallback:', keychainError);
|
|
46
|
+
// Clear corrupted data
|
|
47
|
+
try {
|
|
48
|
+
await Keychain.resetGenericPassword({ service: STORAGE_KEYS.connections });
|
|
49
|
+
} catch (resetError) {
|
|
50
|
+
console.warn('Failed to reset keychain:', resetError);
|
|
51
|
+
}
|
|
38
52
|
}
|
|
39
|
-
} else {
|
|
40
|
-
// Use in-memory mock storage if Keychain is not available
|
|
41
|
-
return mockConnectionStorage[STORAGE_KEYS.connections] || {};
|
|
42
53
|
}
|
|
43
|
-
|
|
54
|
+
|
|
55
|
+
// Use in-memory mock storage if Keychain is not available or failed
|
|
56
|
+
const mockData = mockConnectionStorage[STORAGE_KEYS.connections] || {};
|
|
57
|
+
console.log('Using mock connection storage:', mockData);
|
|
58
|
+
return mockData;
|
|
44
59
|
} catch (error) {
|
|
45
60
|
console.error('Error getting connection status:', error);
|
|
46
61
|
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
return {
|
|
50
|
-
instagram: { userName: 'instagram_debug_user', connected: true },
|
|
51
|
-
youtube: { userName: 'youtube_debug_user', connected: true }
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
|
|
62
|
+
// Always return empty object as safe fallback
|
|
63
|
+
console.log('Returning empty connections due to error');
|
|
55
64
|
return {};
|
|
56
65
|
}
|
|
57
66
|
}, []);
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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 {
|