@onairos/react-native 3.0.16 → 3.0.18

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 (44) hide show
  1. package/lib/commonjs/assets/images/farcaster.png +0 -0
  2. package/lib/commonjs/assets/images/instagram.png +0 -0
  3. package/lib/commonjs/assets/images/linkedin.png +0 -0
  4. package/lib/commonjs/assets/images/pinterest.png +0 -0
  5. package/lib/commonjs/assets/images/reddit.png +0 -0
  6. package/lib/commonjs/assets/images/swerv_logo.png +0 -0
  7. package/lib/commonjs/assets/images/twitter.jpg +0 -0
  8. package/lib/commonjs/assets/images/youtube.png +0 -0
  9. package/lib/commonjs/components/Overlay.js +119 -122
  10. package/lib/commonjs/components/Overlay.js.map +1 -1
  11. package/lib/commonjs/components/Overlay.tsx.new +516 -0
  12. package/lib/commonjs/components/UniversalOnboarding.js +223 -79
  13. package/lib/commonjs/components/UniversalOnboarding.js.map +1 -1
  14. package/lib/commonjs/components/UniversalOnboarding.tsx.new +455 -0
  15. package/lib/module/assets/images/farcaster.png +0 -0
  16. package/lib/module/assets/images/instagram.png +0 -0
  17. package/lib/module/assets/images/linkedin.png +0 -0
  18. package/lib/module/assets/images/pinterest.png +0 -0
  19. package/lib/module/assets/images/reddit.png +0 -0
  20. package/lib/module/assets/images/swerv_logo.png +0 -0
  21. package/lib/module/assets/images/twitter.jpg +0 -0
  22. package/lib/module/assets/images/youtube.png +0 -0
  23. package/lib/module/components/Overlay.js +119 -123
  24. package/lib/module/components/Overlay.js.map +1 -1
  25. package/lib/module/components/Overlay.tsx.new +516 -0
  26. package/lib/module/components/UniversalOnboarding.js +224 -80
  27. package/lib/module/components/UniversalOnboarding.js.map +1 -1
  28. package/lib/module/components/UniversalOnboarding.tsx.new +455 -0
  29. package/lib/typescript/components/Overlay.d.ts +5 -0
  30. package/lib/typescript/components/Overlay.d.ts.map +1 -1
  31. package/lib/typescript/components/UniversalOnboarding.d.ts.map +1 -1
  32. package/package.json +1 -1
  33. package/src/assets/images/farcaster.png +0 -0
  34. package/src/assets/images/instagram.png +0 -0
  35. package/src/assets/images/linkedin.png +0 -0
  36. package/src/assets/images/pinterest.png +0 -0
  37. package/src/assets/images/reddit.png +0 -0
  38. package/src/assets/images/swerv_logo.png +0 -0
  39. package/src/assets/images/twitter.jpg +0 -0
  40. package/src/assets/images/youtube.png +0 -0
  41. package/src/components/Overlay.tsx +144 -161
  42. package/src/components/Overlay.tsx.new +516 -0
  43. package/src/components/UniversalOnboarding.tsx +455 -289
  44. package/src/components/UniversalOnboarding.tsx.new +455 -0
