@oxyhq/services 5.11.9 → 5.11.11
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/ui/components/AnimationExample.js +213 -0
- package/lib/commonjs/ui/components/AnimationExample.js.map +1 -0
- package/lib/commonjs/ui/components/FollowButton.js +58 -47
- package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
- package/lib/commonjs/ui/components/GroupedItem.js +2 -1
- package/lib/commonjs/ui/components/GroupedItem.js.map +1 -1
- package/lib/commonjs/ui/components/GroupedSection.js +3 -0
- package/lib/commonjs/ui/components/GroupedSection.js.map +1 -1
- package/lib/commonjs/ui/components/Header.js +26 -12
- package/lib/commonjs/ui/components/Header.js.map +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js +69 -33
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/ProfileCard.js +5 -1
- package/lib/commonjs/ui/components/ProfileCard.js.map +1 -1
- package/lib/commonjs/ui/components/StepBasedScreen.README.md +337 -0
- package/lib/commonjs/ui/components/StepBasedScreen.js +361 -0
- package/lib/commonjs/ui/components/StepBasedScreen.js.map +1 -0
- package/lib/commonjs/ui/components/icon/OxyIcon.js +3 -3
- package/lib/commonjs/ui/components/icon/OxyIcon.js.map +1 -1
- package/lib/commonjs/ui/components/index.js +0 -7
- package/lib/commonjs/ui/components/index.js.map +1 -1
- package/lib/commonjs/ui/components/internal/PinInput.js +1 -1
- package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -1
- package/lib/commonjs/ui/components/internal/TextField.js +8 -4
- package/lib/commonjs/ui/components/internal/TextField.js.map +1 -1
- package/lib/commonjs/ui/components/photogrid/JustifiedPhotoGrid.js +161 -0
- package/lib/commonjs/ui/components/photogrid/JustifiedPhotoGrid.js.map +1 -0
- package/lib/commonjs/ui/context/OxyContext.js +103 -44
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/hooks/useFollow.types.js +2 -0
- package/lib/commonjs/ui/hooks/useFollow.types.js.map +1 -0
- package/lib/commonjs/ui/navigation/OxyRouter.js +10 -0
- package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountCenterScreen.js +26 -14
- package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js +3 -3
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +64 -15
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +4 -4
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FeedbackScreen.js +72 -75
- package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FileManagementScreen.js +286 -126
- package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +322 -0
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/ProfileScreen.js +56 -56
- package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/RecoverAccountScreen.js +87 -219
- package/lib/commonjs/ui/screens/RecoverAccountScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SessionManagementScreen.js +176 -174
- package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SignInScreen.js +138 -244
- package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SignUpScreen.js +143 -744
- package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js +386 -0
- package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js +25 -15
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js +16 -9
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/RecoverRequestStep.js +110 -0
- package/lib/commonjs/ui/screens/steps/RecoverRequestStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/RecoverSuccessStep.js +138 -0
- package/lib/commonjs/ui/screens/steps/RecoverSuccessStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/RecoverVerifyStep.js +141 -0
- package/lib/commonjs/ui/screens/steps/RecoverVerifyStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/SignInPasswordStep.js +165 -0
- package/lib/commonjs/ui/screens/steps/SignInPasswordStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/SignInUsernameStep.js +150 -0
- package/lib/commonjs/ui/screens/steps/SignInUsernameStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/SignUpIdentityStep.js +171 -0
- package/lib/commonjs/ui/screens/steps/SignUpIdentityStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/SignUpSecurityStep.js +163 -0
- package/lib/commonjs/ui/screens/steps/SignUpSecurityStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/SignUpSummaryStep.js +170 -0
- package/lib/commonjs/ui/screens/steps/SignUpSummaryStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/SignUpWelcomeStep.js +72 -0
- package/lib/commonjs/ui/screens/steps/SignUpWelcomeStep.js.map +1 -0
- package/lib/commonjs/ui/styles/authStyles.js +1 -1
- package/lib/commonjs/ui/styles/authStyles.js.map +1 -1
- package/lib/module/ui/components/AnimationExample.js +209 -0
- package/lib/module/ui/components/AnimationExample.js.map +1 -0
- package/lib/module/ui/components/FollowButton.js +58 -47
- package/lib/module/ui/components/FollowButton.js.map +1 -1
- package/lib/module/ui/components/GroupedItem.js +2 -1
- package/lib/module/ui/components/GroupedItem.js.map +1 -1
- package/lib/module/ui/components/GroupedSection.js +3 -0
- package/lib/module/ui/components/GroupedSection.js.map +1 -1
- package/lib/module/ui/components/Header.js +26 -12
- package/lib/module/ui/components/Header.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +70 -34
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/ProfileCard.js +5 -1
- package/lib/module/ui/components/ProfileCard.js.map +1 -1
- package/lib/module/ui/components/Section.js.map +1 -1
- package/lib/module/ui/components/SectionTitle.js.map +1 -1
- package/lib/module/ui/components/StepBasedScreen.README.md +337 -0
- package/lib/module/ui/components/StepBasedScreen.js +356 -0
- package/lib/module/ui/components/StepBasedScreen.js.map +1 -0
- package/lib/module/ui/components/icon/FAIRWalletIcon.js.map +1 -1
- package/lib/module/ui/components/icon/OxyIcon.js +3 -3
- package/lib/module/ui/components/icon/OxyIcon.js.map +1 -1
- package/lib/module/ui/components/index.js +0 -1
- package/lib/module/ui/components/index.js.map +1 -1
- package/lib/module/ui/components/internal/PinInput.js +1 -1
- package/lib/module/ui/components/internal/PinInput.js.map +1 -1
- package/lib/module/ui/components/internal/TextField.js +8 -4
- package/lib/module/ui/components/internal/TextField.js.map +1 -1
- package/lib/module/ui/components/photogrid/JustifiedPhotoGrid.js +156 -0
- package/lib/module/ui/components/photogrid/JustifiedPhotoGrid.js.map +1 -0
- package/lib/module/ui/context/OxyContext.js +103 -45
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/hooks/useFollow.types.js +2 -0
- package/lib/module/ui/hooks/useFollow.types.js.map +1 -0
- package/lib/module/ui/navigation/OxyRouter.js +10 -0
- package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
- package/lib/module/ui/screens/AccountCenterScreen.js +12 -1
- package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountOverviewScreen.js +3 -3
- package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js +64 -15
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSwitcherScreen.js +4 -4
- package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/module/ui/screens/FeedbackScreen.js +72 -75
- package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/module/ui/screens/FileManagementScreen.js +285 -125
- package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/LanguageSelectorScreen.js +319 -0
- package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -0
- package/lib/module/ui/screens/ProfileScreen.js +56 -56
- package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/RecoverAccountScreen.js +91 -222
- package/lib/module/ui/screens/RecoverAccountScreen.js.map +1 -1
- package/lib/module/ui/screens/SessionManagementScreen.js +177 -175
- package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/SignInScreen.js +140 -246
- package/lib/module/ui/screens/SignInScreen.js.map +1 -1
- package/lib/module/ui/screens/SignUpScreen.js +145 -745
- package/lib/module/ui/screens/SignUpScreen.js.map +1 -1
- package/lib/module/ui/screens/WelcomeNewUserScreen.js +382 -0
- package/lib/module/ui/screens/WelcomeNewUserScreen.js.map +1 -0
- package/lib/module/ui/screens/internal/SignInPasswordStep.js +23 -14
- package/lib/module/ui/screens/internal/SignInPasswordStep.js.map +1 -1
- package/lib/module/ui/screens/internal/SignInUsernameStep.js +15 -9
- package/lib/module/ui/screens/internal/SignInUsernameStep.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaCenterScreen.js +1 -1
- package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/steps/RecoverRequestStep.js +105 -0
- package/lib/module/ui/screens/steps/RecoverRequestStep.js.map +1 -0
- package/lib/module/ui/screens/steps/RecoverSuccessStep.js +133 -0
- package/lib/module/ui/screens/steps/RecoverSuccessStep.js.map +1 -0
- package/lib/module/ui/screens/steps/RecoverVerifyStep.js +136 -0
- package/lib/module/ui/screens/steps/RecoverVerifyStep.js.map +1 -0
- package/lib/module/ui/screens/steps/SignInPasswordStep.js +160 -0
- package/lib/module/ui/screens/steps/SignInPasswordStep.js.map +1 -0
- package/lib/module/ui/screens/steps/SignInUsernameStep.js +145 -0
- package/lib/module/ui/screens/steps/SignInUsernameStep.js.map +1 -0
- package/lib/module/ui/screens/steps/SignUpIdentityStep.js +166 -0
- package/lib/module/ui/screens/steps/SignUpIdentityStep.js.map +1 -0
- package/lib/module/ui/screens/steps/SignUpSecurityStep.js +158 -0
- package/lib/module/ui/screens/steps/SignUpSecurityStep.js.map +1 -0
- package/lib/module/ui/screens/steps/SignUpSummaryStep.js +165 -0
- package/lib/module/ui/screens/steps/SignUpSummaryStep.js.map +1 -0
- package/lib/module/ui/screens/steps/SignUpWelcomeStep.js +67 -0
- package/lib/module/ui/screens/steps/SignUpWelcomeStep.js.map +1 -0
- package/lib/module/ui/styles/authStyles.js +1 -1
- package/lib/module/ui/styles/authStyles.js.map +1 -1
- package/lib/typescript/models/interfaces.d.ts +5 -8
- package/lib/typescript/models/interfaces.d.ts.map +1 -1
- package/lib/typescript/models/session.d.ts +1 -4
- package/lib/typescript/models/session.d.ts.map +1 -1
- package/lib/typescript/ui/components/AnimationExample.d.ts +4 -0
- package/lib/typescript/ui/components/AnimationExample.d.ts.map +1 -0
- package/lib/typescript/ui/components/FollowButton.d.ts.map +1 -1
- package/lib/typescript/ui/components/GroupedItem.d.ts.map +1 -1
- package/lib/typescript/ui/components/Header.d.ts +9 -0
- package/lib/typescript/ui/components/Header.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxyPayButton.d.ts +2 -2
- package/lib/typescript/ui/components/OxyPayButton.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/ui/components/ProfileCard.d.ts +1 -3
- package/lib/typescript/ui/components/ProfileCard.d.ts.map +1 -1
- package/lib/typescript/ui/components/Section.d.ts +2 -1
- package/lib/typescript/ui/components/Section.d.ts.map +1 -1
- package/lib/typescript/ui/components/SectionTitle.d.ts +2 -1
- package/lib/typescript/ui/components/SectionTitle.d.ts.map +1 -1
- package/lib/typescript/ui/components/StepBasedScreen.d.ts +24 -0
- package/lib/typescript/ui/components/StepBasedScreen.d.ts.map +1 -0
- package/lib/typescript/ui/components/icon/FAIRWalletIcon.d.ts +2 -1
- package/lib/typescript/ui/components/icon/FAIRWalletIcon.d.ts.map +1 -1
- package/lib/typescript/ui/components/icon/OxyIcon.d.ts +1 -1
- package/lib/typescript/ui/components/icon/OxyIcon.d.ts.map +1 -1
- package/lib/typescript/ui/components/index.d.ts +0 -1
- package/lib/typescript/ui/components/index.d.ts.map +1 -1
- package/lib/typescript/ui/components/internal/PinInput.d.ts +9 -1
- package/lib/typescript/ui/components/internal/PinInput.d.ts.map +1 -1
- package/lib/typescript/ui/components/internal/TextField.d.ts.map +1 -1
- package/lib/typescript/ui/components/photogrid/JustifiedPhotoGrid.d.ts +27 -0
- package/lib/typescript/ui/components/photogrid/JustifiedPhotoGrid.d.ts.map +1 -0
- package/lib/typescript/ui/context/OxyContext.d.ts +8 -3
- package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/useFollow.types.d.ts +33 -0
- package/lib/typescript/ui/hooks/useFollow.types.d.ts.map +1 -0
- package/lib/typescript/ui/navigation/OxyRouter.d.ts.map +1 -1
- package/lib/typescript/ui/navigation/types.d.ts +5 -0
- package/lib/typescript/ui/navigation/types.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountCenterScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/FeedbackScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/FileManagementScreen.d.ts +18 -1
- package/lib/typescript/ui/screens/FileManagementScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/LanguageSelectorScreen.d.ts +7 -0
- package/lib/typescript/ui/screens/LanguageSelectorScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/PaymentGatewayScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/ProfileScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts +2 -9
- package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SessionManagementScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SignUpScreen.d.ts +1 -1
- package/lib/typescript/ui/screens/SignUpScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/WelcomeNewUserScreen.d.ts +13 -0
- package/lib/typescript/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts +5 -5
- package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts +4 -4
- package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/RecoverRequestStep.d.ts +21 -0
- package/lib/typescript/ui/screens/steps/RecoverRequestStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/RecoverSuccessStep.d.ts +18 -0
- package/lib/typescript/ui/screens/steps/RecoverSuccessStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/RecoverVerifyStep.d.ts +24 -0
- package/lib/typescript/ui/screens/steps/RecoverVerifyStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/SignInPasswordStep.d.ts +27 -0
- package/lib/typescript/ui/screens/steps/SignInPasswordStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/SignInUsernameStep.d.ts +27 -0
- package/lib/typescript/ui/screens/steps/SignInUsernameStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/SignUpIdentityStep.d.ts +25 -0
- package/lib/typescript/ui/screens/steps/SignUpIdentityStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/SignUpSecurityStep.d.ts +26 -0
- package/lib/typescript/ui/screens/steps/SignUpSecurityStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/SignUpSummaryStep.d.ts +16 -0
- package/lib/typescript/ui/screens/steps/SignUpSummaryStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/SignUpWelcomeStep.d.ts +13 -0
- package/lib/typescript/ui/screens/steps/SignUpWelcomeStep.d.ts.map +1 -0
- package/lib/typescript/ui/styles/authStyles.d.ts +1 -1
- package/package.json +10 -3
- package/src/models/interfaces.ts +7 -8
- package/src/models/session.ts +1 -4
- package/src/ui/components/AnimationExample.tsx +195 -0
- package/src/ui/components/FollowButton.tsx +65 -45
- package/src/ui/components/GroupedItem.tsx +1 -0
- package/src/ui/components/GroupedSection.tsx +1 -1
- package/src/ui/components/Header.tsx +37 -13
- package/src/ui/components/OxyPayButton.tsx +2 -2
- package/src/ui/components/OxyProvider.tsx +67 -33
- package/src/ui/components/ProfileCard.tsx +6 -8
- package/src/ui/components/Section.tsx +7 -7
- package/src/ui/components/SectionTitle.tsx +2 -2
- package/src/ui/components/StepBasedScreen.README.md +337 -0
- package/src/ui/components/StepBasedScreen.tsx +417 -0
- package/src/ui/components/icon/FAIRWalletIcon.tsx +2 -2
- package/src/ui/components/icon/OxyIcon.tsx +10 -11
- package/src/ui/components/index.ts +0 -1
- package/src/ui/components/internal/PinInput.tsx +13 -4
- package/src/ui/components/internal/TextField.tsx +12 -6
- package/src/ui/components/photogrid/JustifiedPhotoGrid.tsx +158 -0
- package/src/ui/context/OxyContext.tsx +90 -59
- package/src/ui/hooks/useFollow.types.ts +33 -0
- package/src/ui/navigation/OxyRouter.tsx +10 -0
- package/src/ui/navigation/types.ts +6 -0
- package/src/ui/screens/AccountCenterScreen.tsx +13 -7
- package/src/ui/screens/AccountOverviewScreen.tsx +3 -3
- package/src/ui/screens/AccountSettingsScreen.tsx +65 -13
- package/src/ui/screens/AccountSwitcherScreen.tsx +4 -4
- package/src/ui/screens/FeedbackScreen.tsx +57 -80
- package/src/ui/screens/FileManagementScreen.tsx +278 -175
- package/src/ui/screens/LanguageSelectorScreen.tsx +322 -0
- package/src/ui/screens/PaymentGatewayScreen.tsx +2 -2
- package/src/ui/screens/ProfileScreen.tsx +60 -55
- package/src/ui/screens/RecoverAccountScreen.tsx +98 -211
- package/src/ui/screens/SessionManagementScreen.tsx +148 -151
- package/src/ui/screens/SignInScreen.tsx +148 -290
- package/src/ui/screens/SignUpScreen.tsx +147 -751
- package/src/ui/screens/WelcomeNewUserScreen.tsx +272 -0
- package/src/ui/screens/internal/SignInPasswordStep.tsx +28 -13
- package/src/ui/screens/internal/SignInUsernameStep.tsx +21 -11
- package/src/ui/screens/karma/KarmaCenterScreen.tsx +1 -1
- package/src/ui/screens/steps/RecoverRequestStep.tsx +130 -0
- package/src/ui/screens/steps/RecoverSuccessStep.tsx +131 -0
- package/src/ui/screens/steps/RecoverVerifyStep.tsx +153 -0
- package/src/ui/screens/steps/SignInPasswordStep.tsx +172 -0
- package/src/ui/screens/steps/SignInUsernameStep.tsx +176 -0
- package/src/ui/screens/steps/SignUpIdentityStep.tsx +204 -0
- package/src/ui/screens/steps/SignUpSecurityStep.tsx +191 -0
- package/src/ui/screens/steps/SignUpSummaryStep.tsx +130 -0
- package/src/ui/screens/steps/SignUpWelcomeStep.tsx +65 -0
- package/src/ui/styles/authStyles.ts +1 -1
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import React, { useEffect, useMemo, useState, useCallback } from 'react';
|
|
2
|
+
import { View, Text, type LayoutChangeEvent } from 'react-native';
|
|
3
|
+
import type { FileMetadata } from '../../../models/interfaces';
|
|
4
|
+
// Using plain React Native styles (nativewind not installed in this repo)
|
|
5
|
+
|
|
6
|
+
export interface JustifiedPhotoGridProps {
|
|
7
|
+
photos: FileMetadata[];
|
|
8
|
+
photoDimensions: { [key: string]: { width: number; height: number } };
|
|
9
|
+
loadPhotoDimensions: (photos: FileMetadata[]) => Promise<void>;
|
|
10
|
+
createJustifiedRows: (photos: FileMetadata[], containerWidth: number) => FileMetadata[][];
|
|
11
|
+
renderJustifiedPhotoItem: (photo: FileMetadata, width: number, height: number, isLast: boolean) => React.ReactElement;
|
|
12
|
+
renderSimplePhotoItem: (photo: FileMetadata, index: number) => React.ReactElement;
|
|
13
|
+
textColor: string;
|
|
14
|
+
/**
|
|
15
|
+
* Full available width from parent. If omitted, component will measure itself and adapt responsively.
|
|
16
|
+
*/
|
|
17
|
+
containerWidth?: number; // optional; will auto-measure if not provided
|
|
18
|
+
gap?: number;
|
|
19
|
+
minRowHeight?: number;
|
|
20
|
+
maxRowHeight?: number;
|
|
21
|
+
dateFormatLocale?: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Responsive justified photo grid that stretches to the provided containerWidth.
|
|
26
|
+
* Uses flex rows with proportional children widths instead of absolute pixel widths so it always fills.
|
|
27
|
+
*/
|
|
28
|
+
const JustifiedPhotoGrid: React.FC<JustifiedPhotoGridProps> = ({
|
|
29
|
+
photos,
|
|
30
|
+
photoDimensions,
|
|
31
|
+
loadPhotoDimensions,
|
|
32
|
+
createJustifiedRows,
|
|
33
|
+
renderJustifiedPhotoItem,
|
|
34
|
+
textColor,
|
|
35
|
+
containerWidth: explicitWidth,
|
|
36
|
+
gap = 4,
|
|
37
|
+
minRowHeight = 100,
|
|
38
|
+
maxRowHeight = 300,
|
|
39
|
+
dateFormatLocale = 'en-US',
|
|
40
|
+
}) => {
|
|
41
|
+
// Responsive width measurement if not explicitly provided
|
|
42
|
+
const [measuredWidth, setMeasuredWidth] = useState<number | null>(null);
|
|
43
|
+
const effectiveWidth = explicitWidth ?? measuredWidth ?? 0; // 0 until measured
|
|
44
|
+
|
|
45
|
+
const onLayoutContainer = useCallback((e: LayoutChangeEvent) => {
|
|
46
|
+
if (explicitWidth) return; // ignore if controlled
|
|
47
|
+
const w = e.nativeEvent.layout.width;
|
|
48
|
+
setMeasuredWidth(prev => (prev === w ? prev : w));
|
|
49
|
+
}, [explicitWidth]);
|
|
50
|
+
// Ensure dimensions are loaded for displayed photos
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
loadPhotoDimensions(photos);
|
|
53
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
54
|
+
}, [photos.map(p => p.id).join(',')]);
|
|
55
|
+
|
|
56
|
+
// Group photos by date first
|
|
57
|
+
const photosByDate = useMemo(() => {
|
|
58
|
+
return photos.reduce((groups: { [key: string]: FileMetadata[] }, photo) => {
|
|
59
|
+
const date = new Date(photo.uploadDate).toDateString();
|
|
60
|
+
if (!groups[date]) groups[date] = [];
|
|
61
|
+
groups[date].push(photo);
|
|
62
|
+
return groups;
|
|
63
|
+
}, {} as { [key: string]: FileMetadata[] });
|
|
64
|
+
}, [photos]);
|
|
65
|
+
|
|
66
|
+
const sortedDates = useMemo(() => Object.keys(photosByDate).sort((a, b) => new Date(b).getTime() - new Date(a).getTime()), [photosByDate]);
|
|
67
|
+
|
|
68
|
+
// Track measured width of each date section (may differ if parent applies horizontal padding/margins)
|
|
69
|
+
const [dateWidths, setDateWidths] = useState<Record<string, number>>({});
|
|
70
|
+
const onLayoutDate = useCallback((date: string, width: number) => {
|
|
71
|
+
setDateWidths(prev => (prev[date] === width ? prev : { ...prev, [date]: width }));
|
|
72
|
+
}, []);
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<View style={{ width: '100%' }} onLayout={onLayoutContainer}>
|
|
76
|
+
{/* If width not yet known (uncontrolled), avoid rendering to prevent layout jump */}
|
|
77
|
+
{effectiveWidth === 0 && !explicitWidth ? null : (
|
|
78
|
+
<>
|
|
79
|
+
{sortedDates.map((date: string) => {
|
|
80
|
+
const dayPhotos = photosByDate[date];
|
|
81
|
+
// createJustifiedRows should build rows such that the "ideal" height (availableWidth / totalAspect) stays within min/max.
|
|
82
|
+
// We pass the effective container width.
|
|
83
|
+
const dateWidth = dateWidths[date] ?? effectiveWidth; // fallback to overall width until measured
|
|
84
|
+
const rows = dateWidth > 0 ? createJustifiedRows(dayPhotos, dateWidth) : [];
|
|
85
|
+
return (
|
|
86
|
+
<View
|
|
87
|
+
key={date}
|
|
88
|
+
style={{ marginBottom: 24, width: '100%' }}
|
|
89
|
+
onLayout={e => onLayoutDate(date, e.nativeEvent.layout.width)}
|
|
90
|
+
>
|
|
91
|
+
<Text style={{ fontSize: 14, fontWeight: '600', marginBottom: 12, color: textColor }}>
|
|
92
|
+
{new Date(date).toLocaleDateString(dateFormatLocale, { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}
|
|
93
|
+
</Text>
|
|
94
|
+
<View style={{ width: '100%' }}>
|
|
95
|
+
{rows.map((row, rowIndex) => {
|
|
96
|
+
// Compute total aspect ratios using loaded dimensions (fallback 4/3)
|
|
97
|
+
const aspects = row.map(p => {
|
|
98
|
+
const dims = photoDimensions[p.id];
|
|
99
|
+
return dims ? dims.width / dims.height : 4 / 3;
|
|
100
|
+
});
|
|
101
|
+
const totalAspect = aspects.reduce((a, b) => a + b, 0);
|
|
102
|
+
const gapsTotal = gap * (row.length - 1);
|
|
103
|
+
const availableWidth = dateWidth - gapsTotal;
|
|
104
|
+
// Ideal height that perfectly fills width when preserving aspect ratios
|
|
105
|
+
const idealHeight = availableWidth / totalAspect;
|
|
106
|
+
// We rely on row construction keeping idealHeight within min/max bounds; if not, clamp but then distribute leftover/overflow.
|
|
107
|
+
let rowHeight = idealHeight;
|
|
108
|
+
let widthAdjustment = 0; // difference to distribute if clamped
|
|
109
|
+
if (idealHeight < minRowHeight) {
|
|
110
|
+
rowHeight = minRowHeight;
|
|
111
|
+
widthAdjustment = availableWidth - rowHeight * totalAspect; // negative means overflow
|
|
112
|
+
} else if (idealHeight > maxRowHeight) {
|
|
113
|
+
rowHeight = maxRowHeight;
|
|
114
|
+
widthAdjustment = availableWidth - rowHeight * totalAspect;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Pre-compute widths maintaining aspect ratios
|
|
118
|
+
let widths = aspects.map(ar => ar * rowHeight);
|
|
119
|
+
// If we have widthAdjustment (due to clamping) distribute proportionally so row still fills exactly
|
|
120
|
+
if (widthAdjustment !== 0) {
|
|
121
|
+
const widthSum = widths.reduce((a, b) => a + b, 0);
|
|
122
|
+
widths = widths.map(w => w + (w / widthSum) * widthAdjustment);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// To combat rounding issues, adjust last item width to fill precisely
|
|
126
|
+
const widthSumRounded = widths.reduce((a, b) => a + b, 0);
|
|
127
|
+
const roundingDiff = availableWidth - widthSumRounded;
|
|
128
|
+
if (Math.abs(roundingDiff) > 0.5) {
|
|
129
|
+
widths[widths.length - 1] += roundingDiff; // minimal correction
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<View key={rowIndex} style={{ flexDirection: 'row', width: '100%', marginBottom: 4 }}>
|
|
134
|
+
{row.map((p, i) => {
|
|
135
|
+
const photoWidth = widths[i];
|
|
136
|
+
return (
|
|
137
|
+
<View
|
|
138
|
+
key={p.id}
|
|
139
|
+
style={{ width: photoWidth, height: rowHeight, marginRight: i === row.length - 1 ? 0 : gap }}
|
|
140
|
+
>
|
|
141
|
+
{renderJustifiedPhotoItem(p, photoWidth, rowHeight, i === row.length - 1)}
|
|
142
|
+
</View>
|
|
143
|
+
);
|
|
144
|
+
})}
|
|
145
|
+
</View>
|
|
146
|
+
);
|
|
147
|
+
})}
|
|
148
|
+
</View>
|
|
149
|
+
</View>
|
|
150
|
+
);
|
|
151
|
+
})}
|
|
152
|
+
</>
|
|
153
|
+
)}
|
|
154
|
+
</View>
|
|
155
|
+
);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
export default React.memo(JustifiedPhotoGrid);
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
import { createContext, useContext, useEffect, useCallback, useMemo, useRef, useState, type ReactNode } from 'react';
|
|
3
|
+
import type { UseFollowHook } from '../hooks/useFollow.types';
|
|
2
4
|
import { View, Text } from 'react-native';
|
|
3
5
|
import { OxyServices } from '../../core';
|
|
4
6
|
import type { User, ApiError } from '../../models/interfaces';
|
|
@@ -9,8 +11,8 @@ import { toast } from '../../lib/sonner';
|
|
|
9
11
|
import { useAuthStore } from '../stores/authStore';
|
|
10
12
|
|
|
11
13
|
// Define the context shape
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
// NOTE: We intentionally avoid importing useFollow here to prevent a require cycle.
|
|
15
|
+
// If consumers relied on `const { useFollow } = useOxy()`, we provide a lazy proxy below.
|
|
14
16
|
|
|
15
17
|
export interface OxyContextState {
|
|
16
18
|
// Authentication state
|
|
@@ -22,6 +24,9 @@ export interface OxyContextState {
|
|
|
22
24
|
isLoading: boolean;
|
|
23
25
|
error: string | null;
|
|
24
26
|
|
|
27
|
+
// Language state
|
|
28
|
+
currentLanguage: string;
|
|
29
|
+
|
|
25
30
|
// Auth methods
|
|
26
31
|
login: (username: string, password: string, deviceName?: string) => Promise<User>;
|
|
27
32
|
logout: (targetSessionId?: string) => Promise<void>;
|
|
@@ -33,6 +38,9 @@ export interface OxyContextState {
|
|
|
33
38
|
removeSession: (sessionId: string) => Promise<void>;
|
|
34
39
|
refreshSessions: () => Promise<void>;
|
|
35
40
|
|
|
41
|
+
// Language methods
|
|
42
|
+
setLanguage: (languageId: string) => Promise<void>;
|
|
43
|
+
|
|
36
44
|
// Device management methods
|
|
37
45
|
getDeviceSessions: () => Promise<any[]>;
|
|
38
46
|
logoutAllDeviceSessions: () => Promise<void>;
|
|
@@ -47,9 +55,10 @@ export interface OxyContextState {
|
|
|
47
55
|
hideBottomSheet?: () => void;
|
|
48
56
|
|
|
49
57
|
/**
|
|
50
|
-
* useFollow hook
|
|
58
|
+
* (Deprecated) useFollow hook access via context. Prefer: import { useFollow } from '@oxyhq/services';
|
|
59
|
+
* Kept for backward compatibility; implemented as a lazy dynamic require to avoid circular dependency.
|
|
51
60
|
*/
|
|
52
|
-
useFollow:
|
|
61
|
+
useFollow: UseFollowHook; // Back-compat; prefer direct import
|
|
53
62
|
}
|
|
54
63
|
|
|
55
64
|
// Create the context with default values
|
|
@@ -122,6 +131,7 @@ const getStorage = async (): Promise<StorageInterface> => {
|
|
|
122
131
|
// Storage keys for sessions
|
|
123
132
|
const getStorageKeys = (prefix = 'oxy_session') => ({
|
|
124
133
|
activeSessionId: `${prefix}_active_session_id`, // Only store the active session ID
|
|
134
|
+
language: `${prefix}_language`, // Store the selected language
|
|
125
135
|
});
|
|
126
136
|
|
|
127
137
|
export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
@@ -158,12 +168,13 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
158
168
|
const logoutStore = useAuthStore((state) => state.logout);
|
|
159
169
|
|
|
160
170
|
// Local state for non-auth fields
|
|
161
|
-
const [minimalUser, setMinimalUser] =
|
|
162
|
-
const [sessions, setSessions] =
|
|
163
|
-
const [activeSessionId, setActiveSessionId] =
|
|
164
|
-
const [storage, setStorage] =
|
|
171
|
+
const [minimalUser, setMinimalUser] = useState<MinimalUserData | null>(null);
|
|
172
|
+
const [sessions, setSessions] = useState<ClientSession[]>([]);
|
|
173
|
+
const [activeSessionId, setActiveSessionId] = useState<string | null>(null);
|
|
174
|
+
const [storage, setStorage] = useState<StorageInterface | null>(null);
|
|
175
|
+
const [currentLanguage, setCurrentLanguage] = useState<string>('en');
|
|
165
176
|
// Add a new state to track token restoration
|
|
166
|
-
const [tokenReady, setTokenReady] =
|
|
177
|
+
const [tokenReady, setTokenReady] = useState(false);
|
|
167
178
|
|
|
168
179
|
// Storage keys (memoized to prevent infinite loops)
|
|
169
180
|
const keys = useMemo(() => getStorageKeys(storageKeyPrefix), [storageKeyPrefix]);
|
|
@@ -185,88 +196,66 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
185
196
|
const platformStorage = await getStorage();
|
|
186
197
|
setStorage(platformStorage);
|
|
187
198
|
} catch (error) {
|
|
188
|
-
console.error('
|
|
199
|
+
console.error('Init storage failed', error);
|
|
189
200
|
useAuthStore.setState({ error: 'Failed to initialize storage' });
|
|
190
201
|
}
|
|
191
202
|
};
|
|
192
|
-
|
|
193
203
|
initStorage();
|
|
194
204
|
}, []);
|
|
195
205
|
|
|
196
|
-
//
|
|
206
|
+
// Initialize authentication state
|
|
197
207
|
useEffect(() => {
|
|
198
208
|
const initAuth = async () => {
|
|
199
209
|
if (!storage) return;
|
|
200
|
-
|
|
201
210
|
useAuthStore.setState({ isLoading: true });
|
|
202
211
|
try {
|
|
203
|
-
|
|
204
|
-
const storedActiveSessionId = await storage.getItem(keys.activeSessionId);
|
|
212
|
+
setTokenReady(false);
|
|
205
213
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
214
|
+
// Load saved language preference
|
|
215
|
+
const savedLanguage = await storage.getItem(keys.language);
|
|
216
|
+
if (savedLanguage) {
|
|
217
|
+
setCurrentLanguage(savedLanguage);
|
|
218
|
+
}
|
|
209
219
|
|
|
220
|
+
// Try to restore active session from storage
|
|
221
|
+
const storedActiveSessionId = await storage.getItem(keys.activeSessionId);
|
|
210
222
|
if (storedActiveSessionId) {
|
|
211
|
-
// Validate the stored session with the backend
|
|
212
223
|
try {
|
|
213
|
-
const validation = await oxyServices.validateSession(storedActiveSessionId, {
|
|
214
|
-
useHeaderValidation: true
|
|
215
|
-
});
|
|
216
|
-
|
|
224
|
+
const validation = await oxyServices.validateSession(storedActiveSessionId, { useHeaderValidation: true });
|
|
217
225
|
if (validation.valid) {
|
|
218
|
-
console.log('Auth - session validated successfully');
|
|
219
226
|
setActiveSessionId(storedActiveSessionId);
|
|
220
|
-
|
|
221
|
-
// Get access token for API calls
|
|
222
227
|
await oxyServices.getTokenBySession(storedActiveSessionId);
|
|
223
|
-
|
|
224
|
-
// Load full user data from backend
|
|
225
228
|
const fullUser = await oxyServices.getUserBySession(storedActiveSessionId);
|
|
226
229
|
loginSuccess(fullUser);
|
|
227
|
-
setMinimalUser({
|
|
228
|
-
id: fullUser.id,
|
|
229
|
-
username: fullUser.username,
|
|
230
|
-
avatar: fullUser.avatar
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
// Load sessions from backend
|
|
230
|
+
setMinimalUser({ id: fullUser.id, username: fullUser.username, avatar: fullUser.avatar });
|
|
234
231
|
const serverSessions = await oxyServices.getSessionsBySessionId(storedActiveSessionId);
|
|
235
|
-
const clientSessions: ClientSession[] = serverSessions.map(
|
|
236
|
-
sessionId:
|
|
237
|
-
deviceId:
|
|
238
|
-
expiresAt:
|
|
239
|
-
lastActive:
|
|
240
|
-
userId:
|
|
232
|
+
const clientSessions: ClientSession[] = serverSessions.map(s => ({
|
|
233
|
+
sessionId: s.sessionId,
|
|
234
|
+
deviceId: s.deviceId,
|
|
235
|
+
expiresAt: s.expiresAt || new Date().toISOString(),
|
|
236
|
+
lastActive: s.lastActive || new Date().toISOString(),
|
|
237
|
+
userId: s.userId || fullUser.id
|
|
241
238
|
}));
|
|
242
239
|
setSessions(clientSessions);
|
|
243
|
-
|
|
244
|
-
if (onAuthStateChange) {
|
|
245
|
-
onAuthStateChange(fullUser);
|
|
246
|
-
}
|
|
240
|
+
onAuthStateChange?.(fullUser);
|
|
247
241
|
} else {
|
|
248
|
-
console.log('Auth - session invalid, clearing storage');
|
|
249
242
|
await clearAllStorage();
|
|
250
243
|
}
|
|
251
|
-
} catch (
|
|
252
|
-
console.error('
|
|
244
|
+
} catch (e) {
|
|
245
|
+
console.error('Session validation error', e);
|
|
253
246
|
await clearAllStorage();
|
|
254
247
|
}
|
|
255
|
-
} else {
|
|
256
|
-
console.log('Auth - no stored session found, user needs to login');
|
|
257
248
|
}
|
|
258
|
-
|
|
259
|
-
|
|
249
|
+
setTokenReady(true);
|
|
250
|
+
} catch (e) {
|
|
251
|
+
console.error('Auth init error', e);
|
|
260
252
|
await clearAllStorage();
|
|
261
253
|
} finally {
|
|
262
254
|
useAuthStore.setState({ isLoading: false });
|
|
263
255
|
}
|
|
264
256
|
};
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
initAuth();
|
|
268
|
-
}
|
|
269
|
-
}, [storage, oxyServices, keys, onAuthStateChange, loginSuccess, setMinimalUser, clearAllStorage]);
|
|
257
|
+
initAuth();
|
|
258
|
+
}, [storage, oxyServices, keys, onAuthStateChange, loginSuccess, clearAllStorage]);
|
|
270
259
|
|
|
271
260
|
|
|
272
261
|
|
|
@@ -630,6 +619,26 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
630
619
|
}
|
|
631
620
|
}, [activeSessionId, oxyServices]);
|
|
632
621
|
|
|
622
|
+
// Language management method
|
|
623
|
+
const setLanguage = useCallback(async (languageId: string): Promise<void> => {
|
|
624
|
+
if (!storage) throw new Error('Storage not initialized');
|
|
625
|
+
|
|
626
|
+
try {
|
|
627
|
+
// Save language preference
|
|
628
|
+
await storage.setItem(keys.language, languageId);
|
|
629
|
+
setCurrentLanguage(languageId);
|
|
630
|
+
|
|
631
|
+
console.log(`Language changed to ${languageId}`);
|
|
632
|
+
|
|
633
|
+
// TODO: Here you can add any additional logic needed for app-wide language updates
|
|
634
|
+
// such as updating i18n configuration, refreshing translations, etc.
|
|
635
|
+
|
|
636
|
+
} catch (error) {
|
|
637
|
+
console.error('Error saving language preference:', error);
|
|
638
|
+
throw error;
|
|
639
|
+
}
|
|
640
|
+
}, [storage, keys.language]);
|
|
641
|
+
|
|
633
642
|
// Bottom sheet control methods
|
|
634
643
|
const showBottomSheet = useCallback((screenOrConfig?: string | { screen: string; props?: Record<string, any> }) => {
|
|
635
644
|
console.log('showBottomSheet called with:', screenOrConfig);
|
|
@@ -691,6 +700,24 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
691
700
|
});
|
|
692
701
|
|
|
693
702
|
// Context value - optimized to prevent unnecessary re-renders
|
|
703
|
+
// Lazy proxy to load the hook only when accessed, breaking the static import cycle.
|
|
704
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
|
|
705
|
+
const useFollowProxy: UseFollowHook = (userId?: string | string[]) => {
|
|
706
|
+
try {
|
|
707
|
+
// Dynamically require to avoid top-level cycle
|
|
708
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
709
|
+
const mod = require('../hooks/useFollow');
|
|
710
|
+
if (mod && typeof mod.useFollow === 'function') {
|
|
711
|
+
return mod.useFollow(userId);
|
|
712
|
+
}
|
|
713
|
+
console.warn('useFollow module did not export a function as expected');
|
|
714
|
+
return { isFollowing: false, isLoading: false, error: null, toggleFollow: async () => { }, setFollowStatus: () => { }, fetchStatus: async () => { }, clearError: () => { }, followerCount: null, followingCount: null, isLoadingCounts: false, fetchUserCounts: async () => { }, setFollowerCount: () => { }, setFollowingCount: () => { } } as any;
|
|
715
|
+
} catch (e) {
|
|
716
|
+
console.warn('Failed to dynamically load useFollow hook:', e);
|
|
717
|
+
return { isFollowing: false, isLoading: false, error: null, toggleFollow: async () => { }, setFollowStatus: () => { }, fetchStatus: async () => { }, clearError: () => { }, followerCount: null, followingCount: null, isLoadingCounts: false, fetchUserCounts: async () => { }, setFollowerCount: () => { }, setFollowingCount: () => { } } as any;
|
|
718
|
+
}
|
|
719
|
+
};
|
|
720
|
+
|
|
694
721
|
const contextValue: OxyContextState = useMemo(() => ({
|
|
695
722
|
user,
|
|
696
723
|
minimalUser,
|
|
@@ -699,6 +726,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
699
726
|
isAuthenticated,
|
|
700
727
|
isLoading,
|
|
701
728
|
error,
|
|
729
|
+
currentLanguage,
|
|
702
730
|
login,
|
|
703
731
|
logout,
|
|
704
732
|
logoutAll,
|
|
@@ -706,6 +734,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
706
734
|
switchSession,
|
|
707
735
|
removeSession,
|
|
708
736
|
refreshSessions,
|
|
737
|
+
setLanguage,
|
|
709
738
|
getDeviceSessions,
|
|
710
739
|
logoutAllDeviceSessions,
|
|
711
740
|
updateDeviceName,
|
|
@@ -713,7 +742,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
713
742
|
bottomSheetRef,
|
|
714
743
|
showBottomSheet,
|
|
715
744
|
hideBottomSheet,
|
|
716
|
-
useFollow:
|
|
745
|
+
useFollow: useFollowProxy,
|
|
717
746
|
}), [
|
|
718
747
|
user?.id, // Only depend on user ID, not the entire user object
|
|
719
748
|
minimalUser?.id,
|
|
@@ -722,6 +751,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
722
751
|
isAuthenticated,
|
|
723
752
|
isLoading,
|
|
724
753
|
error,
|
|
754
|
+
currentLanguage,
|
|
725
755
|
login,
|
|
726
756
|
logout,
|
|
727
757
|
logoutAll,
|
|
@@ -729,6 +759,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
729
759
|
switchSession,
|
|
730
760
|
removeSession,
|
|
731
761
|
refreshSessions,
|
|
762
|
+
setLanguage,
|
|
732
763
|
getDeviceSessions,
|
|
733
764
|
logoutAllDeviceSessions,
|
|
734
765
|
updateDeviceName,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Type-only definition for the useFollow hook to allow context exposure without runtime import cycles.
|
|
2
|
+
// Expand this as needed to better reflect the real return type.
|
|
3
|
+
|
|
4
|
+
export type SingleFollowResult = {
|
|
5
|
+
isFollowing: boolean;
|
|
6
|
+
isLoading: boolean;
|
|
7
|
+
error: string | null;
|
|
8
|
+
toggleFollow: () => Promise<void>;
|
|
9
|
+
setFollowStatus: (following: boolean) => void;
|
|
10
|
+
fetchStatus: () => Promise<void>;
|
|
11
|
+
clearError: () => void;
|
|
12
|
+
followerCount: number | null;
|
|
13
|
+
followingCount: number | null;
|
|
14
|
+
isLoadingCounts: boolean;
|
|
15
|
+
fetchUserCounts: () => Promise<void>;
|
|
16
|
+
setFollowerCount: (count: number) => void;
|
|
17
|
+
setFollowingCount: (count: number) => void;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type MultiFollowResult = {
|
|
21
|
+
followData: Record<string, { isFollowing: boolean; isLoading: boolean; error: string | null }>;
|
|
22
|
+
toggleFollowForUser: (userId: string) => Promise<void>;
|
|
23
|
+
setFollowStatusForUser: (userId: string, following: boolean) => void;
|
|
24
|
+
fetchStatusForUser: (userId: string) => Promise<void>;
|
|
25
|
+
fetchAllStatuses: () => Promise<void>;
|
|
26
|
+
clearErrorForUser: (userId: string) => void;
|
|
27
|
+
isAnyLoading: boolean;
|
|
28
|
+
hasAnyError: boolean;
|
|
29
|
+
allFollowing: boolean;
|
|
30
|
+
allNotFollowing: boolean;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type UseFollowHook = (userId?: string | string[]) => SingleFollowResult | MultiFollowResult;
|
|
@@ -25,6 +25,8 @@ import UserLinksScreen from '../screens/UserLinksScreen';
|
|
|
25
25
|
import FileManagementScreen from '../screens/FileManagementScreen';
|
|
26
26
|
import RecoverAccountScreen from '../screens/RecoverAccountScreen';
|
|
27
27
|
import PaymentGatewayScreen from '../screens/PaymentGatewayScreen';
|
|
28
|
+
import WelcomeNewUserScreen from '../screens/WelcomeNewUserScreen';
|
|
29
|
+
import LanguageSelectorScreen from '../screens/LanguageSelectorScreen';
|
|
28
30
|
|
|
29
31
|
// Import types
|
|
30
32
|
import type { OxyRouterProps, RouteConfig } from './types';
|
|
@@ -115,6 +117,14 @@ const routes: Record<string, RouteConfig> = {
|
|
|
115
117
|
component: PaymentGatewayScreen,
|
|
116
118
|
snapPoints: ['60%', '90%'],
|
|
117
119
|
},
|
|
120
|
+
WelcomeNewUser: {
|
|
121
|
+
component: WelcomeNewUserScreen,
|
|
122
|
+
snapPoints: ['65%', '90%'],
|
|
123
|
+
},
|
|
124
|
+
LanguageSelector: {
|
|
125
|
+
component: LanguageSelectorScreen,
|
|
126
|
+
snapPoints: ['70%', '100%'],
|
|
127
|
+
},
|
|
118
128
|
};
|
|
119
129
|
|
|
120
130
|
const OxyRouter: React.FC<OxyRouterProps> = ({
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { OxyServices } from '../../core';
|
|
2
2
|
import type { User } from '../../models/interfaces';
|
|
3
3
|
import type { ComponentType, ReactNode } from 'react';
|
|
4
|
+
import type { QueryClient } from '@tanstack/react-query';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Base props for all screens in the Oxy UI system
|
|
@@ -138,4 +139,9 @@ export interface OxyProviderProps {
|
|
|
138
139
|
* @default true
|
|
139
140
|
*/
|
|
140
141
|
showInternalToaster?: boolean;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Optional QueryClient instance for React Query. If not provided, a sensible default is created.
|
|
145
|
+
*/
|
|
146
|
+
queryClient?: QueryClient;
|
|
141
147
|
}
|
|
@@ -16,13 +16,11 @@ import { toast } from '../../lib/sonner';
|
|
|
16
16
|
import { confirmAction } from '../utils/confirmAction';
|
|
17
17
|
import { Ionicons } from '@expo/vector-icons';
|
|
18
18
|
import { fontFamilies } from '../styles/fonts';
|
|
19
|
-
import
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
GroupedItem
|
|
25
|
-
} from '../components';
|
|
19
|
+
import ProfileCard from '../components/ProfileCard';
|
|
20
|
+
import Section from '../components/Section';
|
|
21
|
+
import QuickActions from '../components/QuickActions';
|
|
22
|
+
import GroupedSection from '../components/GroupedSection';
|
|
23
|
+
import GroupedItem from '../components/GroupedItem';
|
|
26
24
|
|
|
27
25
|
const AccountCenterScreen: React.FC<BaseScreenProps> = ({
|
|
28
26
|
onClose,
|
|
@@ -218,6 +216,14 @@ const AccountCenterScreen: React.FC<BaseScreenProps> = ({
|
|
|
218
216
|
subtitle: 'Manage notification settings',
|
|
219
217
|
onPress: () => toast.info('Notifications feature coming soon!'),
|
|
220
218
|
}] : []),
|
|
219
|
+
{
|
|
220
|
+
id: 'language',
|
|
221
|
+
icon: 'language',
|
|
222
|
+
iconColor: '#32D74B',
|
|
223
|
+
title: 'Language',
|
|
224
|
+
subtitle: 'Choose your preferred language',
|
|
225
|
+
onPress: () => navigate('LanguageSelector'),
|
|
226
|
+
},
|
|
221
227
|
{
|
|
222
228
|
id: 'help',
|
|
223
229
|
icon: 'help-circle',
|
|
@@ -192,7 +192,7 @@ const AccountOverviewScreen: React.FC<BaseScreenProps> = ({
|
|
|
192
192
|
<>
|
|
193
193
|
<View style={styles.userIcon}>
|
|
194
194
|
<Avatar
|
|
195
|
-
uri={user?.avatar
|
|
195
|
+
uri={user?.avatar ? oxyServices.getFileDownloadUrl(user.avatar as string, 'thumb') : undefined}
|
|
196
196
|
name={user?.name?.full}
|
|
197
197
|
size={40}
|
|
198
198
|
theme={theme}
|
|
@@ -301,8 +301,8 @@ const AccountOverviewScreen: React.FC<BaseScreenProps> = ({
|
|
|
301
301
|
customContent: (
|
|
302
302
|
<>
|
|
303
303
|
<View style={styles.userIcon}>
|
|
304
|
-
{account.avatar
|
|
305
|
-
<Image source={{ uri: account.avatar
|
|
304
|
+
{account.avatar ? (
|
|
305
|
+
<Image source={{ uri: oxyServices.getFileStreamUrl(account.avatar as string) }} style={styles.accountAvatarImage} />
|
|
306
306
|
) : (
|
|
307
307
|
<View style={styles.accountAvatarFallback}>
|
|
308
308
|
<Text style={styles.accountAvatarText}>
|