@onairos/react-native 3.1.16 → 3.1.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 (207) hide show
  1. package/README.md +404 -0
  2. package/lib/commonjs/assets/images/Checkbox.svg +3 -3
  3. package/lib/commonjs/assets/images/EnochE.svg +19 -19
  4. package/lib/commonjs/assets/images/Personalityprofile.svg +3 -3
  5. package/lib/commonjs/assets/images/Personalitytraits.svg +3 -3
  6. package/lib/commonjs/assets/images/Userpreferences.svg +3 -3
  7. package/lib/commonjs/assets/images/arrow.svg +20 -20
  8. package/lib/commonjs/assets/images/basicproficon.svg +43 -43
  9. package/lib/commonjs/assets/images/basicprofile.svg +3 -3
  10. package/lib/commonjs/assets/images/checkmark.svg +4 -4
  11. package/lib/commonjs/assets/images/contentanalysis.svg +3 -3
  12. package/lib/commonjs/assets/images/contenticon.svg +23 -23
  13. package/lib/commonjs/assets/images/personalityicon.svg +18 -18
  14. package/lib/commonjs/assets/images/x-close.svg +3 -3
  15. package/lib/commonjs/components/ModalSheet.js +8 -2
  16. package/lib/commonjs/components/ModalSheet.js.map +1 -1
  17. package/lib/commonjs/components/OnairosButton.js +290 -0
  18. package/lib/commonjs/components/OnairosButton.js.map +1 -0
  19. package/lib/commonjs/components/OnairosSignInButton.js +32 -8
  20. package/lib/commonjs/components/OnairosSignInButton.js.map +1 -1
  21. package/lib/commonjs/components/UniversalOnboarding.js +4 -4
  22. package/lib/commonjs/components/WelcomeScreen.js +29 -13
  23. package/lib/commonjs/components/WelcomeScreen.js.map +1 -1
  24. package/lib/commonjs/config/api.js +2 -2
  25. package/lib/commonjs/hooks/useConnections.js +6 -6
  26. package/lib/commonjs/hooks/useUserConnections.js +10 -10
  27. package/lib/commonjs/index.js +13 -6
  28. package/lib/commonjs/index.js.map +1 -1
  29. package/lib/commonjs/services/apiClient.js +35 -35
  30. package/lib/commonjs/services/apiKeyService.js +99 -99
  31. package/lib/commonjs/services/authService.js +82 -82
  32. package/lib/commonjs/services/biometricPinService.js +10 -10
  33. package/lib/commonjs/services/connectedAccountsService.js +32 -32
  34. package/lib/commonjs/services/googleAuthService.js +15 -15
  35. package/lib/commonjs/services/imageCompressionService.js +15 -15
  36. package/lib/commonjs/services/jwtStorageService.js +59 -59
  37. package/lib/commonjs/services/mobileTrainingService.js +14 -14
  38. package/lib/commonjs/services/pinEncryptionService.js +10 -10
  39. package/lib/commonjs/services/pinStorageUtils.js +15 -15
  40. package/lib/commonjs/services/platformAuthService.js +47 -47
  41. package/lib/commonjs/services/storageService.js +31 -31
  42. package/lib/commonjs/services/trainingApiHelpers.js +33 -33
  43. package/lib/commonjs/services/userConnectionsService.js +24 -24
  44. package/lib/commonjs/utils/Portal.js +4 -4
  45. package/lib/commonjs/utils/api.js +24 -24
  46. package/lib/commonjs/utils/auth.js +18 -18
  47. package/lib/commonjs/utils/crypto.js +13 -13
  48. package/lib/commonjs/utils/encryption.js +12 -12
  49. package/lib/commonjs/utils/eventUtils.js +52 -52
  50. package/lib/commonjs/utils/programmaticFlow.js +16 -16
  51. package/lib/commonjs/utils/retryHelper.js +27 -27
  52. package/lib/module/assets/images/Checkbox.svg +3 -3
  53. package/lib/module/assets/images/EnochE.svg +19 -19
  54. package/lib/module/assets/images/Personalityprofile.svg +3 -3
  55. package/lib/module/assets/images/Personalitytraits.svg +3 -3
  56. package/lib/module/assets/images/Userpreferences.svg +3 -3
  57. package/lib/module/assets/images/arrow.svg +20 -20
  58. package/lib/module/assets/images/basicproficon.svg +43 -43
  59. package/lib/module/assets/images/basicprofile.svg +3 -3
  60. package/lib/module/assets/images/checkmark.svg +4 -4
  61. package/lib/module/assets/images/contentanalysis.svg +3 -3
  62. package/lib/module/assets/images/contenticon.svg +23 -23
  63. package/lib/module/assets/images/personalityicon.svg +18 -18
  64. package/lib/module/assets/images/x-close.svg +3 -3
  65. package/lib/module/components/ModalSheet.js +7 -2
  66. package/lib/module/components/ModalSheet.js.map +1 -1
  67. package/lib/module/components/OnairosButton.js +282 -0
  68. package/lib/module/components/OnairosButton.js.map +1 -0
  69. package/lib/module/components/OnairosSignInButton.js +32 -8
  70. package/lib/module/components/OnairosSignInButton.js.map +1 -1
  71. package/lib/module/components/UniversalOnboarding.js +4 -4
  72. package/lib/module/components/WelcomeScreen.js +25 -10
  73. package/lib/module/components/WelcomeScreen.js.map +1 -1
  74. package/lib/module/config/api.js +2 -2
  75. package/lib/module/hooks/useConnections.js +6 -6
  76. package/lib/module/hooks/useUserConnections.js +10 -10
  77. package/lib/module/index.js +11 -11
  78. package/lib/module/index.js.map +1 -1
  79. package/lib/module/services/apiClient.js +35 -35
  80. package/lib/module/services/apiKeyService.js +99 -99
  81. package/lib/module/services/authService.js +82 -82
  82. package/lib/module/services/biometricPinService.js +10 -10
  83. package/lib/module/services/connectedAccountsService.js +32 -32
  84. package/lib/module/services/googleAuthService.js +15 -15
  85. package/lib/module/services/imageCompressionService.js +15 -15
  86. package/lib/module/services/jwtStorageService.js +59 -59
  87. package/lib/module/services/mobileTrainingService.js +14 -14
  88. package/lib/module/services/pinEncryptionService.js +10 -10
  89. package/lib/module/services/pinStorageUtils.js +15 -15
  90. package/lib/module/services/platformAuthService.js +47 -47
  91. package/lib/module/services/storageService.js +31 -31
  92. package/lib/module/services/trainingApiHelpers.js +33 -33
  93. package/lib/module/services/userConnectionsService.js +24 -24
  94. package/lib/module/utils/Portal.js +4 -4
  95. package/lib/module/utils/api.js +24 -24
  96. package/lib/module/utils/auth.js +18 -18
  97. package/lib/module/utils/crypto.js +13 -13
  98. package/lib/module/utils/encryption.js +12 -12
  99. package/lib/module/utils/eventUtils.js +52 -52
  100. package/lib/module/utils/programmaticFlow.js +16 -16
  101. package/lib/module/utils/retryHelper.js +27 -27
  102. package/lib/typescript/components/ModalSheet.d.ts.map +1 -1
  103. package/lib/typescript/components/OnairosButton.d.ts +37 -0
  104. package/lib/typescript/components/OnairosButton.d.ts.map +1 -0
  105. package/lib/typescript/components/OnairosSignInButton.d.ts.map +1 -1
  106. package/lib/typescript/components/WelcomeScreen.d.ts.map +1 -1
  107. package/lib/typescript/index.d.ts +3 -1
  108. package/lib/typescript/index.d.ts.map +1 -1
  109. package/package.json +145 -163
  110. package/src/api/index.ts +151 -151
  111. package/src/assets/images/Checkbox.svg +3 -3
  112. package/src/assets/images/EnochE.svg +19 -19
  113. package/src/assets/images/Personalityprofile.svg +3 -3
  114. package/src/assets/images/Personalitytraits.svg +3 -3
  115. package/src/assets/images/Userpreferences.svg +3 -3
  116. package/src/assets/images/arrow.svg +20 -20
  117. package/src/assets/images/basicproficon.svg +43 -43
  118. package/src/assets/images/basicprofile.svg +3 -3
  119. package/src/assets/images/checkmark.svg +4 -4
  120. package/src/assets/images/contentanalysis.svg +3 -3
  121. package/src/assets/images/contenticon.svg +23 -23
  122. package/src/assets/images/personalityicon.svg +18 -18
  123. package/src/assets/images/x-close.svg +3 -3
  124. package/src/components/BodyText.tsx +33 -33
  125. package/src/components/BrandMark.tsx +62 -62
  126. package/src/components/CodeInput.tsx +32 -32
  127. package/src/components/DataRequestScreen.tsx +355 -355
  128. package/src/components/EmailInput.tsx +31 -31
  129. package/src/components/EmailVerificationModal.tsx +363 -363
  130. package/src/components/ExistingUserDataConfirmation.tsx +506 -506
  131. package/src/components/GoogleButton.tsx +55 -55
  132. package/src/components/HeadingGroup.tsx +49 -49
  133. package/src/components/ModalHeader.tsx +125 -125
  134. package/src/components/ModalSheet.tsx +59 -57
  135. package/src/components/Onairos.tsx +422 -422
  136. package/src/components/OnairosButton.tsx +339 -0
  137. package/src/components/OnairosSignInButton.tsx +31 -9
  138. package/src/components/Overlay.tsx +506 -506
  139. package/src/components/PersonaImage.tsx +79 -79
  140. package/src/components/PersonaLoadingScreen.tsx +201 -201
  141. package/src/components/PersonalizationConsentScreen.tsx +410 -410
  142. package/src/components/PinCreationScreen.tsx +492 -492
  143. package/src/components/PinInput.tsx +555 -555
  144. package/src/components/PlatformConnectorsStep.tsx +891 -891
  145. package/src/components/PlatformList.tsx +144 -144
  146. package/src/components/PlatformToggle.tsx +226 -226
  147. package/src/components/PrimaryButton.tsx +213 -213
  148. package/src/components/SignInMatchAnimation.tsx +225 -225
  149. package/src/components/SignInStep.tsx +217 -217
  150. package/src/components/TrainingModal.tsx +1047 -1047
  151. package/src/components/UniversalOnboarding.tsx +2887 -2887
  152. package/src/components/VerificationStep.tsx +198 -198
  153. package/src/components/WelcomeScreen.tsx +490 -473
  154. package/src/components/icons/Basicproficon.tsx +30 -30
  155. package/src/components/icons/Basicprofile.tsx +17 -17
  156. package/src/components/icons/Checkbox.tsx +17 -17
  157. package/src/components/icons/Checkmark.tsx +24 -24
  158. package/src/components/icons/Contentanalysis.tsx +17 -17
  159. package/src/components/icons/Contenticon.tsx +30 -30
  160. package/src/components/icons/EnochE.tsx +39 -39
  161. package/src/components/icons/Personalityicon.tsx +22 -22
  162. package/src/components/icons/Personalityprofile.tsx +17 -17
  163. package/src/components/icons/Personalitytraits.tsx +17 -17
  164. package/src/components/icons/Userpreferences.tsx +17 -17
  165. package/src/components/icons/index.ts +12 -12
  166. package/src/components/onboarding/OAuthWebView.tsx +232 -232
  167. package/src/config/api.ts +25 -25
  168. package/src/context/AuthContext.tsx +393 -393
  169. package/src/hooks/useConnectedAccounts.ts +138 -138
  170. package/src/hooks/useConnections.ts +161 -161
  171. package/src/hooks/useCredentials.ts +174 -174
  172. package/src/hooks/useUserConnections.ts +165 -165
  173. package/src/index.js +14 -0
  174. package/src/index.ts +99 -96
  175. package/src/services/apiClient.ts +336 -336
  176. package/src/services/apiKeyService.ts +919 -919
  177. package/src/services/authService.ts +1008 -1008
  178. package/src/services/biometricPinService.ts +192 -192
  179. package/src/services/connectedAccountsService.ts +289 -289
  180. package/src/services/googleAuthService.ts +279 -279
  181. package/src/services/imageCompressionService.ts +302 -302
  182. package/src/services/jwtStorageService.ts +256 -256
  183. package/src/services/mobileTrainingService.ts +203 -203
  184. package/src/services/pinEncryptionService.ts +75 -75
  185. package/src/services/pinStorageUtils.ts +96 -96
  186. package/src/services/platformAuthService.ts +1346 -1346
  187. package/src/services/storageService.ts +451 -451
  188. package/src/services/trainingApiHelpers.ts +66 -66
  189. package/src/services/userConnectionsService.ts +556 -556
  190. package/src/services/youtubeMigrationService.ts +453 -453
  191. package/src/theme/index.ts +239 -239
  192. package/src/types/ambient.d.ts +28 -28
  193. package/src/types/index.ts +265 -265
  194. package/src/types/node-fix.d.ts +18 -18
  195. package/src/types/node-override.d.ts +23 -23
  196. package/src/types/opacity.d.ts +15 -15
  197. package/src/types/types.d.ts +17 -17
  198. package/src/utils/Portal.tsx +82 -82
  199. package/src/utils/api.js +111 -111
  200. package/src/utils/auth.js +103 -103
  201. package/src/utils/crypto.js +59 -59
  202. package/src/utils/encryption.ts +68 -68
  203. package/src/utils/eventUtils.ts +302 -302
  204. package/src/utils/haptics.ts +58 -58
  205. package/src/utils/imagePreloader.ts +2 -2
  206. package/src/utils/programmaticFlow.ts +112 -112
  207. package/src/utils/retryHelper.ts +274 -274
