@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.
- package/lib/commonjs/index.js +9 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/ui/components/ActingAsBanner.js +143 -0
- package/lib/commonjs/ui/components/ActingAsBanner.js.map +1 -0
- package/lib/commonjs/ui/components/BottomSheet.js +3 -3
- package/lib/commonjs/ui/components/BottomSheet.js.map +1 -1
- package/lib/commonjs/ui/components/BottomSheetRouter.js +4 -3
- package/lib/commonjs/ui/components/BottomSheetRouter.js.map +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js +48 -43
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/fileManagement/FileDetailsModal.js +3 -2
- package/lib/commonjs/ui/components/fileManagement/FileDetailsModal.js.map +1 -1
- package/lib/commonjs/ui/components/fileManagement/UploadPreview.js +3 -2
- package/lib/commonjs/ui/components/fileManagement/UploadPreview.js.map +1 -1
- package/lib/commonjs/ui/components/modals/DeleteAccountModal.js +3 -2
- package/lib/commonjs/ui/components/modals/DeleteAccountModal.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +94 -6
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js +2 -1
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/commonjs/ui/navigation/routes.js +3 -2
- package/lib/commonjs/ui/navigation/routes.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountCenterScreen.js +29 -7
- package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js +8 -6
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +5 -4
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +240 -3
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountVerificationScreen.js +3 -2
- package/lib/commonjs/ui/screens/AccountVerificationScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/CreateManagedAccountScreen.js +346 -0
- package/lib/commonjs/ui/screens/CreateManagedAccountScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/EditProfileFieldScreen.js +3 -2
- package/lib/commonjs/ui/screens/EditProfileFieldScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FAQScreen.js +3 -2
- package/lib/commonjs/ui/screens/FAQScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FeedbackScreen.js +3 -2
- package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/HelpSupportScreen.js +3 -2
- package/lib/commonjs/ui/screens/HelpSupportScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/HistoryViewScreen.js +3 -2
- package/lib/commonjs/ui/screens/HistoryViewScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +3 -2
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/LearnMoreUsernamesScreen.js +3 -2
- package/lib/commonjs/ui/screens/LearnMoreUsernamesScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/LegalDocumentsScreen.js +6 -4
- package/lib/commonjs/ui/screens/LegalDocumentsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/OxyAuthScreen.js +12 -8
- package/lib/commonjs/ui/screens/OxyAuthScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +3 -2
- package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PrivacySettingsScreen.js +6 -4
- package/lib/commonjs/ui/screens/PrivacySettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ProfileScreen.js +8 -6
- package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SavesCollectionsScreen.js +3 -2
- package/lib/commonjs/ui/screens/SavesCollectionsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SearchSettingsScreen.js +6 -4
- package/lib/commonjs/ui/screens/SearchSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SessionManagementScreen.js +6 -4
- package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/UserLinksScreen.js +3 -2
- package/lib/commonjs/ui/screens/UserLinksScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/UserListScreen.js +9 -6
- package/lib/commonjs/ui/screens/UserListScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js +3 -2
- package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +8 -6
- package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js +3 -2
- package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +3 -2
- package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js +6 -4
- package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +3 -2
- package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
- package/lib/module/index.js +3 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/ui/components/ActingAsBanner.js +140 -0
- package/lib/module/ui/components/ActingAsBanner.js.map +1 -0
- package/lib/module/ui/components/BottomSheet.js +3 -3
- package/lib/module/ui/components/BottomSheet.js.map +1 -1
- package/lib/module/ui/components/BottomSheetRouter.js +4 -3
- package/lib/module/ui/components/BottomSheetRouter.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +49 -44
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/fileManagement/FileDetailsModal.js +3 -2
- package/lib/module/ui/components/fileManagement/FileDetailsModal.js.map +1 -1
- package/lib/module/ui/components/fileManagement/UploadPreview.js +3 -2
- package/lib/module/ui/components/fileManagement/UploadPreview.js.map +1 -1
- package/lib/module/ui/components/modals/DeleteAccountModal.js +3 -2
- package/lib/module/ui/components/modals/DeleteAccountModal.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +94 -6
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/context/hooks/useAuthOperations.js +2 -1
- package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/module/ui/navigation/routes.js +3 -2
- package/lib/module/ui/navigation/routes.js.map +1 -1
- package/lib/module/ui/screens/AccountCenterScreen.js +29 -7
- package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountOverviewScreen.js +8 -6
- package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js +5 -4
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSwitcherScreen.js +240 -3
- package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountVerificationScreen.js +3 -2
- package/lib/module/ui/screens/AccountVerificationScreen.js.map +1 -1
- package/lib/module/ui/screens/CreateManagedAccountScreen.js +342 -0
- package/lib/module/ui/screens/CreateManagedAccountScreen.js.map +1 -0
- package/lib/module/ui/screens/EditProfileFieldScreen.js +3 -2
- package/lib/module/ui/screens/EditProfileFieldScreen.js.map +1 -1
- package/lib/module/ui/screens/FAQScreen.js +3 -2
- package/lib/module/ui/screens/FAQScreen.js.map +1 -1
- package/lib/module/ui/screens/FeedbackScreen.js +3 -2
- package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/module/ui/screens/HelpSupportScreen.js +3 -2
- package/lib/module/ui/screens/HelpSupportScreen.js.map +1 -1
- package/lib/module/ui/screens/HistoryViewScreen.js +3 -2
- package/lib/module/ui/screens/HistoryViewScreen.js.map +1 -1
- package/lib/module/ui/screens/LanguageSelectorScreen.js +3 -2
- package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
- package/lib/module/ui/screens/LearnMoreUsernamesScreen.js +3 -2
- package/lib/module/ui/screens/LearnMoreUsernamesScreen.js.map +1 -1
- package/lib/module/ui/screens/LegalDocumentsScreen.js +6 -4
- package/lib/module/ui/screens/LegalDocumentsScreen.js.map +1 -1
- package/lib/module/ui/screens/OxyAuthScreen.js +12 -8
- package/lib/module/ui/screens/OxyAuthScreen.js.map +1 -1
- package/lib/module/ui/screens/PaymentGatewayScreen.js +3 -2
- package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -1
- package/lib/module/ui/screens/PrivacySettingsScreen.js +6 -4
- package/lib/module/ui/screens/PrivacySettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/ProfileScreen.js +8 -6
- package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/SavesCollectionsScreen.js +3 -2
- package/lib/module/ui/screens/SavesCollectionsScreen.js.map +1 -1
- package/lib/module/ui/screens/SearchSettingsScreen.js +6 -4
- package/lib/module/ui/screens/SearchSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/SessionManagementScreen.js +6 -4
- package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/UserLinksScreen.js +3 -2
- package/lib/module/ui/screens/UserLinksScreen.js.map +1 -1
- package/lib/module/ui/screens/UserListScreen.js +9 -6
- package/lib/module/ui/screens/UserListScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaAboutScreen.js +3 -2
- package/lib/module/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaCenterScreen.js +8 -6
- package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaFAQScreen.js +3 -2
- package/lib/module/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +3 -2
- package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaRewardsScreen.js +6 -4
- package/lib/module/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaRulesScreen.js +3 -2
- package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +1 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/ActingAsBanner.d.ts +4 -0
- package/lib/typescript/commonjs/ui/components/ActingAsBanner.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/BottomSheet.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts +9 -8
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/navigation/routes.d.ts +1 -1
- package/lib/typescript/commonjs/ui/navigation/routes.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/AccountCenterScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/CreateManagedAccountScreen.d.ts +5 -0
- package/lib/typescript/commonjs/ui/screens/CreateManagedAccountScreen.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/screens/EditProfileFieldScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/FeedbackScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/types/navigation.d.ts +3 -0
- package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +1 -0
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/ActingAsBanner.d.ts +4 -0
- package/lib/typescript/module/ui/components/ActingAsBanner.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/BottomSheet.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/OxyContext.d.ts +9 -8
- package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/module/ui/navigation/routes.d.ts +1 -1
- package/lib/typescript/module/ui/navigation/routes.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/AccountCenterScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/CreateManagedAccountScreen.d.ts +5 -0
- package/lib/typescript/module/ui/screens/CreateManagedAccountScreen.d.ts.map +1 -0
- package/lib/typescript/module/ui/screens/EditProfileFieldScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/FeedbackScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/types/navigation.d.ts +3 -0
- package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
- package/package.json +1 -2
- package/src/index.ts +3 -0
- package/src/ui/components/ActingAsBanner.tsx +135 -0
- package/src/ui/components/BottomSheet.tsx +3 -2
- package/src/ui/components/BottomSheetRouter.tsx +2 -2
- package/src/ui/components/OxyProvider.tsx +55 -50
- package/src/ui/components/fileManagement/FileDetailsModal.tsx +1 -1
- package/src/ui/components/fileManagement/UploadPreview.tsx +1 -1
- package/src/ui/components/modals/DeleteAccountModal.tsx +1 -1
- package/src/ui/context/OxyContext.tsx +106 -12
- package/src/ui/context/hooks/useAuthOperations.ts +2 -1
- package/src/ui/navigation/routes.ts +3 -1
- package/src/ui/screens/AccountCenterScreen.tsx +24 -4
- package/src/ui/screens/AccountOverviewScreen.tsx +3 -3
- package/src/ui/screens/AccountSettingsScreen.tsx +2 -2
- package/src/ui/screens/AccountSwitcherScreen.tsx +212 -1
- package/src/ui/screens/AccountVerificationScreen.tsx +1 -1
- package/src/ui/screens/CreateManagedAccountScreen.tsx +338 -0
- package/src/ui/screens/EditProfileFieldScreen.tsx +1 -2
- package/src/ui/screens/FAQScreen.tsx +1 -1
- package/src/ui/screens/FeedbackScreen.tsx +1 -2
- package/src/ui/screens/HelpSupportScreen.tsx +1 -1
- package/src/ui/screens/HistoryViewScreen.tsx +1 -1
- package/src/ui/screens/LanguageSelectorScreen.tsx +1 -1
- package/src/ui/screens/LearnMoreUsernamesScreen.tsx +1 -1
- package/src/ui/screens/LegalDocumentsScreen.tsx +2 -2
- package/src/ui/screens/OxyAuthScreen.tsx +5 -5
- package/src/ui/screens/PaymentGatewayScreen.tsx +1 -1
- package/src/ui/screens/PrivacySettingsScreen.tsx +2 -2
- package/src/ui/screens/ProfileScreen.tsx +3 -3
- package/src/ui/screens/SavesCollectionsScreen.tsx +1 -1
- package/src/ui/screens/SearchSettingsScreen.tsx +2 -2
- package/src/ui/screens/SessionManagementScreen.tsx +2 -2
- package/src/ui/screens/UserLinksScreen.tsx +1 -1
- package/src/ui/screens/UserListScreen.tsx +3 -3
- package/src/ui/screens/karma/KarmaAboutScreen.tsx +1 -1
- package/src/ui/screens/karma/KarmaCenterScreen.tsx +3 -3
- package/src/ui/screens/karma/KarmaFAQScreen.tsx +1 -1
- package/src/ui/screens/karma/KarmaLeaderboardScreen.tsx +1 -1
- package/src/ui/screens/karma/KarmaRewardsScreen.tsx +2 -2
- package/src/ui/screens/karma/KarmaRulesScreen.tsx +1 -1
- package/src/ui/types/navigation.ts +3 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type
|
|
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
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
-
<
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
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
|
-
<
|
|
243
|
+
<KeyboardWrapper>
|
|
239
244
|
{coreContent}
|
|
240
|
-
</
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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
|
-
|
|
480
|
-
|
|
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'
|
|
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
|
|
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' }]}
|
|
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
|
|
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
|
|
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' }]}
|
|
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
|
|
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' }]}
|
|
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
|
|
326
|
+
<View style={[styles.container, { backgroundColor: bloomTheme.colors.background }]}>
|
|
327
327
|
<ScrollView
|
|
328
328
|
ref={scrollViewRef}
|
|
329
329
|
style={styles.content}
|