@oxyhq/services 6.9.42 → 6.9.44

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 (240) hide show
  1. package/lib/commonjs/index.js +9 -0
  2. package/lib/commonjs/index.js.map +1 -1
  3. package/lib/commonjs/ui/components/ActingAsBanner.js +143 -0
  4. package/lib/commonjs/ui/components/ActingAsBanner.js.map +1 -0
  5. package/lib/commonjs/ui/components/BottomSheet.js +3 -3
  6. package/lib/commonjs/ui/components/BottomSheet.js.map +1 -1
  7. package/lib/commonjs/ui/components/BottomSheetRouter.js +4 -3
  8. package/lib/commonjs/ui/components/BottomSheetRouter.js.map +1 -1
  9. package/lib/commonjs/ui/components/OxyProvider.js +48 -43
  10. package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
  11. package/lib/commonjs/ui/components/fileManagement/FileDetailsModal.js +3 -2
  12. package/lib/commonjs/ui/components/fileManagement/FileDetailsModal.js.map +1 -1
  13. package/lib/commonjs/ui/components/fileManagement/UploadPreview.js +3 -2
  14. package/lib/commonjs/ui/components/fileManagement/UploadPreview.js.map +1 -1
  15. package/lib/commonjs/ui/components/modals/DeleteAccountModal.js +3 -2
  16. package/lib/commonjs/ui/components/modals/DeleteAccountModal.js.map +1 -1
  17. package/lib/commonjs/ui/context/OxyContext.js +94 -6
  18. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  19. package/lib/commonjs/ui/context/hooks/useAuthOperations.js +2 -1
  20. package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
  21. package/lib/commonjs/ui/navigation/routes.js +3 -2
  22. package/lib/commonjs/ui/navigation/routes.js.map +1 -1
  23. package/lib/commonjs/ui/screens/AccountCenterScreen.js +29 -7
  24. package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
  25. package/lib/commonjs/ui/screens/AccountOverviewScreen.js +8 -6
  26. package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
  27. package/lib/commonjs/ui/screens/AccountSettingsScreen.js +5 -4
  28. package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
  29. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +240 -3
  30. package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
  31. package/lib/commonjs/ui/screens/AccountVerificationScreen.js +3 -2
  32. package/lib/commonjs/ui/screens/AccountVerificationScreen.js.map +1 -1
  33. package/lib/commonjs/ui/screens/CreateManagedAccountScreen.js +346 -0
  34. package/lib/commonjs/ui/screens/CreateManagedAccountScreen.js.map +1 -0
  35. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js +3 -2
  36. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js.map +1 -1
  37. package/lib/commonjs/ui/screens/FAQScreen.js +3 -2
  38. package/lib/commonjs/ui/screens/FAQScreen.js.map +1 -1
  39. package/lib/commonjs/ui/screens/FeedbackScreen.js +3 -2
  40. package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
  41. package/lib/commonjs/ui/screens/HelpSupportScreen.js +3 -2
  42. package/lib/commonjs/ui/screens/HelpSupportScreen.js.map +1 -1
  43. package/lib/commonjs/ui/screens/HistoryViewScreen.js +3 -2
  44. package/lib/commonjs/ui/screens/HistoryViewScreen.js.map +1 -1
  45. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +3 -2
  46. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
  47. package/lib/commonjs/ui/screens/LearnMoreUsernamesScreen.js +3 -2
  48. package/lib/commonjs/ui/screens/LearnMoreUsernamesScreen.js.map +1 -1
  49. package/lib/commonjs/ui/screens/LegalDocumentsScreen.js +6 -4
  50. package/lib/commonjs/ui/screens/LegalDocumentsScreen.js.map +1 -1
  51. package/lib/commonjs/ui/screens/OxyAuthScreen.js +12 -8
  52. package/lib/commonjs/ui/screens/OxyAuthScreen.js.map +1 -1
  53. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +3 -2
  54. package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -1
  55. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js +6 -4
  56. package/lib/commonjs/ui/screens/PrivacySettingsScreen.js.map +1 -1
  57. package/lib/commonjs/ui/screens/ProfileScreen.js +8 -6
  58. package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
  59. package/lib/commonjs/ui/screens/SavesCollectionsScreen.js +3 -2
  60. package/lib/commonjs/ui/screens/SavesCollectionsScreen.js.map +1 -1
  61. package/lib/commonjs/ui/screens/SearchSettingsScreen.js +6 -4
  62. package/lib/commonjs/ui/screens/SearchSettingsScreen.js.map +1 -1
  63. package/lib/commonjs/ui/screens/SessionManagementScreen.js +6 -4
  64. package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
  65. package/lib/commonjs/ui/screens/UserLinksScreen.js +3 -2
  66. package/lib/commonjs/ui/screens/UserLinksScreen.js.map +1 -1
  67. package/lib/commonjs/ui/screens/UserListScreen.js +9 -6
  68. package/lib/commonjs/ui/screens/UserListScreen.js.map +1 -1
  69. package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js +3 -2
  70. package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
  71. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +8 -6
  72. package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
  73. package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js +3 -2
  74. package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
  75. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +3 -2
  76. package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
  77. package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js +6 -4
  78. package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
  79. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +3 -2
  80. package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
  81. package/lib/module/index.js +3 -0
  82. package/lib/module/index.js.map +1 -1
  83. package/lib/module/ui/components/ActingAsBanner.js +140 -0
  84. package/lib/module/ui/components/ActingAsBanner.js.map +1 -0
  85. package/lib/module/ui/components/BottomSheet.js +3 -3
  86. package/lib/module/ui/components/BottomSheet.js.map +1 -1
  87. package/lib/module/ui/components/BottomSheetRouter.js +4 -3
  88. package/lib/module/ui/components/BottomSheetRouter.js.map +1 -1
  89. package/lib/module/ui/components/OxyProvider.js +49 -44
  90. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  91. package/lib/module/ui/components/fileManagement/FileDetailsModal.js +3 -2
  92. package/lib/module/ui/components/fileManagement/FileDetailsModal.js.map +1 -1
  93. package/lib/module/ui/components/fileManagement/UploadPreview.js +3 -2
  94. package/lib/module/ui/components/fileManagement/UploadPreview.js.map +1 -1
  95. package/lib/module/ui/components/modals/DeleteAccountModal.js +3 -2
  96. package/lib/module/ui/components/modals/DeleteAccountModal.js.map +1 -1
  97. package/lib/module/ui/context/OxyContext.js +94 -6
  98. package/lib/module/ui/context/OxyContext.js.map +1 -1
  99. package/lib/module/ui/context/hooks/useAuthOperations.js +2 -1
  100. package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
  101. package/lib/module/ui/navigation/routes.js +3 -2
  102. package/lib/module/ui/navigation/routes.js.map +1 -1
  103. package/lib/module/ui/screens/AccountCenterScreen.js +29 -7
  104. package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
  105. package/lib/module/ui/screens/AccountOverviewScreen.js +8 -6
  106. package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
  107. package/lib/module/ui/screens/AccountSettingsScreen.js +5 -4
  108. package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
  109. package/lib/module/ui/screens/AccountSwitcherScreen.js +240 -3
  110. package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
  111. package/lib/module/ui/screens/AccountVerificationScreen.js +3 -2
  112. package/lib/module/ui/screens/AccountVerificationScreen.js.map +1 -1
  113. package/lib/module/ui/screens/CreateManagedAccountScreen.js +342 -0
  114. package/lib/module/ui/screens/CreateManagedAccountScreen.js.map +1 -0
  115. package/lib/module/ui/screens/EditProfileFieldScreen.js +3 -2
  116. package/lib/module/ui/screens/EditProfileFieldScreen.js.map +1 -1
  117. package/lib/module/ui/screens/FAQScreen.js +3 -2
  118. package/lib/module/ui/screens/FAQScreen.js.map +1 -1
  119. package/lib/module/ui/screens/FeedbackScreen.js +3 -2
  120. package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
  121. package/lib/module/ui/screens/HelpSupportScreen.js +3 -2
  122. package/lib/module/ui/screens/HelpSupportScreen.js.map +1 -1
  123. package/lib/module/ui/screens/HistoryViewScreen.js +3 -2
  124. package/lib/module/ui/screens/HistoryViewScreen.js.map +1 -1
  125. package/lib/module/ui/screens/LanguageSelectorScreen.js +3 -2
  126. package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
  127. package/lib/module/ui/screens/LearnMoreUsernamesScreen.js +3 -2
  128. package/lib/module/ui/screens/LearnMoreUsernamesScreen.js.map +1 -1
  129. package/lib/module/ui/screens/LegalDocumentsScreen.js +6 -4
  130. package/lib/module/ui/screens/LegalDocumentsScreen.js.map +1 -1
  131. package/lib/module/ui/screens/OxyAuthScreen.js +12 -8
  132. package/lib/module/ui/screens/OxyAuthScreen.js.map +1 -1
  133. package/lib/module/ui/screens/PaymentGatewayScreen.js +3 -2
  134. package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -1
  135. package/lib/module/ui/screens/PrivacySettingsScreen.js +6 -4
  136. package/lib/module/ui/screens/PrivacySettingsScreen.js.map +1 -1
  137. package/lib/module/ui/screens/ProfileScreen.js +8 -6
  138. package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
  139. package/lib/module/ui/screens/SavesCollectionsScreen.js +3 -2
  140. package/lib/module/ui/screens/SavesCollectionsScreen.js.map +1 -1
  141. package/lib/module/ui/screens/SearchSettingsScreen.js +6 -4
  142. package/lib/module/ui/screens/SearchSettingsScreen.js.map +1 -1
  143. package/lib/module/ui/screens/SessionManagementScreen.js +6 -4
  144. package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
  145. package/lib/module/ui/screens/UserLinksScreen.js +3 -2
  146. package/lib/module/ui/screens/UserLinksScreen.js.map +1 -1
  147. package/lib/module/ui/screens/UserListScreen.js +9 -6
  148. package/lib/module/ui/screens/UserListScreen.js.map +1 -1
  149. package/lib/module/ui/screens/karma/KarmaAboutScreen.js +3 -2
  150. package/lib/module/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
  151. package/lib/module/ui/screens/karma/KarmaCenterScreen.js +8 -6
  152. package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
  153. package/lib/module/ui/screens/karma/KarmaFAQScreen.js +3 -2
  154. package/lib/module/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
  155. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +3 -2
  156. package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
  157. package/lib/module/ui/screens/karma/KarmaRewardsScreen.js +6 -4
  158. package/lib/module/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
  159. package/lib/module/ui/screens/karma/KarmaRulesScreen.js +3 -2
  160. package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
  161. package/lib/typescript/commonjs/index.d.ts +1 -0
  162. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  163. package/lib/typescript/commonjs/ui/components/ActingAsBanner.d.ts +4 -0
  164. package/lib/typescript/commonjs/ui/components/ActingAsBanner.d.ts.map +1 -0
  165. package/lib/typescript/commonjs/ui/components/BottomSheet.d.ts.map +1 -1
  166. package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
  167. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts +9 -8
  168. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
  169. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  170. package/lib/typescript/commonjs/ui/navigation/routes.d.ts +1 -1
  171. package/lib/typescript/commonjs/ui/navigation/routes.d.ts.map +1 -1
  172. package/lib/typescript/commonjs/ui/screens/AccountCenterScreen.d.ts.map +1 -1
  173. package/lib/typescript/commonjs/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
  174. package/lib/typescript/commonjs/ui/screens/CreateManagedAccountScreen.d.ts +5 -0
  175. package/lib/typescript/commonjs/ui/screens/CreateManagedAccountScreen.d.ts.map +1 -0
  176. package/lib/typescript/commonjs/ui/screens/EditProfileFieldScreen.d.ts.map +1 -1
  177. package/lib/typescript/commonjs/ui/screens/FeedbackScreen.d.ts.map +1 -1
  178. package/lib/typescript/commonjs/ui/types/navigation.d.ts +3 -0
  179. package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
  180. package/lib/typescript/module/index.d.ts +1 -0
  181. package/lib/typescript/module/index.d.ts.map +1 -1
  182. package/lib/typescript/module/ui/components/ActingAsBanner.d.ts +4 -0
  183. package/lib/typescript/module/ui/components/ActingAsBanner.d.ts.map +1 -0
  184. package/lib/typescript/module/ui/components/BottomSheet.d.ts.map +1 -1
  185. package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
  186. package/lib/typescript/module/ui/context/OxyContext.d.ts +9 -8
  187. package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
  188. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  189. package/lib/typescript/module/ui/navigation/routes.d.ts +1 -1
  190. package/lib/typescript/module/ui/navigation/routes.d.ts.map +1 -1
  191. package/lib/typescript/module/ui/screens/AccountCenterScreen.d.ts.map +1 -1
  192. package/lib/typescript/module/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
  193. package/lib/typescript/module/ui/screens/CreateManagedAccountScreen.d.ts +5 -0
  194. package/lib/typescript/module/ui/screens/CreateManagedAccountScreen.d.ts.map +1 -0
  195. package/lib/typescript/module/ui/screens/EditProfileFieldScreen.d.ts.map +1 -1
  196. package/lib/typescript/module/ui/screens/FeedbackScreen.d.ts.map +1 -1
  197. package/lib/typescript/module/ui/types/navigation.d.ts +3 -0
  198. package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
  199. package/package.json +1 -2
  200. package/src/index.ts +3 -0
  201. package/src/ui/components/ActingAsBanner.tsx +135 -0
  202. package/src/ui/components/BottomSheet.tsx +3 -2
  203. package/src/ui/components/BottomSheetRouter.tsx +2 -2
  204. package/src/ui/components/OxyProvider.tsx +55 -50
  205. package/src/ui/components/fileManagement/FileDetailsModal.tsx +1 -1
  206. package/src/ui/components/fileManagement/UploadPreview.tsx +1 -1
  207. package/src/ui/components/modals/DeleteAccountModal.tsx +1 -1
  208. package/src/ui/context/OxyContext.tsx +106 -12
  209. package/src/ui/context/hooks/useAuthOperations.ts +2 -1
  210. package/src/ui/navigation/routes.ts +3 -1
  211. package/src/ui/screens/AccountCenterScreen.tsx +24 -4
  212. package/src/ui/screens/AccountOverviewScreen.tsx +3 -3
  213. package/src/ui/screens/AccountSettingsScreen.tsx +2 -2
  214. package/src/ui/screens/AccountSwitcherScreen.tsx +212 -1
  215. package/src/ui/screens/AccountVerificationScreen.tsx +1 -1
  216. package/src/ui/screens/CreateManagedAccountScreen.tsx +338 -0
  217. package/src/ui/screens/EditProfileFieldScreen.tsx +1 -2
  218. package/src/ui/screens/FAQScreen.tsx +1 -1
  219. package/src/ui/screens/FeedbackScreen.tsx +1 -2
  220. package/src/ui/screens/HelpSupportScreen.tsx +1 -1
  221. package/src/ui/screens/HistoryViewScreen.tsx +1 -1
  222. package/src/ui/screens/LanguageSelectorScreen.tsx +1 -1
  223. package/src/ui/screens/LearnMoreUsernamesScreen.tsx +1 -1
  224. package/src/ui/screens/LegalDocumentsScreen.tsx +2 -2
  225. package/src/ui/screens/OxyAuthScreen.tsx +5 -5
  226. package/src/ui/screens/PaymentGatewayScreen.tsx +1 -1
  227. package/src/ui/screens/PrivacySettingsScreen.tsx +2 -2
  228. package/src/ui/screens/ProfileScreen.tsx +3 -3
  229. package/src/ui/screens/SavesCollectionsScreen.tsx +1 -1
  230. package/src/ui/screens/SearchSettingsScreen.tsx +2 -2
  231. package/src/ui/screens/SessionManagementScreen.tsx +2 -2
  232. package/src/ui/screens/UserLinksScreen.tsx +1 -1
  233. package/src/ui/screens/UserListScreen.tsx +3 -3
  234. package/src/ui/screens/karma/KarmaAboutScreen.tsx +1 -1
  235. package/src/ui/screens/karma/KarmaCenterScreen.tsx +3 -3
  236. package/src/ui/screens/karma/KarmaFAQScreen.tsx +1 -1
  237. package/src/ui/screens/karma/KarmaLeaderboardScreen.tsx +1 -1
  238. package/src/ui/screens/karma/KarmaRewardsScreen.tsx +2 -2
  239. package/src/ui/screens/karma/KarmaRulesScreen.tsx +1 -1
  240. package/src/ui/types/navigation.ts +3 -0