@@ -1,79 +1,79 @@
1
- import React, { useEffect, useRef } from 'react';
2
- import {
3
- View,
4
- Image,
5
- Animated,
6
- StyleSheet,
7
- } from 'react-native';
8
-
9
- interface PersonaImageProps {
10
- level: number; // 1-5 based on connected platforms
11
- style?: any;
12
- }
13
-
14
- const PersonaImage: React.FC<PersonaImageProps> = ({
15
- level,
16
- style,
17
- }) => {
18
- const fadeAnims = useRef([
19
- new Animated.Value(1), // persona1
20
- new Animated.Value(0), // persona2
21
- new Animated.Value(0), // persona3
22
- new Animated.Value(0), // persona4
23
- new Animated.Value(0), // persona5
24
- ]).current;
25
-
26
- const personaImages = [
27
- require('../assets/images/persona1.png'),
28
- require('../assets/images/persona2.png'),
29
- require('../assets/images/persona3.png'),
30
- require('../assets/images/persona4.png'),
31
- require('../assets/images/persona5.png'),
32
- ];
33
-
34
- useEffect(() => {
35
- // Animate to show the correct persona level
36
- fadeAnims.forEach((anim, index) => {
37
- Animated.timing(anim, {
38
- toValue: index === level - 1 ? 1 : 0,
39
- duration: 400,
40
- useNativeDriver: true,
41
- }).start();
42
- });
43
- }, [level, fadeAnims]);
44
-
45
- return (
46
- <View style={[styles.container, style]}>
47
- {personaImages.map((image, index) => (
48
- <Animated.Image
49
- key={index}
50
- source={image}
51
- style={[
52
- styles.personaImage,
53
- {
54
- opacity: fadeAnims[index],
55
- position: index === 0 ? 'relative' : 'absolute',
56
- },
57
- ]}
58
- resizeMode="contain"
59
- />
60
- ))}
61
- </View>
62
- );
63
- };
64
-
65
- const styles = StyleSheet.create({
66
- container: {
67
- width: 200,
68
- height: 200,
69
- alignItems: 'center',
70
- justifyContent: 'center',
71
- },
72
-
73
- personaImage: {
74
- width: '100%',
75
- height: '100%',
76
- },
77
- });
78
-
79
- export default PersonaImage;
1
+ import React, { useEffect, useRef } from 'react';
2
+ import {
3
+ View,
4
+ Image,
5
+ Animated,
6
+ StyleSheet,
7
+ } from 'react-native';
8
+
9
+ interface PersonaImageProps {
10
+ level: number; // 1-5 based on connected platforms
11
+ style?: any;
12
+ }
13
+
14
+ const PersonaImage: React.FC<PersonaImageProps> = ({
15
+ level,
16
+ style,
17
+ }) => {
18
+ const fadeAnims = useRef([
19
+ new Animated.Value(1), // persona1
20
+ new Animated.Value(0), // persona2
21
+ new Animated.Value(0), // persona3
22
+ new Animated.Value(0), // persona4
23
+ new Animated.Value(0), // persona5
24
+ ]).current;
25
+
26
+ const personaImages = [
27
+ require('../assets/images/persona1.png'),
28
+ require('../assets/images/persona2.png'),
29
+ require('../assets/images/persona3.png'),
30
+ require('../assets/images/persona4.png'),
31
+ require('../assets/images/persona5.png'),
32
+ ];
33
+
34
+ useEffect(() => {
35
+ // Animate to show the correct persona level
36
+ fadeAnims.forEach((anim, index) => {
37
+ Animated.timing(anim, {
38
+ toValue: index === level - 1 ? 1 : 0,
39
+ duration: 400,
40
+ useNativeDriver: true,
41
+ }).start();
42
+ });
43
+ }, [level, fadeAnims]);
44
+
45
+ return (
46
+ <View style={[styles.container, style]}>
47
+ {personaImages.map((image, index) => (
48
+ <Animated.Image
49
+ key={index}
50
+ source={image}
51
+ style={[
52
+ styles.personaImage,
53
+ {
54
+ opacity: fadeAnims[index],
55
+ position: index === 0 ? 'relative' : 'absolute',
56
+ },
57
+ ]}
58
+ resizeMode="contain"
59
+ />
60
+ ))}
61
+ </View>
62
+ );
63
+ };
64
+
65
+ const styles = StyleSheet.create({
66
+ container: {
67
+ width: 200,
68
+ height: 200,
69
+ alignItems: 'center',
70
+ justifyContent: 'center',
71
+ },
72
+
73
+ personaImage: {
74
+ width: '100%',
75
+ height: '100%',
76
+ },
77
+ });
78
+
79
+ export default PersonaImage;
@@ -1,201 +1,201 @@
1
- import React, { useEffect, useState } from 'react';
2
- import {
3
- View,
4
- Text,
5
- StyleSheet,
6
- Animated,
7
- Easing,
8
- } from 'react-native';
9
- import { COLORS, SPACING } from '../theme';
10
- import PrimaryButton from './PrimaryButton';
11
-
12
- interface PersonaLoadingScreenProps {
13
- visible: boolean;
14
- onComplete: () => void;
15
- progress: number; // 0-100
16
- status: string;
17
- }
18
-
19
- const PersonaLoadingScreen: React.FC<PersonaLoadingScreenProps> = ({
20
- visible,
21
- onComplete,
22
- progress,
23
- status,
24
- }) => {
25
- const [dotsAnimation] = useState(new Animated.Value(0));
26
- const [showCompleteButton, setShowCompleteButton] = useState(false);
27
-
28
- // Animate dots
29
- useEffect(() => {
30
- if (visible && progress < 100) {
31
- const animation = Animated.loop(
32
- Animated.timing(dotsAnimation, {
33
- toValue: 1,
34
- duration: 1500,
35
- easing: Easing.linear,
36
- useNativeDriver: false,
37
- })
38
- );
39
- animation.start();
40
-
41
- return () => animation.stop();
42
- }
43
- }, [visible, progress, dotsAnimation]);
44
-
45
- // Show complete button when progress reaches 100
46
- useEffect(() => {
47
- if (progress >= 100) {
48
- setShowCompleteButton(true);
49
- }
50
- }, [progress]);
51
-
52
- const getDots = () => {
53
- // const animatedValue = dotsAnimation._value; // _value is deprecated
54
- const animatedValue = Math.random(); // Use random for animation effect
55
- if (animatedValue < 0.33) return '.';
56
- if (animatedValue < 0.66) return '..';
57
- return '...';
58
- };
59
-
60
- const getStatusMessage = (progress: number) => {
61
- if (progress === 0) return 'Initializing';
62
- if (progress < 25) return 'Connecting to your data';
63
- if (progress < 50) return 'Training your persona';
64
- if (progress < 75) return 'Running test inference';
65
- if (progress < 100) return 'Finalizing your profile';
66
- return 'Complete!';
67
- };
68
-
69
- if (!visible) {
70
- return null;
71
- }
72
-
73
- return (
74
- <View style={styles.container}>
75
- <View style={styles.content}>
76
- {/* Header */}
77
- <View style={styles.header}>
78
- <Text style={styles.title}>Building your persona</Text>
79
- <Text style={styles.subtitle}>
80
- {progress < 100
81
- ? 'This will only take a moment. We\'re personalizing your experience.'
82
- : 'Your persona is ready!'
83
- }
84
- </Text>
85
- </View>
86
-
87
- {/* Progress Bar */}
88
- <View style={styles.progressContainer}>
89
- <View style={styles.progressBar}>
90
- <View
91
- style={[
92
- styles.progressFill,
93
- { width: `${progress}%` }
94
- ]}
95
- />
96
- </View>
97
- <Text style={styles.progressText}>{Math.round(progress)}%</Text>
98
- {!showCompleteButton && (
99
- <Text style={styles.statusText}>
100
- {status || getStatusMessage(progress)}
101
- {progress < 100 && (
102
- <Animated.Text>
103
- {getDots()}
104
- </Animated.Text>
105
- )}
106
- </Text>
107
- )}
108
- </View>
109
-
110
- {/* Complete Button */}
111
- {showCompleteButton && (
112
- <View style={styles.completeContainer}>
113
- <PrimaryButton
114
- label="Continue"
115
- onPress={onComplete}
116
- />
117
- </View>
118
- )}
119
- </View>
120
- </View>
121
- );
122
- };
123
-
124
- const styles = StyleSheet.create({
125
- container: {
126
- flex: 1,
127
- backgroundColor: COLORS.surface,
128
- justifyContent: 'center',
129
- paddingHorizontal: 24,
130
- },
131
-
132
- content: {
133
- alignItems: 'center',
134
- },
135
-
136
- header: {
137
- alignItems: 'center',
138
- marginBottom: 48,
139
- },
140
-
141
- title: {
142
- fontSize: 24,
143
- fontFamily: 'IBM Plex Sans',
144
- fontWeight: '700',
145
- color: COLORS.grey800,
146
- textAlign: 'center',
147
- marginBottom: 12,
148
- },
149
-
150
- subtitle: {
151
- fontSize: 16,
152
- fontFamily: 'Inter',
153
- fontWeight: '400',
154
- color: COLORS.grey600,
155
- textAlign: 'center',
156
- lineHeight: 24,
157
- },
158
-
159
- progressContainer: {
160
- width: '100%',
161
- alignItems: 'center',
162
- marginBottom: 48,
163
- },
164
-
165
- progressBar: {
166
- width: '100%',
167
- height: 8,
168
- backgroundColor: '#F5F5F5',
169
- borderRadius: 4,
170
- overflow: 'hidden',
171
- marginBottom: 16,
172
- },
173
-
174
- progressFill: {
175
- height: '100%',
176
- backgroundColor: '#1BA9D4',
177
- borderRadius: 4,
178
- },
179
-
180
- progressText: {
181
- fontSize: 18,
182
- fontFamily: 'Inter',
183
- fontWeight: '600',
184
- color: COLORS.grey800,
185
- marginBottom: 8,
186
- },
187
-
188
- statusText: {
189
- fontSize: 14,
190
- fontFamily: 'Inter',
191
- fontWeight: '400',
192
- color: COLORS.grey600,
193
- textAlign: 'center',
194
- },
195
-
196
- completeContainer: {
197
- width: '100%',
198
- },
199
- });
200
-
201
- export default PersonaLoadingScreen;
1
+ import React, { useEffect, useState } from 'react';
2
+ import {
3
+ View,
4
+ Text,
5
+ StyleSheet,
6
+ Animated,
7
+ Easing,
8
+ } from 'react-native';
9
+ import { COLORS, SPACING } from '../theme';
10
+ import PrimaryButton from './PrimaryButton';
11
+
12
+ interface PersonaLoadingScreenProps {
13
+ visible: boolean;
14
+ onComplete: () => void;
15
+ progress: number; // 0-100
16
+ status: string;
17
+ }
18
+
19
+ const PersonaLoadingScreen: React.FC<PersonaLoadingScreenProps> = ({
20
+ visible,
21
+ onComplete,
22
+ progress,
23
+ status,
24
+ }) => {
25
+ const [dotsAnimation] = useState(new Animated.Value(0));
26
+ const [showCompleteButton, setShowCompleteButton] = useState(false);
27
+
28
+ // Animate dots
29
+ useEffect(() => {
30
+ if (visible && progress < 100) {
31
+ const animation = Animated.loop(
32
+ Animated.timing(dotsAnimation, {
33
+ toValue: 1,
34
+ duration: 1500,
35
+ easing: Easing.linear,
36
+ useNativeDriver: false,
37
+ })
38
+ );
39
+ animation.start();
40
+
41
+ return () => animation.stop();
42
+ }
43
+ }, [visible, progress, dotsAnimation]);
44
+
45
+ // Show complete button when progress reaches 100
46
+ useEffect(() => {
47
+ if (progress >= 100) {
48
+ setShowCompleteButton(true);
49
+ }
50
+ }, [progress]);
51
+
52
+ const getDots = () => {
53
+ // const animatedValue = dotsAnimation._value; // _value is deprecated
54
+ const animatedValue = Math.random(); // Use random for animation effect
55
+ if (animatedValue < 0.33) return '.';
56
+ if (animatedValue < 0.66) return '..';
57
+ return '...';
58
+ };
59
+
60
+ const getStatusMessage = (progress: number) => {
61
+ if (progress === 0) return 'Initializing';
62
+ if (progress < 25) return 'Connecting to your data';
63
+ if (progress < 50) return 'Training your persona';
64
+ if (progress < 75) return 'Running test inference';
65
+ if (progress < 100) return 'Finalizing your profile';
66
+ return 'Complete!';
67
+ };
68
+
69
+ if (!visible) {
70
+ return null;
71
+ }
72
+
73
+ return (
74
+ <View style={styles.container}>
75
+ <View style={styles.content}>
76
+ {/* Header */}
77
+ <View style={styles.header}>
78
+ <Text style={styles.title}>Building your persona</Text>
79
+ <Text style={styles.subtitle}>
80
+ {progress < 100
81
+ ? 'This will only take a moment. We\'re personalizing your experience.'
82
+ : 'Your persona is ready!'
83
+ }
84
+ </Text>
85
+ </View>
86
+
87
+ {/* Progress Bar */}
88
+ <View style={styles.progressContainer}>
89
+ <View style={styles.progressBar}>
90
+ <View
91
+ style={[
92
+ styles.progressFill,
93
+ { width: `${progress}%` }
94
+ ]}
95
+ />
96
+ </View>
97
+ <Text style={styles.progressText}>{Math.round(progress)}%</Text>
98
+ {!showCompleteButton && (
99
+ <Text style={styles.statusText}>
100
+ {status || getStatusMessage(progress)}
101
+ {progress < 100 && (
102
+ <Animated.Text>
103
+ {getDots()}
104
+ </Animated.Text>
105
+ )}
106
+ </Text>
107
+ )}
108
+ </View>
109
+
110
+ {/* Complete Button */}
111
+ {showCompleteButton && (
112
+ <View style={styles.completeContainer}>
113
+ <PrimaryButton
114
+ label="Continue"
115
+ onPress={onComplete}
116
+ />
117
+ </View>
118
+ )}
119
+ </View>
120
+ </View>
121
+ );
122
+ };
123
+
124
+ const styles = StyleSheet.create({
125
+ container: {
126
+ flex: 1,
127
+ backgroundColor: COLORS.surface,
128
+ justifyContent: 'center',
129
+ paddingHorizontal: 24,
130
+ },
131
+
132
+ content: {
133
+ alignItems: 'center',
134
+ },
135
+
136
+ header: {
137
+ alignItems: 'center',
138
+ marginBottom: 48,
139
+ },
140
+
141
+ title: {
142
+ fontSize: 24,
143
+ fontFamily: 'IBM Plex Sans',
144
+ fontWeight: '700',
145
+ color: COLORS.grey800,
146
+ textAlign: 'center',
147
+ marginBottom: 12,
148
+ },
149
+
150
+ subtitle: {
151
+ fontSize: 16,
152
+ fontFamily: 'Inter',
153
+ fontWeight: '400',
154
+ color: COLORS.grey600,
155
+ textAlign: 'center',
156
+ lineHeight: 24,
157
+ },
158
+
159
+ progressContainer: {
160
+ width: '100%',
161
+ alignItems: 'center',
162
+ marginBottom: 48,
163
+ },
164
+
165
+ progressBar: {
166
+ width: '100%',
167
+ height: 8,
168
+ backgroundColor: '#F5F5F5',
169
+ borderRadius: 4,
170
+ overflow: 'hidden',
171
+ marginBottom: 16,
172
+ },
173
+
174
+ progressFill: {
175
+ height: '100%',
176
+ backgroundColor: '#1BA9D4',
177
+ borderRadius: 4,
178
+ },
179
+
180
+ progressText: {
181
+ fontSize: 18,
182
+ fontFamily: 'Inter',
183
+ fontWeight: '600',
184
+ color: COLORS.grey800,
185
+ marginBottom: 8,
186
+ },
187
+
188
+ statusText: {
189
+ fontSize: 14,
190
+ fontFamily: 'Inter',
191
+ fontWeight: '400',
192
+ color: COLORS.grey600,
193
+ textAlign: 'center',
194
+ },
195
+
196
+ completeContainer: {
197
+ width: '100%',
198
+ },
199
+ });
200
+
201
+ export default PersonaLoadingScreen;