@onairos/react-native 3.0.24 → 3.0.25
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/lib/commonjs/components/OnairosButton.js +2 -3
- package/lib/commonjs/components/OnairosButton.js.map +1 -1
- package/lib/commonjs/components/TrainingModal.js +120 -16
- package/lib/commonjs/components/TrainingModal.js.map +1 -1
- package/lib/commonjs/components/UniversalOnboarding.js +131 -76
- package/lib/commonjs/components/UniversalOnboarding.js.map +1 -1
- package/lib/commonjs/components/onboarding/OAuthWebView.js +138 -27
- package/lib/commonjs/components/onboarding/OAuthWebView.js.map +1 -1
- package/lib/commonjs/constants/index.js +3 -3
- package/lib/commonjs/constants/index.js.map +1 -1
- package/lib/commonjs/services/platformAuthService.js +91 -44
- package/lib/commonjs/services/platformAuthService.js.map +1 -1
- package/lib/module/components/OnairosButton.js +2 -3
- package/lib/module/components/OnairosButton.js.map +1 -1
- package/lib/module/components/TrainingModal.js +120 -17
- package/lib/module/components/TrainingModal.js.map +1 -1
- package/lib/module/components/UniversalOnboarding.js +132 -77
- package/lib/module/components/UniversalOnboarding.js.map +1 -1
- package/lib/module/components/onboarding/OAuthWebView.js +139 -28
- package/lib/module/components/onboarding/OAuthWebView.js.map +1 -1
- package/lib/module/constants/index.js +3 -3
- package/lib/module/constants/index.js.map +1 -1
- package/lib/module/services/platformAuthService.js +88 -42
- package/lib/module/services/platformAuthService.js.map +1 -1
- package/lib/typescript/components/OnairosButton.d.ts.map +1 -1
- package/lib/typescript/components/TrainingModal.d.ts.map +1 -1
- package/lib/typescript/components/UniversalOnboarding.d.ts.map +1 -1
- package/lib/typescript/components/onboarding/OAuthWebView.d.ts.map +1 -1
- package/lib/typescript/services/platformAuthService.d.ts +11 -4
- package/lib/typescript/services/platformAuthService.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/OnairosButton.tsx +1 -4
- package/src/components/TrainingModal.tsx +202 -61
- package/src/components/UniversalOnboarding.tsx +129 -76
- package/src/components/onboarding/OAuthWebView.tsx +135 -25
- package/src/constants/index.ts +3 -3
- package/src/services/platformAuthService.ts +106 -40
|
@@ -52,7 +52,9 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
52
52
|
const [platformToggles, setPlatformToggles] = useState<{[key: string]: boolean}>({});
|
|
53
53
|
const [oauthUrl, setOauthUrl] = useState<string>('');
|
|
54
54
|
const [currentPlatform, setCurrentPlatform] = useState<string>('');
|
|
55
|
-
const [
|
|
55
|
+
const [userEmail, setUserEmail] = useState<string>('user@example.com'); // Use proper email instead of random username
|
|
56
|
+
const [isConnectingPlatform, setIsConnectingPlatform] = useState<boolean>(false);
|
|
57
|
+
const [connectingPlatform, setConnectingPlatform] = useState<string | null>(null);
|
|
56
58
|
|
|
57
59
|
const platforms = [
|
|
58
60
|
{ id: 'instagram', name: 'Instagram', icon: require('../assets/images/instagram.png') },
|
|
@@ -155,63 +157,73 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
155
157
|
}, [getConnectionStatus]);
|
|
156
158
|
|
|
157
159
|
const togglePlatform = useCallback(async (platformId: string) => {
|
|
158
|
-
// If toggling on, initiate the OAuth flow for the platform
|
|
159
160
|
if (!platformToggles[platformId]) {
|
|
161
|
+
// Attempt to connect platform
|
|
160
162
|
try {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
...prev,
|
|
165
|
-
[platformId]: !prev[platformId]
|
|
166
|
-
}));
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
163
|
+
setIsConnectingPlatform(true);
|
|
164
|
+
setConnectingPlatform(platformId);
|
|
165
|
+
console.log(`Initiating connection for ${platformId}`);
|
|
169
166
|
|
|
170
|
-
// Check if
|
|
167
|
+
// Check if platform has a native SDK
|
|
171
168
|
if (hasNativeSDK(platformId)) {
|
|
172
|
-
|
|
173
|
-
|
|
169
|
+
console.log(`Using native SDK for ${platformId}`);
|
|
170
|
+
// Use native SDK for authentication
|
|
174
171
|
const success = await initiateNativeAuth(platformId);
|
|
175
|
-
|
|
176
172
|
if (success) {
|
|
177
|
-
|
|
178
|
-
|
|
173
|
+
console.log(`Native authentication successful for ${platformId}`);
|
|
174
|
+
// Update platform toggle state
|
|
175
|
+
setPlatformToggles(prev => ({
|
|
179
176
|
...prev,
|
|
180
|
-
[platformId]:
|
|
177
|
+
[platformId]: true
|
|
181
178
|
}));
|
|
182
179
|
|
|
183
|
-
// Update
|
|
184
|
-
|
|
180
|
+
// Update connections state
|
|
181
|
+
setConnections(prev => ({
|
|
185
182
|
...prev,
|
|
186
|
-
[platformId]: true
|
|
183
|
+
[platformId]: { userName: userEmail, connected: true }
|
|
187
184
|
}));
|
|
188
185
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
186
|
+
} else {
|
|
187
|
+
console.log(`Initiating OAuth flow for ${platformId}`);
|
|
188
|
+
// Use OAuth flow through proxy server
|
|
189
|
+
const oauthUrl = await initiateOAuth(platformId, userEmail);
|
|
190
|
+
if (oauthUrl) {
|
|
191
|
+
console.log(`Received OAuth URL for ${platformId}: ${oauthUrl}`);
|
|
192
|
+
setCurrentPlatform(platformId);
|
|
193
|
+
setOauthUrl(oauthUrl);
|
|
194
|
+
setStep('oauth');
|
|
195
|
+
} else {
|
|
196
|
+
console.error(`No OAuth URL returned for ${platformId}`);
|
|
197
|
+
}
|
|
200
198
|
}
|
|
201
199
|
} catch (error) {
|
|
202
|
-
console.error(`Error
|
|
203
|
-
//
|
|
204
|
-
|
|
200
|
+
console.error(`Error connecting ${platformId}:`, error);
|
|
201
|
+
// Reset toggle state on error
|
|
202
|
+
setPlatformToggles(prev => ({
|
|
203
|
+
...prev,
|
|
204
|
+
[platformId]: false
|
|
205
|
+
}));
|
|
206
|
+
} finally {
|
|
207
|
+
setIsConnectingPlatform(false);
|
|
208
|
+
setConnectingPlatform(null);
|
|
205
209
|
}
|
|
206
210
|
} else {
|
|
207
|
-
//
|
|
211
|
+
// Disconnect platform
|
|
212
|
+
console.log(`Disconnecting ${platformId}`);
|
|
208
213
|
setPlatformToggles(prev => ({
|
|
209
214
|
...prev,
|
|
210
|
-
[platformId]:
|
|
215
|
+
[platformId]: false
|
|
211
216
|
}));
|
|
217
|
+
|
|
218
|
+
// Update connections state
|
|
219
|
+
setConnections(prev => {
|
|
220
|
+
const newConnections = { ...prev };
|
|
221
|
+
delete newConnections[platformId];
|
|
222
|
+
return newConnections;
|
|
223
|
+
});
|
|
212
224
|
}
|
|
213
|
-
}, [platformToggles,
|
|
214
|
-
|
|
225
|
+
}, [platformToggles, userEmail]);
|
|
226
|
+
|
|
215
227
|
/**
|
|
216
228
|
* Handles OAuth callback URLs
|
|
217
229
|
*/
|
|
@@ -226,7 +238,7 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
226
238
|
// Update connections state
|
|
227
239
|
setConnections(prev => ({
|
|
228
240
|
...prev,
|
|
229
|
-
[platform]: { userName:
|
|
241
|
+
[platform]: { userName: userEmail, connected: true }
|
|
230
242
|
}));
|
|
231
243
|
|
|
232
244
|
// Update platform toggles
|
|
@@ -241,18 +253,21 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
241
253
|
} catch (error) {
|
|
242
254
|
console.error('Error handling OAuth callback:', error);
|
|
243
255
|
}
|
|
244
|
-
}, [currentPlatform,
|
|
256
|
+
}, [currentPlatform, userEmail]);
|
|
245
257
|
|
|
246
258
|
/**
|
|
247
259
|
* Handles completion of the OAuth flow
|
|
248
260
|
*/
|
|
249
261
|
const handleOAuthSuccess = useCallback((code: string) => {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
262
|
+
console.log(`OAuth success for ${currentPlatform} with code: ${code}`);
|
|
263
|
+
|
|
264
|
+
// Update connections for the current platform
|
|
265
|
+
if (currentPlatform) {
|
|
266
|
+
// Update connections state
|
|
267
|
+
setConnections(prev => ({
|
|
268
|
+
...prev,
|
|
269
|
+
[currentPlatform]: { userName: userEmail, connected: true }
|
|
270
|
+
}));
|
|
256
271
|
|
|
257
272
|
// Update platform toggles
|
|
258
273
|
setPlatformToggles(prev => ({
|
|
@@ -260,33 +275,37 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
260
275
|
[currentPlatform]: true
|
|
261
276
|
}));
|
|
262
277
|
|
|
263
|
-
//
|
|
264
|
-
|
|
278
|
+
// In a real implementation, we would send the code to our server
|
|
279
|
+
// to exchange it for an access token and store it securely
|
|
280
|
+
console.log(`Simulating token exchange for ${currentPlatform}`);
|
|
281
|
+
|
|
282
|
+
// For demo purposes, we'll just simulate a successful token exchange
|
|
283
|
+
if (debug || test) {
|
|
284
|
+
console.log('Debug mode: Simulating successful token exchange');
|
|
285
|
+
}
|
|
265
286
|
}
|
|
266
|
-
|
|
287
|
+
|
|
288
|
+
// Close OAuth window and return to connect step
|
|
289
|
+
setOauthUrl('');
|
|
290
|
+
setStep('connect');
|
|
291
|
+
}, [currentPlatform, userEmail, debug, test]);
|
|
267
292
|
|
|
268
293
|
const handlePinSubmit = useCallback(async (userPin: string) => {
|
|
269
294
|
setPin(userPin);
|
|
270
295
|
setStep('training');
|
|
271
|
-
// Simulate training progress
|
|
296
|
+
// Simulate training progress over 10 seconds
|
|
272
297
|
let progress = 0;
|
|
273
298
|
const interval = setInterval(() => {
|
|
274
|
-
progress +=
|
|
299
|
+
progress += 1; // 10% progress every second for 1 seconds total
|
|
275
300
|
setTraining({
|
|
276
301
|
progress,
|
|
277
|
-
eta: `${Math.round((1 - progress) *
|
|
302
|
+
eta: `${Math.round((1 - progress) * 10)} seconds remaining`,
|
|
278
303
|
});
|
|
279
304
|
if (progress >= 1) {
|
|
280
305
|
clearInterval(interval);
|
|
281
|
-
|
|
282
|
-
pin: userPin,
|
|
283
|
-
connections,
|
|
284
|
-
platformToggles,
|
|
285
|
-
selectedTier,
|
|
286
|
-
tierData: requestData?.[selectedTier],
|
|
287
|
-
});
|
|
306
|
+
// Training complete - TrainingModal will handle email input and final completion
|
|
288
307
|
}
|
|
289
|
-
}, 1000);
|
|
308
|
+
}, 1000); // 1 second intervals for 10 total seconds
|
|
290
309
|
}, [connections, onComplete, selectedTier, requestData, platformToggles]);
|
|
291
310
|
|
|
292
311
|
const canProceedToPin = useCallback(() => {
|
|
@@ -354,26 +373,41 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
354
373
|
|
|
355
374
|
{/* Platform connection options */}
|
|
356
375
|
<View style={styles.platformsContainer}>
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
376
|
+
{platforms.map((platform) => (
|
|
377
|
+
<View key={platform.id} style={[
|
|
378
|
+
styles.platformItem,
|
|
379
|
+
connections[platform.id]?.connected && styles.platformItemConnected
|
|
380
|
+
]}>
|
|
381
|
+
<View style={styles.platformInfo}>
|
|
382
|
+
<Image
|
|
383
|
+
source={platform.icon}
|
|
384
|
+
style={styles.platformIcon}
|
|
385
|
+
resizeMode="contain"
|
|
386
|
+
/>
|
|
387
|
+
<View style={styles.platformTextContainer}>
|
|
365
388
|
<Text style={styles.platformName}>
|
|
366
389
|
{platform.name}
|
|
367
390
|
</Text>
|
|
391
|
+
{connections[platform.id]?.connected && (
|
|
392
|
+
<Text style={styles.connectedText}>Connected</Text>
|
|
393
|
+
)}
|
|
368
394
|
</View>
|
|
369
|
-
<Switch
|
|
370
|
-
value={platformToggles[platform.id]}
|
|
371
|
-
onValueChange={() => togglePlatform(platform.id)}
|
|
372
|
-
trackColor={{ false: '#767577', true: '#81b0ff' }}
|
|
373
|
-
thumbColor={platformToggles[platform.id] ? '#2196F3' : '#f4f3f4'}
|
|
374
|
-
/>
|
|
375
395
|
</View>
|
|
376
|
-
|
|
396
|
+
<View style={styles.platformActions}>
|
|
397
|
+
{connectingPlatform === platform.id ? (
|
|
398
|
+
<ActivityIndicator size="small" color={COLORS.primary} />
|
|
399
|
+
) : (
|
|
400
|
+
<Switch
|
|
401
|
+
value={platformToggles[platform.id] || connections[platform.id]?.connected || false}
|
|
402
|
+
onValueChange={() => togglePlatform(platform.id)}
|
|
403
|
+
trackColor={{ false: '#767577', true: '#81b0ff' }}
|
|
404
|
+
thumbColor={platformToggles[platform.id] || connections[platform.id]?.connected ? '#2196F3' : '#f4f3f4'}
|
|
405
|
+
disabled={connectingPlatform !== null}
|
|
406
|
+
/>
|
|
407
|
+
)}
|
|
408
|
+
</View>
|
|
409
|
+
</View>
|
|
410
|
+
))}
|
|
377
411
|
</View>
|
|
378
412
|
</ScrollView>
|
|
379
413
|
|
|
@@ -422,10 +456,11 @@ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
|
|
|
422
456
|
platformToggles,
|
|
423
457
|
selectedTier,
|
|
424
458
|
tierData: requestData?.[selectedTier],
|
|
459
|
+
userEmail,
|
|
425
460
|
});
|
|
426
461
|
}}
|
|
427
462
|
modelKey="onairosTrainingModel"
|
|
428
|
-
username={
|
|
463
|
+
username={userEmail}
|
|
429
464
|
/>
|
|
430
465
|
)}
|
|
431
466
|
|
|
@@ -566,6 +601,24 @@ const styles = StyleSheet.create({
|
|
|
566
601
|
fontWeight: '500',
|
|
567
602
|
color: '#000',
|
|
568
603
|
},
|
|
604
|
+
platformTextContainer: {
|
|
605
|
+
flex: 1,
|
|
606
|
+
},
|
|
607
|
+
connectedText: {
|
|
608
|
+
fontSize: 12,
|
|
609
|
+
color: '#4CAF50',
|
|
610
|
+
fontWeight: '500',
|
|
611
|
+
marginTop: 2,
|
|
612
|
+
},
|
|
613
|
+
platformActions: {
|
|
614
|
+
alignItems: 'center',
|
|
615
|
+
justifyContent: 'center',
|
|
616
|
+
},
|
|
617
|
+
platformItemConnected: {
|
|
618
|
+
backgroundColor: '#F8F9FA',
|
|
619
|
+
borderColor: '#4CAF50',
|
|
620
|
+
borderWidth: 1,
|
|
621
|
+
},
|
|
569
622
|
footer: {
|
|
570
623
|
flexDirection: 'row',
|
|
571
624
|
alignItems: 'center',
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import React, { useCallback, useState } from 'react';
|
|
2
|
-
import { View, StyleSheet, ActivityIndicator, SafeAreaView, TouchableOpacity } from 'react-native';
|
|
2
|
+
import { View, StyleSheet, ActivityIndicator, SafeAreaView, TouchableOpacity, Text } from 'react-native';
|
|
3
3
|
import { WebView, WebViewNavigation } from 'react-native-webview';
|
|
4
4
|
import Icon from 'react-native-vector-icons/MaterialIcons';
|
|
5
5
|
import { COLORS } from '../../constants';
|
|
6
|
+
import { isOAuthSuccess, handleOAuthCallback } from '../../services/platformAuthService';
|
|
6
7
|
import type { OAuthWebViewProps } from '../../types';
|
|
7
8
|
|
|
8
9
|
export const OAuthWebView: React.FC<OAuthWebViewProps> = ({
|
|
@@ -13,41 +14,83 @@ export const OAuthWebView: React.FC<OAuthWebViewProps> = ({
|
|
|
13
14
|
onSuccess,
|
|
14
15
|
}) => {
|
|
15
16
|
const [loading, setLoading] = useState(true);
|
|
17
|
+
const [currentUrl, setCurrentUrl] = useState(url);
|
|
16
18
|
|
|
17
19
|
const handleNavigationStateChange = useCallback(
|
|
18
20
|
(navState: WebViewNavigation) => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
console.log(`[OAuthWebView] Navigation state changed for ${platform}:`, navState.url);
|
|
22
|
+
setCurrentUrl(navState.url);
|
|
23
|
+
|
|
24
|
+
// Check for final redirect to onairos.uk/Home (indicates proxy has processed the callback)
|
|
25
|
+
if (navState.url.includes('onairos.uk/Home')) {
|
|
26
|
+
console.log(`[OAuthWebView] Detected final redirect to onairos.uk/Home for ${platform}`);
|
|
27
|
+
|
|
28
|
+
// Add a small delay to ensure the redirect is fully processed
|
|
29
|
+
setTimeout(() => {
|
|
30
|
+
onSuccess('success');
|
|
31
|
+
if (onComplete) {
|
|
32
|
+
onComplete();
|
|
33
|
+
}
|
|
34
|
+
}, 500);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Check for platform-specific success patterns using the service
|
|
39
|
+
if (platform && isOAuthSuccess(navState.url, platform)) {
|
|
40
|
+
console.log(`[OAuthWebView] Detected platform-specific success pattern for ${platform}`);
|
|
41
|
+
|
|
42
|
+
// For YouTube/Google, wait for the final redirect
|
|
43
|
+
if (platform === 'youtube') {
|
|
44
|
+
console.log(`[OAuthWebView] YouTube success detected, waiting for final redirect...`);
|
|
45
|
+
// Don't close immediately for YouTube, wait for the onairos.uk/Home redirect
|
|
46
|
+
return;
|
|
25
47
|
}
|
|
26
48
|
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
|
|
49
|
+
// For other platforms, close immediately
|
|
50
|
+
setTimeout(() => {
|
|
51
|
+
onSuccess('success');
|
|
52
|
+
if (onComplete) {
|
|
53
|
+
onComplete();
|
|
54
|
+
}
|
|
55
|
+
}, 300);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Check for callback URLs with authorization codes
|
|
60
|
+
if (navState.url.includes('/callback') || navState.url.includes('code=')) {
|
|
61
|
+
console.log(`[OAuthWebView] Detected callback URL for ${platform}:`, navState.url);
|
|
62
|
+
|
|
63
|
+
// Extract the authorization code
|
|
64
|
+
const authCode = handleOAuthCallback(navState.url);
|
|
65
|
+
if (authCode) {
|
|
66
|
+
console.log(`[OAuthWebView] Extracted auth code for ${platform}:`, authCode);
|
|
67
|
+
onSuccess(authCode);
|
|
68
|
+
if (onComplete) {
|
|
69
|
+
onComplete();
|
|
70
|
+
}
|
|
30
71
|
}
|
|
31
72
|
return;
|
|
32
73
|
}
|
|
33
74
|
},
|
|
34
|
-
[onComplete, onSuccess]
|
|
75
|
+
[platform, onComplete, onSuccess]
|
|
35
76
|
);
|
|
36
77
|
|
|
78
|
+
const handleLoadStart = useCallback(() => {
|
|
79
|
+
setLoading(true);
|
|
80
|
+
}, []);
|
|
81
|
+
|
|
37
82
|
const handleLoadEnd = useCallback(() => {
|
|
38
83
|
setLoading(false);
|
|
39
84
|
}, []);
|
|
40
85
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
};
|
|
86
|
+
const handleError = useCallback((syntheticEvent: any) => {
|
|
87
|
+
const { nativeEvent } = syntheticEvent;
|
|
88
|
+
console.error(`[OAuthWebView] WebView error for ${platform}:`, nativeEvent);
|
|
89
|
+
setLoading(false);
|
|
90
|
+
}, [platform]);
|
|
91
|
+
|
|
92
|
+
// Get iOS Safari user agent for better compatibility
|
|
93
|
+
const userAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1';
|
|
51
94
|
|
|
52
95
|
return (
|
|
53
96
|
<SafeAreaView style={styles.container}>
|
|
@@ -61,21 +104,56 @@ export const OAuthWebView: React.FC<OAuthWebViewProps> = ({
|
|
|
61
104
|
size={20}
|
|
62
105
|
color={getPlatformColor(platform || 'default')}
|
|
63
106
|
/>
|
|
107
|
+
<Text style={styles.platformTitle}>
|
|
108
|
+
Connect {platform ? platform.charAt(0).toUpperCase() + platform.slice(1) : 'Account'}
|
|
109
|
+
</Text>
|
|
64
110
|
</View>
|
|
111
|
+
<View style={styles.placeholder} />
|
|
65
112
|
</View>
|
|
66
113
|
|
|
67
114
|
<WebView
|
|
68
115
|
source={{ uri: url }}
|
|
69
116
|
onNavigationStateChange={handleNavigationStateChange}
|
|
117
|
+
onLoadStart={handleLoadStart}
|
|
70
118
|
onLoadEnd={handleLoadEnd}
|
|
119
|
+
onError={handleError}
|
|
71
120
|
startInLoadingState={true}
|
|
72
121
|
renderLoading={() => <View />}
|
|
73
122
|
style={styles.webView}
|
|
123
|
+
// Essential WebView configuration for OAuth
|
|
124
|
+
javaScriptEnabled={true}
|
|
125
|
+
domStorageEnabled={true}
|
|
126
|
+
cacheEnabled={true}
|
|
127
|
+
incognito={false} // Allow session persistence
|
|
128
|
+
sharedCookiesEnabled={true} // Critical for Google/YouTube OAuth
|
|
129
|
+
thirdPartyCookiesEnabled={true} // Required for OAuth flows
|
|
130
|
+
userAgent={userAgent} // iOS Safari for better compatibility
|
|
131
|
+
// Additional settings for better OAuth support
|
|
132
|
+
allowsInlineMediaPlayback={true}
|
|
133
|
+
mediaPlaybackRequiresUserAction={false}
|
|
134
|
+
allowsBackForwardNavigationGestures={true}
|
|
135
|
+
// Security settings
|
|
136
|
+
allowsLinkPreview={false}
|
|
137
|
+
allowFileAccess={false}
|
|
138
|
+
allowUniversalAccessFromFileURLs={false}
|
|
139
|
+
mixedContentMode="compatibility"
|
|
74
140
|
/>
|
|
75
141
|
|
|
76
142
|
{loading && (
|
|
77
143
|
<View style={styles.loadingContainer}>
|
|
78
144
|
<ActivityIndicator size="large" color={COLORS.primary} />
|
|
145
|
+
<Text style={styles.loadingText}>
|
|
146
|
+
Connecting to {platform ? platform.charAt(0).toUpperCase() + platform.slice(1) : 'platform'}...
|
|
147
|
+
</Text>
|
|
148
|
+
</View>
|
|
149
|
+
)}
|
|
150
|
+
|
|
151
|
+
{/* Debug info in development */}
|
|
152
|
+
{__DEV__ && (
|
|
153
|
+
<View style={styles.debugContainer}>
|
|
154
|
+
<Text style={styles.debugText} numberOfLines={1}>
|
|
155
|
+
{currentUrl}
|
|
156
|
+
</Text>
|
|
79
157
|
</View>
|
|
80
158
|
)}
|
|
81
159
|
</SafeAreaView>
|
|
@@ -95,6 +173,8 @@ const getPlatformIcon = (platform: string): string => {
|
|
|
95
173
|
return 'push-pin';
|
|
96
174
|
case 'reddit':
|
|
97
175
|
return 'forum';
|
|
176
|
+
case 'email':
|
|
177
|
+
return 'email';
|
|
98
178
|
default:
|
|
99
179
|
return 'link';
|
|
100
180
|
}
|
|
@@ -113,6 +193,8 @@ const getPlatformColor = (platform: string): string => {
|
|
|
113
193
|
return '#E60023';
|
|
114
194
|
case 'reddit':
|
|
115
195
|
return '#FF4500';
|
|
196
|
+
case 'email':
|
|
197
|
+
return '#4285F4';
|
|
116
198
|
default:
|
|
117
199
|
return COLORS.primary;
|
|
118
200
|
}
|
|
@@ -134,21 +216,49 @@ const styles = StyleSheet.create({
|
|
|
134
216
|
},
|
|
135
217
|
titleContainer: {
|
|
136
218
|
flex: 1,
|
|
219
|
+
flexDirection: 'row',
|
|
137
220
|
alignItems: 'center',
|
|
221
|
+
justifyContent: 'center',
|
|
222
|
+
},
|
|
223
|
+
platformTitle: {
|
|
224
|
+
fontSize: 16,
|
|
225
|
+
fontWeight: '600',
|
|
226
|
+
color: '#000',
|
|
227
|
+
marginLeft: 8,
|
|
138
228
|
},
|
|
139
229
|
closeButton: {
|
|
140
230
|
padding: 8,
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
231
|
+
width: 40,
|
|
232
|
+
},
|
|
233
|
+
placeholder: {
|
|
234
|
+
width: 40,
|
|
144
235
|
},
|
|
145
236
|
webView: {
|
|
146
237
|
flex: 1,
|
|
147
238
|
},
|
|
148
239
|
loadingContainer: {
|
|
149
240
|
...StyleSheet.absoluteFillObject,
|
|
150
|
-
backgroundColor: 'rgba(255, 255, 255, 0.
|
|
241
|
+
backgroundColor: 'rgba(255, 255, 255, 0.9)',
|
|
151
242
|
alignItems: 'center',
|
|
152
243
|
justifyContent: 'center',
|
|
153
244
|
},
|
|
245
|
+
loadingText: {
|
|
246
|
+
fontSize: 16,
|
|
247
|
+
color: '#666',
|
|
248
|
+
marginTop: 16,
|
|
249
|
+
textAlign: 'center',
|
|
250
|
+
},
|
|
251
|
+
debugContainer: {
|
|
252
|
+
position: 'absolute',
|
|
253
|
+
bottom: 0,
|
|
254
|
+
left: 0,
|
|
255
|
+
right: 0,
|
|
256
|
+
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
|
257
|
+
padding: 8,
|
|
258
|
+
},
|
|
259
|
+
debugText: {
|
|
260
|
+
color: '#fff',
|
|
261
|
+
fontSize: 12,
|
|
262
|
+
fontFamily: 'monospace',
|
|
263
|
+
},
|
|
154
264
|
});
|
package/src/constants/index.ts
CHANGED
|
@@ -77,7 +77,7 @@ export const PIN_REQUIREMENTS = {
|
|
|
77
77
|
};
|
|
78
78
|
|
|
79
79
|
export const DEEP_LINK_CONFIG = {
|
|
80
|
-
scheme: '
|
|
81
|
-
host: '
|
|
82
|
-
redirectUri: '
|
|
80
|
+
scheme: 'onairosevents',
|
|
81
|
+
host: 'auth',
|
|
82
|
+
redirectUri: 'onairosevents://auth/callback',
|
|
83
83
|
};
|