@@ -1,9 +1,9 @@
1
- import type React from 'react';
2
- import { useEffect, useRef, useState, type FC } from 'react';
1
+ import { lazy, Suspense, useEffect, useRef, useState, type ComponentType, type FC, type ReactNode } from 'react';
3
2
  import { AppState, Platform } from 'react-native';
4
3
  import type { OxyProviderProps } from '../types/navigation';
5
4
  import { OxyContextProvider, type OxyContextProviderProps } from '../context/OxyContext';
6
5
  import { QueryClientProvider, focusManager, onlineManager } from '@tanstack/react-query';
6
+ import { BloomThemeProvider } from '@oxyhq/bloom';
7
7
  import { setupFonts } from './FontLoader';
8
8
  import { Toaster } from '../../lib/sonner';
9
9
  import { createQueryClient } from '../hooks/queryClient';
@@ -15,39 +15,27 @@ setupFonts();
15
15
  // Detect if running on web
16
16
  const isWeb = Platform.OS === 'web';
17
17
 
18
- // Conditionally import components
19
- let KeyboardProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => <>{children}</>;
20
- let BottomSheetRouter: React.ComponentType | null = null;
21
- let SignInModal: React.ComponentType | null = null;
22
-
23
- // KeyboardProvider only on native
24
- if (!isWeb) {
25
- try {
26
- KeyboardProvider = require('react-native-keyboard-controller').KeyboardProvider;
27
- } catch {
28
- // KeyboardProvider not available
29
- }
30
- }
31
-
32
- // BottomSheetRouter works on all platforms
33
- try {
34
- BottomSheetRouter = require('./BottomSheetRouter').default;
35
- } catch (error) {
36
- if (__DEV__) {
37
- console.error('[OxyProvider] Failed to load BottomSheetRouter:', error);
38
- }
39
- }
40
-
41
- // SignInModal works on all platforms
42
- try {
43
- SignInModal = require('./SignInModal').default;
44
- } catch {
45
- // SignInModal not available
46
- }
47
-
48
- if (__DEV__ && !BottomSheetRouter) {
49
- console.warn('[OxyProvider] BottomSheetRouter is null — bottom sheet navigation will not work. Check that BottomSheetRouter.tsx and its dependencies are importable.');
50
- }
18
+ // Lazy-load optional components (avoids require() for ESM compatibility).
19
+ // The .then() extracts + casts the default export so that `lazy()` sees
20
+ // `Promise<{ default: ComponentType }>` instead of the full module namespace.
21
+ const LazyBottomSheetRouter = lazy((): Promise<{ default: ComponentType }> =>
22
+ import('./BottomSheetRouter.js').then(
23
+ (mod) => ({ default: mod.default as unknown as ComponentType }),
24
+ (error) => {
25
+ if (__DEV__) {
26
+ console.error('[OxyProvider] Failed to load BottomSheetRouter:', error);
27
+ }
28
+ return { default: (() => null) as FC };
29
+ },
30
+ ),
31
+ );
32
+
33
+ const LazySignInModal = lazy((): Promise<{ default: ComponentType }> =>
34
+ import('./SignInModal.js').then(
35
+ (mod) => ({ default: mod.default as unknown as ComponentType }),
36
+ () => ({ default: (() => null) as FC }),
37
+ ),
38
+ );
51
39
 