@@ -0,0 +1,455 @@
1
+ import React, { useCallback, useEffect, useState, useRef } from 'react';
2
+ import {
3
+ View,
4
+ Text,
5
+ StyleSheet,
6
+ TouchableOpacity,
7
+ ActivityIndicator,
8
+ Dimensions,
9
+ Platform,
10
+ Modal,
11
+ Animated,
12
+ SafeAreaView,
13
+ TouchableWithoutFeedback,
14
+ ScrollView,
15
+ Image,
16
+ Switch,
17
+ } from 'react-native';
18
+ import Icon from 'react-native-vector-icons/MaterialIcons';
19
+ import { PlatformList } from './PlatformList';
20
+ import { PinInput } from './PinInput';
21
+ import { TrainingModal } from './TrainingModal';
22
+ import { useConnections } from '../hooks/useConnections';
23
+ import { COLORS } from '../constants';
24
+ import type { UniversalOnboardingProps, ConnectionStatus } from '../types';
25
+
26
+ const { height, width } = Dimensions.get('window');
27
+
28
+ export const UniversalOnboarding: React.FC<UniversalOnboardingProps> = ({
29
+ visible,
30
+ onClose,
31
+ AppName,
32
+ requestData,
33
+ returnLink,
34
+ onComplete,
35
+ embedd = false,
36
+ debug = false,
37
+ test = false,
38
+ preferredPlatform,
39
+ }) => {
40
+ const [step, setStep] = useState<'connect' | 'pin' | 'training'>('connect');
41
+ const [connections, setConnections] = useState<ConnectionStatus>({});
42
+ const [pin, setPin] = useState<string>('');
43
+ const [selectedTier, setSelectedTier] = useState<'Small' | 'Medium' | 'Large'>('Medium');
44
+ const [training, setTraining] = useState<{
45
+ progress: number;
46
+ eta: string;
47
+ }>({ progress: 0, eta: '' });
48
+ const [slideAnim] = useState(new Animated.Value(height));
49
+ const [platformToggles, setPlatformToggles] = useState<{[key: string]: boolean}>({});
50
+
51
+ const platforms = [
52
+ { id: 'instagram', name: 'Instagram', icon: require('../assets/images/instagram.png') },
53
+ { id: 'youtube', name: 'YouTube', icon: require('../assets/images/youtube.png') },
54
+ ];
55
+
56
+ const {
57
+ connectPlatform,
58
+ disconnectPlatform,
59
+ getConnectionStatus,
60
+ isConnecting,
61
+ } = useConnections();
62
+
63
+ useEffect(() => {
64
+ if (visible) {
65
+ loadInitialStatus();
66
+ // Animate in
67
+ Animated.spring(slideAnim, {
68
+ toValue: 0,
69
+ useNativeDriver: true,
70
+ bounciness: 0,
71
+ }).start();
72
+
73
+ // Initialize platform toggles
74
+ const initialToggles: { [key: string]: boolean } = {};
75
+ platforms.forEach((platform) => {
76
+ initialToggles[platform.id] = false;
77
+ });
78
+ setPlatformToggles(initialToggles);
79
+
80
+ // Debug mode for Expo Go
81
+ if (debug || Platform.OS === 'web') {
82
+ console.log('Debug mode enabled - Using mock data for onboarding');
83
+ // Pre-populate with mock connections in debug mode
84
+ if (test || Platform.OS === 'web') {
85
+ setConnections({
86
+ instagram: { userName: 'instagram_user', connected: true },
87
+ youtube: { userName: 'youtube_user', connected: true },
88
+ });
89
+ }
90
+ }
91
+
92
+ // If there's a preferred platform, pre-connect
93
+ if (preferredPlatform && debug) {
94
+ setConnections(prev => ({
95
+ ...prev,
96
+ [preferredPlatform]: { userName: `${preferredPlatform}_user`, connected: true }
97
+ }));
98
+ }
99
+ } else {
100
+ // Animate out
101
+ Animated.timing(slideAnim, {
102
+ toValue: height,
103
+ duration: 250,
104
+ useNativeDriver: true,
105
+ }).start(() => {
106
+ // Reset state if needed
107
+ });
108
+ }
109
+ }, [visible, preferredPlatform]);
110
+
111
+ const handleClose = () => {
112
+ // Animate out and then call onClose
113
+ Animated.timing(slideAnim, {
114
+ toValue: height,
115
+ duration: 250,
116
+ useNativeDriver: true,
117
+ }).start(() => {
118
+ onClose();
119
+ });
120
+ };
121
+
122
+ const loadInitialStatus = useCallback(async () => {
123
+ const status = await getConnectionStatus();
124
+ setConnections(status);
125
+ }, [getConnectionStatus]);
126
+
127
+ const togglePlatform = useCallback((platformId: string) => {
128
+ setPlatformToggles(prev => ({
129
+ ...prev,
130
+ [platformId]: !prev[platformId]
131
+ }));
132
+ }, []);
133
+
134
+ const handlePinSubmit = useCallback(async (userPin: string) => {
135
+ setPin(userPin);
136
+ setStep('training');
137
+ // Simulate training progress
138
+ let progress = 0;
139
+ const interval = setInterval(() => {
140
+ progress += 0.1;
141
+ setTraining({
142
+ progress,
143
+ eta: `${Math.round((1 - progress) * 100)} seconds remaining`,
144
+ });
145
+ if (progress >= 1) {
146
+ clearInterval(interval);
147
+ onComplete('https://api2.onairos.uk', 'dummy-token', {
148
+ pin: userPin,
149
+ connections,
150
+ platformToggles,
151
+ selectedTier,
152
+ tierData: requestData?.[selectedTier],
153
+ });
154
+ }
155
+ }, 1000);
156
+ }, [connections, onComplete, selectedTier, requestData, platformToggles]);
157
+
158
+ const canProceedToPin = useCallback(() => {
159
+ // Check if at least one platform is toggled on
160
+ return Object.values(platformToggles).some(value => value === true);
161
+ }, [platformToggles]);
162
+
163
+ const handleProceed = () => {
164
+ if (canProceedToPin()) {
165
+ setStep('pin');
166
+ }
167
+ };
168
+
169
+ return (
170
+ <Modal
171
+ visible={visible}
172
+ transparent
173
+ animationType="none"
174
+ statusBarTranslucent
175
+ onRequestClose={handleClose}
176
+ >
177
+ <TouchableWithoutFeedback onPress={handleClose}>
178
+ <View style={styles.modalOverlay}>
179
+ <TouchableWithoutFeedback onPress={e => e.stopPropagation()}>
180
+ <Animated.View
181
+ style={[
182
+ styles.bottomSheet,
183
+ {
184
+ transform: [{ translateY: slideAnim }],
185
+ }
186
+ ]}
187
+ >
188
+ <SafeAreaView style={styles.container}>
189
+ <View style={styles.handleContainer}>
190
+ <View style={styles.handle} />
191
+ </View>
192
+
193
+ {step === 'connect' && (
194
+ <>
195
+ {/* Header with app icon and arrow to Onairos icon */}
196
+ <View style={styles.header}>
197
+ <View style={styles.headerContent}>
198
+ <View style={styles.appIcon}>
199
+ <Text style={styles.appIconText}>
200
+ {AppName.charAt(0)}
201
+ </Text>
202
+ </View>
203
+ <Icon name="arrow_forward" size={24} color="#666" style={styles.arrow} />
204
+ <View style={styles.onairosIcon}>
205
+ <Text style={styles.onairosIconText}>O</Text>
206
+ </View>
207
+ </View>
208
+ </View>
209
+
210
+ <ScrollView style={styles.content}>
211
+ {/* Main title and description */}
212
+ <View style={styles.titleContainer}>
213
+ <Text style={styles.mainTitle}>
214
+ Connect your data to create a Persona of you, to connect to Cosmos
215
+ </Text>
216
+ <Text style={styles.privacyMessage}>
217
+ None of your app data is shared with ANYONE
218
+ </Text>
219
+ </View>
220
+
221
+ {/* Platform connection options */}
222
+ <View style={styles.platformsContainer}>
223
+ {platforms.map((platform) => (
224
+ <View key={platform.id} style={styles.platformItem}>
225
+ <View style={styles.platformInfo}>
226
+ <Image
227
+ source={platform.icon}
228
+ style={styles.platformIcon}
229
+ resizeMode="contain"
230
+ />
231
+ <Text style={styles.platformName}>
232
+ {platform.name}
233
+ </Text>
234
+ </View>
235
+ <Switch
236
+ value={platformToggles[platform.id]}
237
+ onValueChange={() => togglePlatform(platform.id)}
238
+ trackColor={{ false: '#767577', true: '#81b0ff' }}
239
+ thumbColor={platformToggles[platform.id] ? '#2196F3' : '#f4f3f4'}
240
+ />
241
+ </View>
242
+ ))}
243
+ </View>
244
+ </ScrollView>
245
+
246
+ <View style={styles.footer}>
247
+ <TouchableOpacity
248
+ style={styles.footerButtonCancel}
249
+ onPress={handleClose}
250
+ >
251
+ <Text style={styles.footerButtonText}>Cancel</Text>
252
+ </TouchableOpacity>
253
+
254
+ <TouchableOpacity
255
+ style={[
256
+ styles.footerButtonConfirm,
257
+ !canProceedToPin() && styles.footerButtonDisabled
258
+ ]}
259
+ onPress={handleProceed}
260
+ disabled={!canProceedToPin()}
261
+ >
262
+ <Text style={styles.footerButtonTextConfirm}>Connect</Text>
263
+ </TouchableOpacity>
264
+ </View>
265
+ </>
266
+ )}
267
+
268
+ {step === 'pin' && (
269
+ <PinInput
270
+ onSubmit={handlePinSubmit}
271
+ minLength={8}
272
+ requireSpecialChar
273
+ requireNumber
274
+ />
275
+ )}
276
+
277
+ {step === 'training' && (
278
+ <TrainingModal
279
+ visible={step === 'training'}
280
+ onClose={handleClose}
281
+ onComplete={() => {
282
+ onComplete('https://api2.onairos.uk', 'dummy-token', {
283
+ pin,
284
+ connections,
285
+ platformToggles,
286
+ selectedTier,
287
+ tierData: requestData?.[selectedTier],
288
+ });
289
+ }}
290
+ modelKey="onairosTrainingModel"
291
+ username="demo_user"
292
+ progress={training.progress}
293
+ eta={training.eta}
294
+ onCancel={handleClose}
295
+ />
296
+ )}
297
+ </SafeAreaView>
298
+ </Animated.View>
299
+ </TouchableWithoutFeedback>
300
+ </View>
301
+ </TouchableWithoutFeedback>
302
+ </Modal>
303
+ );
304
+ };
305
+
306
+ const styles = StyleSheet.create({
307
+ modalOverlay: {
308
+ flex: 1,
309
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
310
+ justifyContent: 'flex-end',
311
+ alignItems: 'center',
312
+ },
313
+ bottomSheet: {
314
+ backgroundColor: '#fff',
315
+ width: width,
316
+ height: height * 0.9,
317
+ borderTopLeftRadius: 24,
318
+ borderTopRightRadius: 24,
319
+ overflow: 'hidden',
320
+ },
321
+ container: {
322
+ flex: 1,
323
+ backgroundColor: '#fff',
324
+ },
325
+ handleContainer: {
326
+ width: '100%',
327
+ alignItems: 'center',
328
+ paddingTop: 12,
329
+ paddingBottom: 8,
330
+ },
331
+ handle: {
332
+ width: 40,
333
+ height: 5,
334
+ borderRadius: 3,
335
+ backgroundColor: '#E0E0E0',
336
+ },
337
+ header: {
338
+ padding: 24,
339
+ alignItems: 'center',
340
+ },
341
+ headerContent: {
342
+ flexDirection: 'row',
343
+ alignItems: 'center',
344
+ justifyContent: 'center',
345
+ marginBottom: 16,
346
+ },
347
+ appIcon: {
348
+ width: 48,
349
+ height: 48,
350
+ borderRadius: 16,
351
+ backgroundColor: '#F5F5F5',
352
+ alignItems: 'center',
353
+ justifyContent: 'center',
354
+ },
355
+ appIconText: {
356
+ fontSize: 24,
357
+ color: '#000',
358
+ },
359
+ arrow: {
360
+ marginHorizontal: 16,
361
+ },
362
+ onairosIcon: {
363
+ width: 48,
364
+ height: 48,
365
+ borderRadius: 16,
366
+ backgroundColor: '#F5F5F5',
367
+ alignItems: 'center',
368
+ justifyContent: 'center',
369
+ },
370
+ onairosIconText: {
371
+ fontSize: 24,
372
+ color: '#000',
373
+ },
374
+ titleContainer: {
375
+ marginBottom: 30,
376
+ },
377
+ mainTitle: {
378
+ fontSize: 22,
379
+ fontWeight: '600',
380
+ color: '#000',
381
+ textAlign: 'center',
382
+ marginBottom: 16,
383
+ },
384
+ privacyMessage: {
385
+ fontSize: 14,
386
+ color: '#666',
387
+ textAlign: 'center',
388
+ marginBottom: 16,
389
+ },
390
+ content: {
391
+ flex: 1,
392
+ paddingHorizontal: 24,
393
+ },
394
+ platformsContainer: {
395
+ marginTop: 16,
396
+ },
397
+ platformItem: {
398
+ flexDirection: 'row',
399
+ justifyContent: 'space-between',
400
+ alignItems: 'center',
401
+ padding: 16,
402
+ backgroundColor: '#fff',
403
+ borderRadius: 16,
404
+ marginBottom: 16,
405
+ borderWidth: 1,
406
+ borderColor: '#eee',
407
+ },
408
+ platformInfo: {
409
+ flexDirection: 'row',
410
+ alignItems: 'center',
411
+ },
412
+ platformIcon: {
413
+ width: 32,
414
+ height: 32,
415
+ marginRight: 12,
416
+ },
417
+ platformName: {
418
+ fontSize: 16,
419
+ fontWeight: '500',
420
+ color: '#000',
421
+ },
422
+ footer: {
423
+ flexDirection: 'row',
424
+ alignItems: 'center',
425
+ justifyContent: 'space-between',
426
+ padding: 24,
427
+ borderTopWidth: 1,
428
+ borderTopColor: '#eee',
429
+ backgroundColor: '#fff',
430
+ },
431
+ footerButtonCancel: {
432
+ paddingVertical: 8,
433
+ paddingHorizontal: 16,
434
+ },
435
+ footerButtonConfirm: {
436
+ paddingVertical: 16,
437
+ paddingHorizontal: 32,
438
+ borderRadius: 16,
439
+ backgroundColor: '#fff',
440
+ borderWidth: 1,
441
+ borderColor: '#000',
442
+ },
443
+ footerButtonDisabled: {
444
+ opacity: 0.5,
445
+ },
446
+ footerButtonText: {
447
+ color: '#666',
448
+ fontSize: 16,
449
+ },
450
+ footerButtonTextConfirm: {
451
+ color: '#000',
452
+ fontSize: 16,
453
+ fontWeight: '600',
454
+ },
455
+ });