52
40
  /**
53
41
  * OxyProvider - Universal provider for Expo apps (native + web)
@@ -91,8 +79,21 @@ const OxyProvider: FC<OxyProviderProps> = ({
91
79
  authWebUrl,
92
80
  authRedirectUri,
93
81
  queryClient: providedQueryClient,
82
+ themeMode = 'system',
83
+ colorPreset,
94
84
  }) => {
95
85
 
86
+ // Dynamic KeyboardProvider for native (avoids require() for ESM compatibility)
87
+ const [KBProvider, setKBProvider] = useState<FC<{ children: ReactNode }> | null>(null);
88
+ useEffect(() => {
89
+ if (isWeb) return;
90
+ const moduleName = 'react-native-keyboard-controller';
91
+ import(/* webpackIgnore: true */ moduleName)
92
+ .then((mod) => setKBProvider(() => mod.KeyboardProvider))
93
+ .catch(() => { /* KeyboardProvider not available */ });
94
+ }, []);
95
+ const KeyboardWrapper: FC<{ children: ReactNode }> = KBProvider ?? (({ children }) => <>{children}</>);
96
+
96
97
  // Simple storage initialization for query persistence
97
98
  const storageRef = useRef<StorageInterface | null>(null);
98
99
  const queryClientRef = useRef<ReturnType<typeof createQueryClient> | null>(null);
@@ -218,26 +219,30 @@ const OxyProvider: FC<OxyProviderProps> = ({
218
219
  // Core content: QueryClient + OxyContext + UI overlays
219
220
  const coreContent = (
220
221
  <QueryClientProvider client={queryClient}>
221
- <OxyContextProvider
222
- oxyServices={oxyServices as OxyContextProviderProps['oxyServices']}
223
- baseURL={baseURL}
224
- authWebUrl={authWebUrl}
225
- authRedirectUri={authRedirectUri}
226
- storageKeyPrefix={storageKeyPrefix}
227
- onAuthStateChange={onAuthStateChange as OxyContextProviderProps['onAuthStateChange']}
228
- >
229
- {children}
230
- {BottomSheetRouter && <BottomSheetRouter />}
231
- {SignInModal && <SignInModal />}
232
- <Toaster />
233
- </OxyContextProvider>
222
+ <BloomThemeProvider mode={themeMode} colorPreset={colorPreset}>
223
+ <OxyContextProvider
224
+ oxyServices={oxyServices as OxyContextProviderProps['oxyServices']}
225
+ baseURL={baseURL}
226
+ authWebUrl={authWebUrl}
227
+ authRedirectUri={authRedirectUri}
228
+ storageKeyPrefix={storageKeyPrefix}
229
+ onAuthStateChange={onAuthStateChange as OxyContextProviderProps['onAuthStateChange']}
230
+ >
231
+ {children}
232
+ <Suspense fallback={null}>
233
+ <LazyBottomSheetRouter />
234
+ <LazySignInModal />
235
+ </Suspense>
236
+ <Toaster />
237
+ </OxyContextProvider>
238
+ </BloomThemeProvider>
234
239
  </QueryClientProvider>
235
240
  );
236
241
 
237
242
  return (
238
- <KeyboardProvider>
243
+ <KeyboardWrapper>
239
244
  {coreContent}
240
- </KeyboardProvider>
245
+ </KeyboardWrapper>
241
246
  );
242
247
  };
243
248
 
@@ -36,7 +36,7 @@ export const FileDetailsModal: React.FC<FileDetailsModalProps> = ({
36
36
  presentationStyle="pageSheet"
37
37
  onRequestClose={onClose}
38
38
  >
39
- <View className="bg-background" style={fileManagementStyles.modalContainer}>
39
+ <View style={[fileManagementStyles.modalContainer, { backgroundColor: colors.background }]}>
40
40
  <View className="border-b border-border" style={fileManagementStyles.modalHeader}>
41
41
  <TouchableOpacity
42
42
  style={fileManagementStyles.modalCloseButton}
@@ -40,7 +40,7 @@ const UploadPreviewContent: React.FC<{
40
40
  const totalSize = pendingFiles.reduce((sum, f) => sum + f.size, 0);
41
41
 
42
42
  return (
43
- <View className="bg-background" style={fileManagementStyles.uploadPreviewContainer}>
43
+ <View style={[fileManagementStyles.uploadPreviewContainer, { backgroundColor: colors.background }]}>
44
44
  <View className="border-b border-border" style={fileManagementStyles.uploadPreviewHeader}>
45
45
  <Text className="text-foreground" style={fileManagementStyles.uploadPreviewTitle}>
46
46
  Review Files ({pendingFiles.length})
@@ -78,7 +78,7 @@ const DeleteAccountModal: React.FC<DeleteAccountModalProps> = ({
78
78
  activeOpacity={1}
79
79
  onPress={handleClose}
80
80
  />
81
- <View className="bg-background" style={styles.modal}>
81
+ <View style={[styles.modal, { backgroundColor: theme.colors.background }]}>
82
82
  <View style={styles.header}>
83
83
  <OxyIcon name="alert" size={32} color={theme.colors.error} />
84
84
  <Text className="text-destructive" style={styles.title}>
@@ -10,7 +10,8 @@ import {
10
10
  type ReactNode,
11
11
  } from 'react';
12
12
  import { OxyServices } from '@oxyhq/core';
13
- import type { User, ApiError } from '@oxyhq/core';
13
+ import type { User, ApiError, SessionLoginResponse } from '@oxyhq/core';
14
+ import type { ManagedAccount, CreateManagedAccountInput } from '@oxyhq/core';
14
15
  import { KeyManager } from '@oxyhq/core';
15
16
  import type { ClientSession } from '@oxyhq/core';
16
17
  import { toast } from '../../lib/sonner';
@@ -58,13 +59,7 @@ export interface OxyContextState {
58
59
  * Handle session from popup authentication
59
60
  * Updates auth state, persists session to storage
60
61
  */
61
- handlePopupSession: (session: {
62
- sessionId: string;
63
- accessToken?: string;
64
- expiresAt?: string;
65
- user: User;
66
- deviceId?: string;
67
- }) => Promise<void>;
62
+ handlePopupSession: (session: SessionLoginResponse) => Promise<void>;
68
63
 
69
64
  // Session management
70
65
  logout: (targetSessionId?: string) => Promise<void>;
@@ -86,10 +81,18 @@ export interface OxyContextState {
86
81
  updateDeviceName: (deviceName: string) => Promise<void>;
87
82
  clearSessionState: () => Promise<void>;
88
83
  clearAllAccountData: () => Promise<void>;
84
+ storageKeyPrefix: string;
89
85
  oxyServices: OxyServices;
90
86
  useFollow?: UseFollowHook;
91
87
  showBottomSheet?: (screenOrConfig: RouteName | { screen: RouteName; props?: Record<string, unknown> }) => void;
92
88
  openAvatarPicker: () => void;
89
+
90
+ // Managed accounts (sub-accounts / managed identities)
91
+ actingAs: string | null;
92
+ managedAccounts: ManagedAccount[];
93
+ setActingAs: (userId: string | null) => void;
94
+ refreshManagedAccounts: () => Promise<void>;
95
+ createManagedAccount: (data: CreateManagedAccountInput) => Promise<ManagedAccount>;
93
96
  }
94
97
 
95
98
  const OxyContext = createContext<OxyContextState | null>(null);
@@ -450,7 +453,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
450
453
 
451
454
  // Web SSO: Automatically check for cross-domain session on web platforms
452
455
  // Also used for popup auth - updates all state and persists session
453
- const handleWebSSOSession = useCallback(async (session: any) => {
456
+ const handleWebSSOSession = useCallback(async (session: SessionLoginResponse) => {
454
457
  if (!session?.user || !session?.sessionId) {
455
458
  if (__DEV__) {
456
459
  loggerUtil.warn('handleWebSSOSession: Invalid session', { component: 'OxyContext' });
@@ -476,8 +479,19 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
476
479
 
477
480
  updateSessions([clientSession], { merge: true });
478
481
  setActiveSessionId(session.sessionId);
479
- loginSuccess(session.user);
480
- onAuthStateChange?.(session.user);
482
+
483
+ // Fetch the full user profile now that we have a valid access token.
484
+ // The session only carries MinimalUserData; the store and callbacks expect a full User.
485
+ let fullUser: User;
486
+ try {
487
+ fullUser = await oxyServices.getCurrentUser();
488
+ } catch {
489
+ // If the profile fetch fails, fall back to the minimal data from the session
490
+ // so the user is still logged in (the store accepts User, but the shapes overlap at runtime).
491
+ fullUser = session.user as unknown as User;
492
+ }
493
+ loginSuccess(fullUser);
494
+ onAuthStateChange?.(fullUser);
481
495
 
482
496
  // Persist to storage
483
497
  if (storage) {
@@ -567,7 +581,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
567
581
  pendingIdPCleanupRef.current?.();
568
582
  pendingIdPCleanupRef.current = null;
569
583
  };
570
- }, [user, initialized, clearSessionState]);
584
+ }, [user, initialized, clearSessionState, authWebUrl]);
571
585
 
572
586
  const activeSession = activeSessionId
573
587
  ? sessions.find((session) => session.sessionId === activeSessionId)
@@ -639,6 +653,68 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
639
653
  showBottomSheet: showBottomSheetForContext,
640
654
  });
641
655
 
656
+ // --- Managed accounts state ---
657
+ const [actingAs, setActingAsState] = useState<string | null>(null);
658
+ const [managedAccounts, setManagedAccounts] = useState<ManagedAccount[]>([]);
659
+
660
+ // Restore actingAs from storage on startup
661
+ useEffect(() => {
662
+ if (!storage || !initialized) return;
663
+ let mounted = true;
664
+ (async () => {
665
+ try {
666
+ const stored = await storage.getItem(`${storageKeyPrefix}_acting_as`);
667
+ if (mounted && stored) {
668
+ setActingAsState(stored);
669
+ oxyServices.setActingAs(stored);
670
+ }
671
+ } catch (err) {
672
+ if (__DEV__) {
673
+ loggerUtil.debug('Failed to restore actingAs from storage', { component: 'OxyContext' }, err as unknown);
674
+ }
675
+ }
676
+ })();
677
+ return () => { mounted = false; };
678
+ }, [storage, initialized, storageKeyPrefix, oxyServices]);
679
+
680
+ // Load managed accounts when authenticated
681
+ const refreshManagedAccounts = useCallback(async (): Promise<void> => {
682
+ if (!isAuthenticated) return;
683
+ try {
684
+ const accounts = await oxyServices.getManagedAccounts();
685
+ setManagedAccounts(accounts);
686
+ } catch (err) {
687
+ if (__DEV__) {
688
+ loggerUtil.debug('Failed to load managed accounts', { component: 'OxyContext' }, err as unknown);
689
+ }
690
+ }
691
+ }, [isAuthenticated, oxyServices]);
692
+
693
+ useEffect(() => {
694
+ if (isAuthenticated && initialized && tokenReady) {
695
+ refreshManagedAccounts();
696
+ }
697
+ }, [isAuthenticated, initialized, tokenReady, refreshManagedAccounts]);
698
+
699
+ const setActingAs = useCallback((userId: string | null) => {
700
+ oxyServices.setActingAs(userId);
701
+ setActingAsState(userId);
702
+ // Persist to storage
703
+ if (storage) {
704
+ if (userId) {
705
+ storage.setItem(`${storageKeyPrefix}_acting_as`, userId).catch(() => {});
706
+ } else {
707
+ storage.removeItem(`${storageKeyPrefix}_acting_as`).catch(() => {});
708
+ }
709
+ }
710
+ }, [oxyServices, storage, storageKeyPrefix]);
711
+
712
+ const createManagedAccountFn = useCallback(async (data: CreateManagedAccountInput): Promise<ManagedAccount> => {
713
+ const account = await oxyServices.createManagedAccount(data);
714
+ await refreshManagedAccounts();
715
+ return account;
716
+ }, [oxyServices, refreshManagedAccounts]);
717
+
642
718
  const contextValue: OxyContextState = useMemo(() => ({
643
719
  user,
644
720
  sessions,
@@ -667,10 +743,16 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
667
743
  updateDeviceName,
668
744
  clearSessionState,
669
745
  clearAllAccountData,
746
+ storageKeyPrefix,
670
747
  oxyServices,
671
748
  useFollow: useFollowHook,
672
749
  showBottomSheet: showBottomSheetForContext,
673
750
  openAvatarPicker,
751
+ actingAs,
752
+ managedAccounts,
753
+ setActingAs,
754
+ refreshManagedAccounts,
755
+ createManagedAccount: createManagedAccountFn,
674
756
  }), [
675
757
  activeSessionId,
676
758
  signIn,
@@ -689,6 +771,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
689
771
  logoutAll,
690
772
  logoutAllDeviceSessions,
691
773
  oxyServices,
774
+ storageKeyPrefix,
692
775
  refreshSessionsWithUser,
693
776
  sessions,
694
777
  setLanguage,
@@ -701,6 +784,11 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
701
784
  user,
702
785
  showBottomSheetForContext,
703
786
  openAvatarPicker,
787
+ actingAs,
788
+ managedAccounts,
789
+ setActingAs,
790
+ refreshManagedAccounts,
791
+ createManagedAccountFn,
704
792
  ]);
705
793
 
706
794
  return (
@@ -742,8 +830,14 @@ const LOADING_STATE: OxyContextState = {
742
830
  updateDeviceName: noop,
743
831
  clearSessionState: noop,
744
832
  clearAllAccountData: noop,
833
+ storageKeyPrefix: 'oxy_session',
745
834
  oxyServices: null as any,
746
835
  openAvatarPicker: () => {},
836
+ actingAs: null,
837
+ managedAccounts: [],
838
+ setActingAs: () => {},
839
+ refreshManagedAccounts: noop,
840
+ createManagedAccount: noop,
747
841
  };
748
842
 
749
843
  export const useOxy = (): OxyContextState => {
@@ -8,7 +8,6 @@ import { handleAuthError, isInvalidSessionError } from '../../utils/errorHandler
8
8
  import type { StorageInterface } from '../../utils/storageHelpers';
9
9
  import type { OxyServices } from '@oxyhq/core';
10
10
  import { SignatureService } from '@oxyhq/core';
11
- import * as Crypto from 'expo-crypto';
12
11
 
13
12
  /** Type guard for error objects with optional code and status properties */
14
13
  function isErrorWithCodeOrStatus(error: unknown): error is { code?: string; status?: number; message?: string } {
@@ -133,6 +132,8 @@ export const useAuthOperations = ({
133
132
  }
134
133
 
135
134
  // Generate a local session ID using cryptographically secure randomness
135
+ const cryptoModule = 'expo-crypto';
136
+ const Crypto = await import(/* webpackIgnore: true */ cryptoModule);
136
137
  const localSessionId = `offline_${Crypto.getRandomUUID()}`;
137
138
  const localDeviceId = `device_${Crypto.getRandomUUID()}`;
138
139
  const expiresAt = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(); // 7 days
@@ -39,7 +39,8 @@ export type RouteName =
39
39
  | 'AboutKarma'
40
40
  | 'KarmaFAQ'
41
41
  | 'FollowersList' // List of user's followers
42
- | 'FollowingList'; // List of users being followed
42
+ | 'FollowingList' // List of users being followed
43
+ | 'CreateManagedAccount'; // Create a new managed sub-account
43
44
 
44
45
  // Lazy screen loaders - functions that return screen components on-demand
45
46
  // This breaks the require cycle by deferring imports until screens are actually needed
@@ -80,6 +81,7 @@ const screenLoaders: Record<RouteName, () => ComponentType<BaseScreenProps>> = {
80
81
  // User list screens (followers/following)
81
82
  FollowersList: () => require('../screens/FollowersListScreen').default,
82
83
  FollowingList: () => require('../screens/FollowingListScreen').default,
84
+ CreateManagedAccount: () => require('../screens/CreateManagedAccountScreen').default,
83
85
  };
84
86
 
85
87
  // Cache loaded components to avoid re-requiring
@@ -32,7 +32,7 @@ const AccountCenterScreen: React.FC<BaseScreenProps> = ({
32
32
  navigate,
33
33
  }) => {
34
34
  // Use useOxy() hook for OxyContext values
35
- const { user, logout, isLoading, sessions, isAuthenticated } = useOxy();
35
+ const { user, logout, isLoading, sessions, isAuthenticated, managedAccounts } = useOxy();
36
36
  const { t } = useI18n();
37
37
  const bloomTheme = useTheme();
38
38
  const colorScheme = useColorScheme();
@@ -65,7 +65,7 @@ const AccountCenterScreen: React.FC<BaseScreenProps> = ({
65
65
 
66
66
  if (!isAuthenticated) {
67
67
  return (
68
- <View style={styles.container} className="bg-background">
68
+ <View style={[styles.container, { backgroundColor: bloomTheme.colors.background }]}>
69
69
  <Text style={styles.message} className="text-foreground">{t('common.status.notSignedIn') || 'Not signed in'}</Text>
70
70
  </View>
71
71
  );
@@ -73,14 +73,14 @@ const AccountCenterScreen: React.FC<BaseScreenProps> = ({
73
73
 
74
74
  if (isLoading) {
75
75
  return (
76
- <View style={[styles.container, { justifyContent: 'center' }]} className="bg-background">
76
+ <View style={[styles.container, { justifyContent: 'center', backgroundColor: bloomTheme.colors.background }]}>
77
77
  <ActivityIndicator size="large" color={bloomTheme.colors.primary} />
78
78
  </View>
79
79
  );
80
80
  }
81
81
 
82
82
  return (
83
- <View style={styles.container} className="bg-background">
83
+ <View style={[styles.container, { backgroundColor: bloomTheme.colors.background }]}>
84
84
  {/* Header with user profile */}
85
85
  {user && (
86
86
  <ProfileCard
@@ -181,6 +181,26 @@ const AccountCenterScreen: React.FC<BaseScreenProps> = ({
181
181
  </SettingsListGroup>
182
182
  )}
183
183
 
184
+ {/* Managed Accounts */}
185
+ {isAuthenticated && (
186
+ <SettingsListGroup title="Managed Accounts">
187
+ <SettingsListItem
188
+ icon={<SettingsIcon name="account-switch" color={colors.iconStorage} />}
189
+ title="Manage Identities"
190
+ description={managedAccounts.length > 0
191
+ ? `${managedAccounts.length} managed ${managedAccounts.length === 1 ? 'identity' : 'identities'}`
192
+ : 'Sub-accounts you control'}
193
+ onPress={() => navigate?.('AccountSwitcher')}
194
+ />
195
+ <SettingsListItem
196
+ icon={<SettingsIcon name="account-plus" color={colors.iconPersonalInfo} />}
197
+ title="Create New Identity"
198
+ description="Add a managed sub-account"
199
+ onPress={() => navigate?.('CreateManagedAccount')}
200
+ />
201
+ </SettingsListGroup>
202
+ )}
203
+
184
204
  {/* Additional Options */}
185
205
  <SettingsListGroup title={t('accountCenter.sections.moreOptions') || 'More Options'}>
186
206
  {Platform.OS !== 'web' ? (
@@ -320,7 +320,7 @@ const AccountOverviewScreen: React.FC<BaseScreenProps> = ({
320
320
 
321
321
  if (!isAuthenticated) {
322
322
  return (
323
- <View style={styles.container} className="bg-background">
323
+ <View style={[styles.container, { backgroundColor: bloomTheme.colors.background }]}>
324
324
  <Text style={styles.message} className="text-foreground">{t('common.status.notSignedIn')}</Text>
325
325
  </View>
326
326
  );
@@ -328,7 +328,7 @@ const AccountOverviewScreen: React.FC<BaseScreenProps> = ({
328
328
 
329
329
  if (isLoading) {
330
330
  return (
331
- <View style={[styles.container, { justifyContent: 'center' }]} className="bg-background">
331
+ <View style={[styles.container, { justifyContent: 'center', backgroundColor: bloomTheme.colors.background }]}>
332
332
  <ActivityIndicator size="large" color={themeColors.primaryColor} />
333
333
  </View>
334
334
  );
@@ -336,7 +336,7 @@ const AccountOverviewScreen: React.FC<BaseScreenProps> = ({
336
336
 
337
337
 
338
338
  return (
339
- <View style={styles.container} className="bg-background">
339
+ <View style={[styles.container, { backgroundColor: bloomTheme.colors.background }]}>
340
340
  <ScrollView
341
341
  style={styles.content}
342
342
  contentContainerStyle={styles.scrollContent}
@@ -316,14 +316,14 @@ const AccountSettingsScreen: React.FC<BaseScreenProps & { initialField?: string;
316
316
 
317
317
  if (userLoading || !isAuthenticated) {
318
318
  return (
319
- <View style={[styles.container, { justifyContent: 'center' }]} className="bg-background">
319
+ <View style={[styles.container, { justifyContent: 'center', backgroundColor: bloomTheme.colors.background }]}>
320
320
  <ActivityIndicator size="large" color={bloomTheme.colors.primary} />
321
321
  </View>
322
322
  );
323
323
  }
324
324
 
325
325
  return (
326
- <View style={styles.container} className="bg-background">
326
+ <View style={[styles.container, { backgroundColor: bloomTheme.colors.background }]}>
327
327
  <ScrollView
328
328
  ref={scrollViewRef}
329
329
  style={styles.content}