@oxyhq/services 5.5.9 → 5.6.0
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/README.md +16 -2
- package/lib/commonjs/core/index.js +69 -82
- package/lib/commonjs/core/index.js.map +1 -1
- package/lib/commonjs/index.js +24 -183
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/node/index.js +0 -2
- package/lib/commonjs/node/index.js.map +1 -1
- package/lib/commonjs/ui/components/FollowButton.js +100 -229
- package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
- package/lib/commonjs/ui/components/OxyPayButton.js +131 -0
- package/lib/commonjs/ui/components/OxyPayButton.js.map +1 -0
- package/lib/commonjs/ui/components/OxyProvider.js +41 -198
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/OxySignInButton.js +15 -2
- package/lib/commonjs/ui/components/OxySignInButton.js.map +1 -1
- package/lib/commonjs/ui/components/icon/FAIRWalletIcon.js +66 -0
- package/lib/commonjs/ui/components/icon/FAIRWalletIcon.js.map +1 -0
- package/lib/commonjs/ui/components/icon/index.js +7 -0
- package/lib/commonjs/ui/components/icon/index.js.map +1 -1
- package/lib/commonjs/ui/components/index.js +7 -0
- package/lib/commonjs/ui/components/index.js.map +1 -1
- package/lib/commonjs/ui/components/internal/GroupedPillButtons.js +14 -7
- package/lib/commonjs/ui/components/internal/GroupedPillButtons.js.map +1 -1
- package/lib/commonjs/ui/components/internal/PinInput.js +108 -0
- package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -0
- package/lib/commonjs/ui/components/internal/TextField.js +20 -0
- package/lib/commonjs/ui/components/internal/TextField.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +26 -36
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/hooks/index.js +2 -15
- package/lib/commonjs/ui/hooks/index.js.map +1 -1
- package/lib/commonjs/ui/hooks/useFollow.js +52 -136
- package/lib/commonjs/ui/hooks/useFollow.js.map +1 -1
- package/lib/commonjs/ui/hooks/useSessionSocket.js +52 -0
- package/lib/commonjs/ui/hooks/useSessionSocket.js.map +1 -0
- package/lib/commonjs/ui/index.js +8 -191
- package/lib/commonjs/ui/index.js.map +1 -1
- package/lib/commonjs/ui/navigation/OxyRouter.js +52 -60
- package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountCenterScreen.js +18 -30
- package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js +4 -22
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +6 -14
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +37 -66
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AppInfoScreen.js +21 -44
- package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FeedbackScreen.js +44 -23
- package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FileManagementScreen.js +59 -78
- package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +1588 -0
- package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +22 -36
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/RecoverAccountScreen.js +269 -0
- package/lib/commonjs/ui/screens/RecoverAccountScreen.js.map +1 -0
- package/lib/commonjs/ui/screens/SessionManagementScreen.js +47 -69
- package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SignInScreen.js +99 -333
- package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SignUpScreen.js +136 -340
- package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js +192 -0
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js.map +1 -0
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js +135 -0
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js.map +1 -0
- package/lib/commonjs/ui/screens/internal/SignUpIdentityStep.js +108 -0
- package/lib/commonjs/ui/screens/internal/SignUpIdentityStep.js.map +1 -0
- package/lib/commonjs/ui/screens/internal/SignUpSecurityStep.js +126 -0
- package/lib/commonjs/ui/screens/internal/SignUpSecurityStep.js.map +1 -0
- package/lib/commonjs/ui/screens/internal/SignUpSummaryStep.js +84 -0
- package/lib/commonjs/ui/screens/internal/SignUpSummaryStep.js.map +1 -0
- package/lib/commonjs/ui/screens/internal/SignUpWelcomeStep.js +59 -0
- package/lib/commonjs/ui/screens/internal/SignUpWelcomeStep.js.map +1 -0
- package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js +15 -2
- package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
- package/lib/commonjs/ui/stores/authStore.js +31 -0
- package/lib/commonjs/ui/stores/authStore.js.map +1 -0
- package/lib/commonjs/ui/stores/followStore.js +124 -0
- package/lib/commonjs/ui/stores/followStore.js.map +1 -0
- package/lib/commonjs/ui/styles/index.js +0 -11
- package/lib/commonjs/ui/styles/index.js.map +1 -1
- package/lib/commonjs/ui/utils/confirmAction.js +28 -0
- package/lib/commonjs/ui/utils/confirmAction.js.map +1 -0
- package/lib/module/core/index.js +69 -81
- package/lib/module/core/index.js.map +1 -1
- package/lib/module/index.js +14 -17
- package/lib/module/index.js.map +1 -1
- package/lib/module/node/index.js +0 -3
- package/lib/module/node/index.js.map +1 -1
- package/lib/module/ui/components/FollowButton.js +100 -229
- package/lib/module/ui/components/FollowButton.js.map +1 -1
- package/lib/module/ui/components/OxyPayButton.js +125 -0
- package/lib/module/ui/components/OxyPayButton.js.map +1 -0
- package/lib/module/ui/components/OxyProvider.js +42 -199
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/OxySignInButton.js +15 -2
- package/lib/module/ui/components/OxySignInButton.js.map +1 -1
- package/lib/module/ui/components/icon/FAIRWalletIcon.js +60 -0
- package/lib/module/ui/components/icon/FAIRWalletIcon.js.map +1 -0
- package/lib/module/ui/components/icon/index.js +1 -0
- package/lib/module/ui/components/icon/index.js.map +1 -1
- package/lib/module/ui/components/index.js +1 -0
- package/lib/module/ui/components/index.js.map +1 -1
- package/lib/module/ui/components/internal/GroupedPillButtons.js +15 -8
- package/lib/module/ui/components/internal/GroupedPillButtons.js.map +1 -1
- package/lib/module/ui/components/internal/PinInput.js +103 -0
- package/lib/module/ui/components/internal/PinInput.js.map +1 -0
- package/lib/module/ui/components/internal/TextField.js +20 -0
- package/lib/module/ui/components/internal/TextField.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +26 -36
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/hooks/index.js +1 -2
- package/lib/module/ui/hooks/index.js.map +1 -1
- package/lib/module/ui/hooks/useFollow.js +52 -137
- package/lib/module/ui/hooks/useFollow.js.map +1 -1
- package/lib/module/ui/hooks/useSessionSocket.js +47 -0
- package/lib/module/ui/hooks/useSessionSocket.js.map +1 -0
- package/lib/module/ui/index.js +2 -13
- package/lib/module/ui/index.js.map +1 -1
- package/lib/module/ui/navigation/OxyRouter.js +53 -61
- package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
- package/lib/module/ui/screens/AccountCenterScreen.js +6 -18
- package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountOverviewScreen.js +5 -23
- package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js +7 -15
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSwitcherScreen.js +38 -67
- package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/module/ui/screens/AppInfoScreen.js +22 -45
- package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
- package/lib/module/ui/screens/FeedbackScreen.js +44 -23
- package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/module/ui/screens/FileManagementScreen.js +59 -78
- package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/PaymentGatewayScreen.js +1583 -0
- package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -0
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js +23 -37
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/module/ui/screens/RecoverAccountScreen.js +263 -0
- package/lib/module/ui/screens/RecoverAccountScreen.js.map +1 -0
- package/lib/module/ui/screens/SessionManagementScreen.js +47 -69
- package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/SignInScreen.js +100 -334
- package/lib/module/ui/screens/SignInScreen.js.map +1 -1
- package/lib/module/ui/screens/SignUpScreen.js +137 -341
- package/lib/module/ui/screens/SignUpScreen.js.map +1 -1
- package/lib/module/ui/screens/internal/SignInPasswordStep.js +186 -0
- package/lib/module/ui/screens/internal/SignInPasswordStep.js.map +1 -0
- package/lib/module/ui/screens/internal/SignInUsernameStep.js +129 -0
- package/lib/module/ui/screens/internal/SignInUsernameStep.js.map +1 -0
- package/lib/module/ui/screens/internal/SignUpIdentityStep.js +102 -0
- package/lib/module/ui/screens/internal/SignUpIdentityStep.js.map +1 -0
- package/lib/module/ui/screens/internal/SignUpSecurityStep.js +120 -0
- package/lib/module/ui/screens/internal/SignUpSecurityStep.js.map +1 -0
- package/lib/module/ui/screens/internal/SignUpSummaryStep.js +79 -0
- package/lib/module/ui/screens/internal/SignUpSummaryStep.js.map +1 -0
- package/lib/module/ui/screens/internal/SignUpWelcomeStep.js +54 -0
- package/lib/module/ui/screens/internal/SignUpWelcomeStep.js.map +1 -0
- package/lib/module/ui/screens/karma/KarmaRewardsScreen.js +16 -3
- package/lib/module/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
- package/lib/module/ui/stores/authStore.js +27 -0
- package/lib/module/ui/stores/authStore.js.map +1 -0
- package/lib/module/ui/stores/followStore.js +120 -0
- package/lib/module/ui/stores/followStore.js.map +1 -0
- package/lib/module/ui/styles/index.js +0 -1
- package/lib/module/ui/styles/index.js.map +1 -1
- package/lib/module/ui/utils/confirmAction.js +25 -0
- package/lib/module/ui/utils/confirmAction.js.map +1 -0
- package/lib/typescript/core/index.d.ts +28 -10
- package/lib/typescript/core/index.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +5 -4
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/models/secureSession.d.ts +0 -1
- package/lib/typescript/models/secureSession.d.ts.map +1 -1
- package/lib/typescript/node/index.d.ts +0 -1
- package/lib/typescript/node/index.d.ts.map +1 -1
- package/lib/typescript/ui/components/FollowButton.d.ts +1 -77
- package/lib/typescript/ui/components/FollowButton.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxyPayButton.d.ts +29 -0
- package/lib/typescript/ui/components/OxyPayButton.d.ts.map +1 -0
- package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxySignInButton.d.ts.map +1 -1
- package/lib/typescript/ui/components/icon/FAIRWalletIcon.d.ts +8 -0
- package/lib/typescript/ui/components/icon/FAIRWalletIcon.d.ts.map +1 -0
- package/lib/typescript/ui/components/icon/index.d.ts +1 -0
- package/lib/typescript/ui/components/icon/index.d.ts.map +1 -1
- package/lib/typescript/ui/components/index.d.ts +1 -0
- package/lib/typescript/ui/components/index.d.ts.map +1 -1
- package/lib/typescript/ui/components/internal/GroupedPillButtons.d.ts.map +1 -1
- package/lib/typescript/ui/components/internal/PinInput.d.ts +12 -0
- package/lib/typescript/ui/components/internal/PinInput.d.ts.map +1 -0
- package/lib/typescript/ui/components/internal/TextField.d.ts +1 -0
- package/lib/typescript/ui/components/internal/TextField.d.ts.map +1 -1
- package/lib/typescript/ui/context/OxyContext.d.ts +0 -2
- package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/index.d.ts +1 -2
- package/lib/typescript/ui/hooks/index.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/useFollow.d.ts +14 -15
- package/lib/typescript/ui/hooks/useFollow.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/useSessionSocket.d.ts +11 -0
- package/lib/typescript/ui/hooks/useSessionSocket.d.ts.map +1 -0
- package/lib/typescript/ui/index.d.ts +2 -5
- package/lib/typescript/ui/index.d.ts.map +1 -1
- package/lib/typescript/ui/navigation/OxyRouter.d.ts.map +1 -1
- package/lib/typescript/ui/navigation/types.d.ts +5 -23
- 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/AccountOverviewScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AppInfoScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/FeedbackScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/FileManagementScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/PaymentGatewayScreen.d.ts +27 -0
- package/lib/typescript/ui/screens/PaymentGatewayScreen.d.ts.map +1 -0
- package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts +8 -0
- package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts.map +1 -0
- 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.map +1 -1
- package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts +27 -0
- package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts +26 -0
- package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/internal/SignUpIdentityStep.d.ts +20 -0
- package/lib/typescript/ui/screens/internal/SignUpIdentityStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/internal/SignUpSecurityStep.d.ts +24 -0
- package/lib/typescript/ui/screens/internal/SignUpSecurityStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/internal/SignUpSummaryStep.d.ts +15 -0
- package/lib/typescript/ui/screens/internal/SignUpSummaryStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/internal/SignUpWelcomeStep.d.ts +13 -0
- package/lib/typescript/ui/screens/internal/SignUpWelcomeStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/karma/KarmaRewardsScreen.d.ts.map +1 -1
- package/lib/typescript/ui/stores/authStore.d.ts +14 -0
- package/lib/typescript/ui/stores/authStore.d.ts.map +1 -0
- package/lib/typescript/ui/stores/followStore.d.ts +15 -0
- package/lib/typescript/ui/stores/followStore.d.ts.map +1 -0
- package/lib/typescript/ui/styles/index.d.ts +0 -1
- package/lib/typescript/ui/styles/index.d.ts.map +1 -1
- package/lib/typescript/ui/utils/confirmAction.d.ts +7 -0
- package/lib/typescript/ui/utils/confirmAction.d.ts.map +1 -0
- package/package.json +12 -7
- package/src/core/index.ts +78 -88
- package/src/index.ts +8 -45
- package/src/models/secureSession.ts +1 -2
- package/src/node/index.ts +0 -3
- package/src/ui/components/FollowButton.tsx +100 -322
- package/src/ui/components/OxyPayButton.tsx +133 -0
- package/src/ui/components/OxyProvider.tsx +39 -201
- package/src/ui/components/OxySignInButton.tsx +13 -2
- package/src/ui/components/icon/FAIRWalletIcon.tsx +49 -0
- package/src/ui/components/icon/index.ts +1 -0
- package/src/ui/components/index.ts +1 -0
- package/src/ui/components/internal/GroupedPillButtons.tsx +12 -8
- package/src/ui/components/internal/PinInput.tsx +102 -0
- package/src/ui/components/internal/TextField.tsx +9 -0
- package/src/ui/context/OxyContext.tsx +26 -40
- package/src/ui/hooks/index.ts +1 -2
- package/src/ui/hooks/useFollow.ts +58 -129
- package/src/ui/hooks/useSessionSocket.ts +50 -0
- package/src/ui/index.ts +2 -37
- package/src/ui/navigation/OxyRouter.tsx +47 -63
- package/src/ui/navigation/types.ts +5 -26
- package/src/ui/screens/AccountCenterScreen.tsx +12 -21
- package/src/ui/screens/AccountOverviewScreen.tsx +6 -30
- package/src/ui/screens/AccountSettingsScreen.tsx +7 -22
- package/src/ui/screens/AccountSwitcherScreen.tsx +46 -88
- package/src/ui/screens/AppInfoScreen.tsx +27 -47
- package/src/ui/screens/FeedbackScreen.tsx +34 -19
- package/src/ui/screens/FileManagementScreen.tsx +293 -321
- package/src/ui/screens/PaymentGatewayScreen.tsx +1315 -0
- package/src/ui/screens/PremiumSubscriptionScreen.tsx +109 -124
- package/src/ui/screens/RecoverAccountScreen.tsx +260 -0
- package/src/ui/screens/SessionManagementScreen.tsx +65 -137
- package/src/ui/screens/SignInScreen.tsx +89 -283
- package/src/ui/screens/SignUpScreen.tsx +138 -291
- package/src/ui/screens/internal/SignInPasswordStep.tsx +179 -0
- package/src/ui/screens/internal/SignInUsernameStep.tsx +139 -0
- package/src/ui/screens/internal/SignUpIdentityStep.tsx +114 -0
- package/src/ui/screens/internal/SignUpSecurityStep.tsx +132 -0
- package/src/ui/screens/internal/SignUpSummaryStep.tsx +66 -0
- package/src/ui/screens/internal/SignUpWelcomeStep.tsx +52 -0
- package/src/ui/screens/karma/KarmaRewardsScreen.tsx +13 -3
- package/src/ui/stores/authStore.ts +24 -0
- package/src/ui/stores/followStore.ts +80 -0
- package/src/ui/styles/index.ts +0 -1
- package/src/ui/utils/confirmAction.ts +23 -0
- package/lib/commonjs/ui/components/bottomSheet/index.js +0 -37
- package/lib/commonjs/ui/components/bottomSheet/index.js.map +0 -1
- package/lib/commonjs/ui/hooks/useAuthFetch.js +0 -217
- package/lib/commonjs/ui/hooks/useAuthFetch.js.map +0 -1
- package/lib/commonjs/ui/hooks/useOxyFollow.js +0 -190
- package/lib/commonjs/ui/hooks/useOxyFollow.js.map +0 -1
- package/lib/commonjs/ui/screens/BillingManagementScreen.js +0 -636
- package/lib/commonjs/ui/screens/BillingManagementScreen.js.map +0 -1
- package/lib/commonjs/ui/store/index.js +0 -67
- package/lib/commonjs/ui/store/index.js.map +0 -1
- package/lib/commonjs/ui/store/setupOxyStore.js +0 -63
- package/lib/commonjs/ui/store/setupOxyStore.js.map +0 -1
- package/lib/commonjs/ui/store/slices/authSlice.js +0 -56
- package/lib/commonjs/ui/store/slices/authSlice.js.map +0 -1
- package/lib/commonjs/ui/store/slices/followSlice.js +0 -238
- package/lib/commonjs/ui/store/slices/followSlice.js.map +0 -1
- package/lib/commonjs/ui/store/slices/index.js +0 -129
- package/lib/commonjs/ui/store/slices/index.js.map +0 -1
- package/lib/commonjs/ui/store/slices/types.js +0 -19
- package/lib/commonjs/ui/store/slices/types.js.map +0 -1
- package/lib/commonjs/ui/styles/shadows.js +0 -123
- package/lib/commonjs/ui/styles/shadows.js.map +0 -1
- package/lib/commonjs/utils/polyfills.js +0 -42
- package/lib/commonjs/utils/polyfills.js.map +0 -1
- package/lib/module/ui/components/bottomSheet/index.js +0 -5
- package/lib/module/ui/components/bottomSheet/index.js.map +0 -1
- package/lib/module/ui/hooks/useAuthFetch.js +0 -212
- package/lib/module/ui/hooks/useAuthFetch.js.map +0 -1
- package/lib/module/ui/hooks/useOxyFollow.js +0 -186
- package/lib/module/ui/hooks/useOxyFollow.js.map +0 -1
- package/lib/module/ui/screens/BillingManagementScreen.js +0 -631
- package/lib/module/ui/screens/BillingManagementScreen.js.map +0 -1
- package/lib/module/ui/store/index.js +0 -33
- package/lib/module/ui/store/index.js.map +0 -1
- package/lib/module/ui/store/setupOxyStore.js +0 -59
- package/lib/module/ui/store/setupOxyStore.js.map +0 -1
- package/lib/module/ui/store/slices/authSlice.js +0 -48
- package/lib/module/ui/store/slices/authSlice.js.map +0 -1
- package/lib/module/ui/store/slices/followSlice.js +0 -232
- package/lib/module/ui/store/slices/followSlice.js.map +0 -1
- package/lib/module/ui/store/slices/index.js +0 -11
- package/lib/module/ui/store/slices/index.js.map +0 -1
- package/lib/module/ui/store/slices/types.js +0 -15
- package/lib/module/ui/store/slices/types.js.map +0 -1
- package/lib/module/ui/styles/shadows.js +0 -119
- package/lib/module/ui/styles/shadows.js.map +0 -1
- package/lib/module/utils/polyfills.js +0 -36
- package/lib/module/utils/polyfills.js.map +0 -1
- package/lib/typescript/types/react-redux.d.ts +0 -5
- package/lib/typescript/ui/components/bottomSheet/index.d.ts +0 -4
- package/lib/typescript/ui/components/bottomSheet/index.d.ts.map +0 -1
- package/lib/typescript/ui/hooks/useAuthFetch.d.ts +0 -34
- package/lib/typescript/ui/hooks/useAuthFetch.d.ts.map +0 -1
- package/lib/typescript/ui/hooks/useOxyFollow.d.ts +0 -81
- package/lib/typescript/ui/hooks/useOxyFollow.d.ts.map +0 -1
- package/lib/typescript/ui/screens/BillingManagementScreen.d.ts +0 -5
- package/lib/typescript/ui/screens/BillingManagementScreen.d.ts.map +0 -1
- package/lib/typescript/ui/store/index.d.ts +0 -27
- package/lib/typescript/ui/store/index.d.ts.map +0 -1
- package/lib/typescript/ui/store/setupOxyStore.d.ts +0 -29
- package/lib/typescript/ui/store/setupOxyStore.d.ts.map +0 -1
- package/lib/typescript/ui/store/slices/authSlice.d.ts +0 -32
- package/lib/typescript/ui/store/slices/authSlice.d.ts.map +0 -1
- package/lib/typescript/ui/store/slices/followSlice.d.ts +0 -120
- package/lib/typescript/ui/store/slices/followSlice.d.ts.map +0 -1
- package/lib/typescript/ui/store/slices/index.d.ts +0 -9
- package/lib/typescript/ui/store/slices/index.d.ts.map +0 -1
- package/lib/typescript/ui/store/slices/types.d.ts +0 -16
- package/lib/typescript/ui/store/slices/types.d.ts.map +0 -1
- package/lib/typescript/ui/styles/shadows.d.ts +0 -233
- package/lib/typescript/ui/styles/shadows.d.ts.map +0 -1
- package/lib/typescript/utils/polyfills.d.ts +0 -6
- package/lib/typescript/utils/polyfills.d.ts.map +0 -1
- package/src/__tests__/backend-middleware.test.ts +0 -209
- package/src/__tests__/polyfills.test.ts +0 -30
- package/src/__tests__/setup.ts +0 -43
- package/src/__tests__/ui/hooks/authfetch-integration.test.ts +0 -197
- package/src/__tests__/ui/hooks/backward-compatibility.test.ts +0 -159
- package/src/__tests__/ui/hooks/real-world-scenarios.test.ts +0 -224
- package/src/__tests__/ui/hooks/url-resolution.test.ts +0 -129
- package/src/__tests__/ui/hooks/useAuthFetch-separation.test.ts +0 -69
- package/src/__tests__/ui/hooks/useAuthFetch.test.ts +0 -70
- package/src/__tests__/ui/hooks/useOxyFollow.test.tsx +0 -92
- package/src/__tests__/ui/screens/AccountSettingsScreen.test.tsx +0 -112
- package/src/__tests__/ui/store/setupOxyStore.test.ts +0 -50
- package/src/__tests__/validate-structure.js +0 -91
- package/src/__tests__/validation.js +0 -42
- package/src/types/react-redux.d.ts +0 -5
- package/src/ui/components/bottomSheet/index.tsx +0 -14
- package/src/ui/hooks/useAuthFetch.ts +0 -238
- package/src/ui/hooks/useOxyFollow.ts +0 -188
- package/src/ui/screens/BillingManagementScreen.tsx +0 -589
- package/src/ui/store/index.ts +0 -36
- package/src/ui/store/setupOxyStore.ts +0 -58
- package/src/ui/store/slices/authSlice.ts +0 -43
- package/src/ui/store/slices/followSlice.ts +0 -207
- package/src/ui/store/slices/index.ts +0 -31
- package/src/ui/store/slices/types.ts +0 -33
- package/src/ui/styles/shadows.ts +0 -112
- package/src/utils/polyfills.ts +0 -34
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import React, { useRef } from 'react';
|
|
2
|
+
import { View, TextInput, StyleSheet, Platform } from 'react-native';
|
|
3
|
+
|
|
4
|
+
interface PinInputProps {
|
|
5
|
+
value: string;
|
|
6
|
+
onChange: (val: string) => void;
|
|
7
|
+
length?: number;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
autoFocus?: boolean;
|
|
10
|
+
colors: any;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const PinInput: React.FC<PinInputProps> = ({ value, onChange, length = 6, disabled, autoFocus, colors }) => {
|
|
14
|
+
const inputs = useRef<Array<TextInput | null>>([]);
|
|
15
|
+
|
|
16
|
+
const handleChange = (text: string, idx: number) => {
|
|
17
|
+
if (!/^[0-9]*$/.test(text)) return;
|
|
18
|
+
let newValue = value.split('');
|
|
19
|
+
if (text.length > 1) {
|
|
20
|
+
// Paste or autofill
|
|
21
|
+
newValue = text.split('').slice(0, length);
|
|
22
|
+
onChange(newValue.join(''));
|
|
23
|
+
if (newValue.length < length) {
|
|
24
|
+
inputs.current[newValue.length]?.focus();
|
|
25
|
+
}
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
newValue[idx] = text;
|
|
29
|
+
const joined = newValue.join('').slice(0, length);
|
|
30
|
+
onChange(joined);
|
|
31
|
+
if (text && idx < length - 1) {
|
|
32
|
+
inputs.current[idx + 1]?.focus();
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const handleKeyPress = (e: any, idx: number) => {
|
|
37
|
+
if (e.nativeEvent.key === 'Backspace' && !value[idx] && idx > 0) {
|
|
38
|
+
inputs.current[idx - 1]?.focus();
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<View style={styles.pinContainer}>
|
|
44
|
+
{Array.from({ length }).map((_, idx) => (
|
|
45
|
+
<TextInput
|
|
46
|
+
key={idx}
|
|
47
|
+
ref={ref => (inputs.current[idx] = ref)}
|
|
48
|
+
style={[
|
|
49
|
+
styles.pinInput,
|
|
50
|
+
{ borderColor: colors.primary, color: colors.text, backgroundColor: colors.inputBackground },
|
|
51
|
+
value[idx] ? { borderWidth: 2 } : { borderWidth: 1 },
|
|
52
|
+
]}
|
|
53
|
+
value={value[idx] || ''}
|
|
54
|
+
onChangeText={text => handleChange(text, idx)}
|
|
55
|
+
onKeyPress={e => handleKeyPress(e, idx)}
|
|
56
|
+
keyboardType={Platform.OS === 'ios' ? 'number-pad' : 'numeric'}
|
|
57
|
+
maxLength={1}
|
|
58
|
+
editable={!disabled}
|
|
59
|
+
autoFocus={autoFocus && idx === 0}
|
|
60
|
+
textAlign="center"
|
|
61
|
+
selectionColor={colors.primary}
|
|
62
|
+
returnKeyType="done"
|
|
63
|
+
/>
|
|
64
|
+
))}
|
|
65
|
+
</View>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const styles = StyleSheet.create({
|
|
70
|
+
pinContainer: {
|
|
71
|
+
flexDirection: 'row',
|
|
72
|
+
justifyContent: 'center',
|
|
73
|
+
gap: 12,
|
|
74
|
+
marginBottom: 24,
|
|
75
|
+
marginTop: 8,
|
|
76
|
+
},
|
|
77
|
+
pinInput: {
|
|
78
|
+
width: 44,
|
|
79
|
+
height: 54,
|
|
80
|
+
borderRadius: 12,
|
|
81
|
+
borderWidth: 1,
|
|
82
|
+
fontSize: 28,
|
|
83
|
+
fontWeight: '600',
|
|
84
|
+
backgroundColor: '#F5F5F5',
|
|
85
|
+
textAlign: 'center',
|
|
86
|
+
marginHorizontal: 2,
|
|
87
|
+
...Platform.select({
|
|
88
|
+
web: {
|
|
89
|
+
boxShadow: '0 1px 4px rgba(0,0,0,0.04)',
|
|
90
|
+
},
|
|
91
|
+
default: {
|
|
92
|
+
shadowColor: '#000',
|
|
93
|
+
shadowOpacity: 0.04,
|
|
94
|
+
shadowOffset: { width: 0, height: 1 },
|
|
95
|
+
shadowRadius: 4,
|
|
96
|
+
elevation: 1,
|
|
97
|
+
}
|
|
98
|
+
}),
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
export default PinInput;
|
|
@@ -34,6 +34,7 @@ export interface TextFieldProps extends Omit<TextInputProps, 'style'> {
|
|
|
34
34
|
onBlur?: () => void;
|
|
35
35
|
onChangeText?: (text: string) => void;
|
|
36
36
|
testID?: string;
|
|
37
|
+
validMessage?: string;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
const TextField = forwardRef<TextInput, TextFieldProps>(({
|
|
@@ -57,6 +58,7 @@ const TextField = forwardRef<TextInput, TextFieldProps>(({
|
|
|
57
58
|
testID,
|
|
58
59
|
secureTextEntry,
|
|
59
60
|
value = '',
|
|
61
|
+
validMessage,
|
|
60
62
|
...textInputProps
|
|
61
63
|
}, ref) => {
|
|
62
64
|
const [isFocused, setIsFocused] = useState(false);
|
|
@@ -556,6 +558,13 @@ const TextField = forwardRef<TextInput, TextFieldProps>(({
|
|
|
556
558
|
</Text>
|
|
557
559
|
</View>
|
|
558
560
|
)}
|
|
561
|
+
{/* Valid Message */}
|
|
562
|
+
{!error && validMessage && (
|
|
563
|
+
<View style={{ flexDirection: 'row', alignItems: 'center', marginTop: 4, gap: 6 }}>
|
|
564
|
+
<Ionicons name="checkmark-circle" size={16} color={colors?.success || '#2E7D32'} />
|
|
565
|
+
<Text style={{ fontSize: 13, fontWeight: '500', color: colors?.success || '#2E7D32' }}>{validMessage}</Text>
|
|
566
|
+
</View>
|
|
567
|
+
)}
|
|
559
568
|
</View>
|
|
560
569
|
);
|
|
561
570
|
});
|
|
@@ -3,6 +3,8 @@ import { OxyServices } from '../../core';
|
|
|
3
3
|
import { User } from '../../models/interfaces';
|
|
4
4
|
import { SecureLoginResponse, SecureClientSession, MinimalUserData } from '../../models/secureSession';
|
|
5
5
|
import { DeviceManager } from '../../utils/deviceManager';
|
|
6
|
+
import { useSessionSocket } from '../hooks/useSessionSocket';
|
|
7
|
+
import { toast } from '../../lib/sonner';
|
|
6
8
|
|
|
7
9
|
// Define the context shape
|
|
8
10
|
export interface OxyContextState {
|
|
@@ -35,10 +37,6 @@ export interface OxyContextState {
|
|
|
35
37
|
oxyServices: OxyServices;
|
|
36
38
|
bottomSheetRef?: React.RefObject<any>;
|
|
37
39
|
|
|
38
|
-
// API configuration
|
|
39
|
-
setApiUrl: (url: string) => void;
|
|
40
|
-
getAppBaseURL: () => string;
|
|
41
|
-
|
|
42
40
|
// Methods to directly control the bottom sheet
|
|
43
41
|
showBottomSheet?: (screenOrConfig?: string | { screen: string; props?: Record<string, any> }) => void;
|
|
44
42
|
hideBottomSheet?: () => void;
|
|
@@ -130,7 +128,6 @@ export const OxyContextProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
130
128
|
const [isLoading, setIsLoading] = useState(true);
|
|
131
129
|
const [error, setError] = useState<string | null>(null);
|
|
132
130
|
const [storage, setStorage] = useState<StorageInterface | null>(null);
|
|
133
|
-
const [appBaseURL, setAppBaseURL] = useState<string>(oxyServices.getBaseURL());
|
|
134
131
|
|
|
135
132
|
// Storage keys (memoized to prevent infinite loops)
|
|
136
133
|
const keys = useMemo(() => getSecureStorageKeys(storageKeyPrefix), [storageKeyPrefix]);
|
|
@@ -172,17 +169,16 @@ export const OxyContextProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
172
169
|
let shouldUpdateStorage = false;
|
|
173
170
|
|
|
174
171
|
for (const session of parsedSessions) {
|
|
175
|
-
if (!session.userId
|
|
172
|
+
if (!session.userId) {
|
|
176
173
|
// Session is missing user info, try to fetch it
|
|
177
174
|
try {
|
|
178
175
|
const sessionUser = await oxyServices.getUserBySession(session.sessionId);
|
|
179
176
|
migratedSessions.push({
|
|
180
177
|
...session,
|
|
181
|
-
userId: sessionUser.id
|
|
182
|
-
username: sessionUser.username
|
|
178
|
+
userId: sessionUser.id
|
|
183
179
|
});
|
|
184
180
|
shouldUpdateStorage = true;
|
|
185
|
-
console.log(`Migrated session ${session.sessionId} for user ${sessionUser.
|
|
181
|
+
console.log(`Migrated session ${session.sessionId} for user ${sessionUser.id}`);
|
|
186
182
|
} catch (error) {
|
|
187
183
|
// Session might be invalid, skip it
|
|
188
184
|
console.log(`Removing invalid session ${session.sessionId}:`, error);
|
|
@@ -361,13 +357,12 @@ export const OxyContextProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
361
357
|
deviceId: response.deviceId,
|
|
362
358
|
expiresAt: response.expiresAt,
|
|
363
359
|
lastActive: new Date().toISOString(),
|
|
364
|
-
userId: response.user.id
|
|
365
|
-
username: response.user.username
|
|
360
|
+
userId: response.user.id
|
|
366
361
|
};
|
|
367
362
|
|
|
368
363
|
// Check if this user already has a session (prevent duplicate accounts)
|
|
369
364
|
const existingUserSessionIndex = sessions.findIndex(s =>
|
|
370
|
-
s.userId === response.user.id
|
|
365
|
+
s.userId === response.user.id
|
|
371
366
|
);
|
|
372
367
|
|
|
373
368
|
let updatedSessions: SecureClientSession[];
|
|
@@ -378,7 +373,7 @@ export const OxyContextProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
378
373
|
updatedSessions = [...sessions];
|
|
379
374
|
updatedSessions[existingUserSessionIndex] = clientSession;
|
|
380
375
|
|
|
381
|
-
console.log(`Reusing/updating existing session for user ${response.user.
|
|
376
|
+
console.log(`Reusing/updating existing session for user ${response.user.id}. Previous session: ${existingSession.sessionId}, New session: ${response.sessionId}`);
|
|
382
377
|
|
|
383
378
|
// If the replaced session was the active one, update active session
|
|
384
379
|
if (activeSessionId === existingSession.sessionId) {
|
|
@@ -388,7 +383,7 @@ export const OxyContextProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
388
383
|
} else {
|
|
389
384
|
// Add new session for new user
|
|
390
385
|
updatedSessions = [...sessions, clientSession];
|
|
391
|
-
console.log(`Added new session for user ${response.user.
|
|
386
|
+
console.log(`Added new session for user ${response.user.id} on device ${response.deviceId}`);
|
|
392
387
|
}
|
|
393
388
|
|
|
394
389
|
setSessions(updatedSessions);
|
|
@@ -645,36 +640,29 @@ export const OxyContextProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
645
640
|
}
|
|
646
641
|
}, [bottomSheetRef]);
|
|
647
642
|
|
|
648
|
-
// API URL configuration
|
|
649
|
-
const setApiUrl = useCallback((url: string) => {
|
|
650
|
-
try {
|
|
651
|
-
// Validate URL
|
|
652
|
-
if (!url) {
|
|
653
|
-
throw new Error('Base URL cannot be empty');
|
|
654
|
-
}
|
|
655
|
-
// Only update the app-specific base URL, not the OxyServices base URL
|
|
656
|
-
// This ensures internal module calls to Oxy API remain unaffected
|
|
657
|
-
setAppBaseURL(url);
|
|
658
|
-
} catch (error) {
|
|
659
|
-
console.error('Failed to update API URL:', error);
|
|
660
|
-
setError(`Failed to update API URL: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
661
|
-
}
|
|
662
|
-
}, []);
|
|
663
|
-
|
|
664
|
-
// Get current app base URL
|
|
665
|
-
const getAppBaseURL = useCallback(() => {
|
|
666
|
-
return appBaseURL;
|
|
667
|
-
}, [appBaseURL]);
|
|
668
|
-
|
|
669
643
|
// Compute comprehensive authentication status
|
|
670
644
|
// This is the single source of truth for authentication across the entire app
|
|
671
645
|
const isAuthenticated = useMemo(() => {
|
|
672
646
|
// User is authenticated if:
|
|
673
647
|
// 1. We have a full user object loaded, OR
|
|
674
|
-
// 2. We have an active session
|
|
648
|
+
// 2. We have an active session with a valid token
|
|
675
649
|
// This covers both the loaded state and the loading-but-authenticated state
|
|
676
|
-
return !!user || !!activeSessionId;
|
|
677
|
-
}, [user, activeSessionId]);
|
|
650
|
+
return !!user || (!!activeSessionId && !!oxyServices?.getCurrentUserId());
|
|
651
|
+
}, [user, activeSessionId, oxyServices]);
|
|
652
|
+
|
|
653
|
+
// Integrate socket for real-time session updates
|
|
654
|
+
console.log('OxyContextProvider: userId', user?.id, 'baseURL', oxyServices.getBaseURL());
|
|
655
|
+
useSessionSocket({
|
|
656
|
+
userId: user?.id,
|
|
657
|
+
activeSessionId,
|
|
658
|
+
refreshSessions,
|
|
659
|
+
logout: () => logout(),
|
|
660
|
+
baseURL: oxyServices.getBaseURL(),
|
|
661
|
+
onRemoteSignOut: () => {
|
|
662
|
+
toast.info('You have been signed out remotely.');
|
|
663
|
+
logout();
|
|
664
|
+
},
|
|
665
|
+
});
|
|
678
666
|
|
|
679
667
|
// Context value
|
|
680
668
|
const contextValue: OxyContextState = {
|
|
@@ -696,8 +684,6 @@ export const OxyContextProvider: React.FC<OxyContextProviderProps> = ({
|
|
|
696
684
|
logoutAllDeviceSessions,
|
|
697
685
|
updateDeviceName,
|
|
698
686
|
oxyServices,
|
|
699
|
-
setApiUrl,
|
|
700
|
-
getAppBaseURL,
|
|
701
687
|
bottomSheetRef,
|
|
702
688
|
showBottomSheet,
|
|
703
689
|
hideBottomSheet,
|
package/src/ui/hooks/index.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export { useAuthFetch } from './useAuthFetch';
|
|
1
|
+
export { useFollow } from './useFollow';
|
|
@@ -1,173 +1,102 @@
|
|
|
1
|
-
import { useDispatch, useSelector } from 'react-redux';
|
|
2
1
|
import { useCallback, useMemo } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
import type { RootState } from '../store';
|
|
2
|
+
import { useFollowStore } from '../stores/followStore';
|
|
5
3
|
import { useOxy } from '../context/OxyContext';
|
|
6
4
|
|
|
7
|
-
// Memoized selector to prevent unnecessary re-renders
|
|
8
|
-
const createFollowSelector = (userId: string) => (state: RootState) => ({
|
|
9
|
-
isFollowing: state.follow.followingUsers[userId] ?? false,
|
|
10
|
-
isLoading: state.follow.loadingUsers[userId] ?? false,
|
|
11
|
-
error: state.follow.errors[userId] ?? null,
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
// Memoized selector for multiple users
|
|
15
|
-
const createMultipleFollowSelector = (userIds: string[]) => (state: RootState) => {
|
|
16
|
-
const followData: Record<string, { isFollowing: boolean; isLoading: boolean; error: string | null }> = {};
|
|
17
|
-
const followState = state.follow;
|
|
18
|
-
|
|
19
|
-
for (const userId of userIds) {
|
|
20
|
-
followData[userId] = {
|
|
21
|
-
isFollowing: followState.followingUsers[userId] ?? false,
|
|
22
|
-
isLoading: followState.loadingUsers[userId] ?? false,
|
|
23
|
-
error: followState.errors[userId] ?? null,
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
followData,
|
|
29
|
-
isAnyLoading: userIds.some(uid => followState.loadingUsers[uid]),
|
|
30
|
-
hasAnyError: userIds.some(uid => followState.errors[uid]),
|
|
31
|
-
allFollowing: userIds.every(uid => followState.followingUsers[uid]),
|
|
32
|
-
allNotFollowing: userIds.every(uid => !followState.followingUsers[uid]),
|
|
33
|
-
};
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Custom hook for managing follow/unfollow functionality
|
|
38
|
-
* Optimized to prevent unnecessary re-renders
|
|
39
|
-
* Can handle both single user and multiple users
|
|
40
|
-
*/
|
|
41
5
|
export const useFollow = (userId?: string | string[]) => {
|
|
42
|
-
const dispatch = useDispatch();
|
|
43
6
|
const { oxyServices } = useOxy();
|
|
44
|
-
|
|
45
|
-
// Memoize user IDs to prevent recreation on every render
|
|
46
|
-
const userIds = useMemo(() => {
|
|
47
|
-
return Array.isArray(userId) ? userId : userId ? [userId] : [];
|
|
48
|
-
}, [userId]);
|
|
49
|
-
|
|
7
|
+
const userIds = useMemo(() => (Array.isArray(userId) ? userId : userId ? [userId] : []), [userId]);
|
|
50
8
|
const isSingleUser = typeof userId === 'string';
|
|
51
|
-
|
|
52
|
-
//
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// Use appropriate selector based on mode
|
|
62
|
-
const singleUserData = useSelector(singleUserSelector || (() => ({ isFollowing: false, isLoading: false, error: null })));
|
|
63
|
-
const multipleUserData = useSelector(multipleUserSelector || (() => ({
|
|
64
|
-
followData: {},
|
|
65
|
-
isAnyLoading: false,
|
|
66
|
-
hasAnyError: false,
|
|
67
|
-
allFollowing: false,
|
|
68
|
-
allNotFollowing: true
|
|
69
|
-
})));
|
|
70
|
-
|
|
71
|
-
// Memoized callbacks to prevent recreation on every render
|
|
9
|
+
|
|
10
|
+
// Zustand selectors
|
|
11
|
+
const followState = useFollowStore();
|
|
12
|
+
|
|
13
|
+
// Single user helpers
|
|
14
|
+
const isFollowing = isSingleUser && userId ? followState.followingUsers[userId] ?? false : false;
|
|
15
|
+
const isLoading = isSingleUser && userId ? followState.loadingUsers[userId] ?? false : false;
|
|
16
|
+
const error = isSingleUser && userId ? followState.errors[userId] ?? null : null;
|
|
17
|
+
|
|
72
18
|
const toggleFollow = useCallback(async () => {
|
|
73
19
|
if (!isSingleUser || !userId) throw new Error('toggleFollow is only available for single user mode');
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const result = await dispatch(toggleFollowUser({
|
|
77
|
-
userId,
|
|
78
|
-
oxyServices,
|
|
79
|
-
isCurrentlyFollowing: singleUserData.isFollowing
|
|
80
|
-
})).unwrap();
|
|
81
|
-
return result;
|
|
82
|
-
} catch (error) {
|
|
83
|
-
throw error;
|
|
84
|
-
}
|
|
85
|
-
}, [dispatch, userId, oxyServices, singleUserData.isFollowing, isSingleUser]);
|
|
20
|
+
await followState.toggleFollowUser(userId, oxyServices, isFollowing);
|
|
21
|
+
}, [isSingleUser, userId, followState, oxyServices, isFollowing]);
|
|
86
22
|
|
|
87
23
|
const setFollowStatus = useCallback((following: boolean) => {
|
|
88
24
|
if (!isSingleUser || !userId) throw new Error('setFollowStatus is only available for single user mode');
|
|
89
|
-
|
|
90
|
-
}, [
|
|
25
|
+
followState.setFollowingStatus(userId, following);
|
|
26
|
+
}, [isSingleUser, userId, followState]);
|
|
91
27
|
|
|
92
28
|
const fetchStatus = useCallback(async () => {
|
|
93
29
|
if (!isSingleUser || !userId) throw new Error('fetchStatus is only available for single user mode');
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
await dispatch(fetchFollowStatus({ userId, oxyServices })).unwrap();
|
|
97
|
-
} catch (error) {
|
|
98
|
-
console.warn(`Failed to fetch follow status for user ${userId}:`, error);
|
|
99
|
-
}
|
|
100
|
-
}, [dispatch, userId, oxyServices, isSingleUser]);
|
|
30
|
+
await followState.fetchFollowStatus(userId, oxyServices);
|
|
31
|
+
}, [isSingleUser, userId, followState, oxyServices]);
|
|
101
32
|
|
|
102
33
|
const clearError = useCallback(() => {
|
|
103
34
|
if (!isSingleUser || !userId) throw new Error('clearError is only available for single user mode');
|
|
104
|
-
|
|
105
|
-
}, [
|
|
35
|
+
followState.clearFollowError(userId);
|
|
36
|
+
}, [isSingleUser, userId, followState]);
|
|
37
|
+
|
|
38
|
+
// Multiple user helpers
|
|
39
|
+
const followData = useMemo(() => {
|
|
40
|
+
const data: Record<string, { isFollowing: boolean; isLoading: boolean; error: string | null }> = {};
|
|
41
|
+
userIds.forEach(uid => {
|
|
42
|
+
data[uid] = {
|
|
43
|
+
isFollowing: followState.followingUsers[uid] ?? false,
|
|
44
|
+
isLoading: followState.loadingUsers[uid] ?? false,
|
|
45
|
+
error: followState.errors[uid] ?? null,
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
return data;
|
|
49
|
+
}, [userIds, followState.followingUsers, followState.loadingUsers, followState.errors]);
|
|
106
50
|
|
|
107
|
-
// Multiple user callbacks
|
|
108
51
|
const toggleFollowForUser = useCallback(async (targetUserId: string) => {
|
|
109
|
-
const currentState =
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
userId: targetUserId,
|
|
113
|
-
oxyServices,
|
|
114
|
-
isCurrentlyFollowing: currentState
|
|
115
|
-
})).unwrap();
|
|
116
|
-
return result;
|
|
117
|
-
} catch (error) {
|
|
118
|
-
throw error;
|
|
119
|
-
}
|
|
120
|
-
}, [dispatch, oxyServices, multipleUserData.followData]);
|
|
52
|
+
const currentState = followState.followingUsers[targetUserId] ?? false;
|
|
53
|
+
await followState.toggleFollowUser(targetUserId, oxyServices, currentState);
|
|
54
|
+
}, [followState, oxyServices]);
|
|
121
55
|
|
|
122
56
|
const setFollowStatusForUser = useCallback((targetUserId: string, following: boolean) => {
|
|
123
|
-
|
|
124
|
-
}, [
|
|
57
|
+
followState.setFollowingStatus(targetUserId, following);
|
|
58
|
+
}, [followState]);
|
|
125
59
|
|
|
126
60
|
const fetchStatusForUser = useCallback(async (targetUserId: string) => {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
} catch (error) {
|
|
130
|
-
console.warn(`Failed to fetch follow status for user ${targetUserId}:`, error);
|
|
131
|
-
}
|
|
132
|
-
}, [dispatch, oxyServices]);
|
|
61
|
+
await followState.fetchFollowStatus(targetUserId, oxyServices);
|
|
62
|
+
}, [followState, oxyServices]);
|
|
133
63
|
|
|
134
64
|
const fetchAllStatuses = useCallback(async () => {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
console.warn(`Failed to fetch follow status for user ${uid}:`, error);
|
|
138
|
-
})
|
|
139
|
-
);
|
|
140
|
-
await Promise.all(promises);
|
|
141
|
-
}, [dispatch, userIds, oxyServices]);
|
|
65
|
+
await Promise.all(userIds.map(uid => followState.fetchFollowStatus(uid, oxyServices)));
|
|
66
|
+
}, [userIds, followState, oxyServices]);
|
|
142
67
|
|
|
143
68
|
const clearErrorForUser = useCallback((targetUserId: string) => {
|
|
144
|
-
|
|
145
|
-
}, [
|
|
69
|
+
followState.clearFollowError(targetUserId);
|
|
70
|
+
}, [followState]);
|
|
71
|
+
|
|
72
|
+
// Aggregate helpers for multiple users
|
|
73
|
+
const isAnyLoading = userIds.some(uid => followState.loadingUsers[uid]);
|
|
74
|
+
const hasAnyError = userIds.some(uid => !!followState.errors[uid]);
|
|
75
|
+
const allFollowing = userIds.every(uid => followState.followingUsers[uid]);
|
|
76
|
+
const allNotFollowing = userIds.every(uid => !followState.followingUsers[uid]);
|
|
146
77
|
|
|
147
|
-
// Return appropriate interface based on mode
|
|
148
78
|
if (isSingleUser && userId) {
|
|
149
79
|
return {
|
|
150
|
-
isFollowing
|
|
151
|
-
isLoading
|
|
152
|
-
error
|
|
80
|
+
isFollowing,
|
|
81
|
+
isLoading,
|
|
82
|
+
error,
|
|
153
83
|
toggleFollow,
|
|
154
84
|
setFollowStatus,
|
|
155
85
|
fetchStatus,
|
|
156
86
|
clearError,
|
|
157
87
|
};
|
|
158
88
|
}
|
|
159
|
-
|
|
89
|
+
|
|
160
90
|
return {
|
|
161
|
-
followData
|
|
91
|
+
followData,
|
|
162
92
|
toggleFollowForUser,
|
|
163
93
|
setFollowStatusForUser,
|
|
164
94
|
fetchStatusForUser,
|
|
165
95
|
fetchAllStatuses,
|
|
166
96
|
clearErrorForUser,
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
allNotFollowing: multipleUserData.allNotFollowing,
|
|
97
|
+
isAnyLoading,
|
|
98
|
+
hasAnyError,
|
|
99
|
+
allFollowing,
|
|
100
|
+
allNotFollowing,
|
|
172
101
|
};
|
|
173
102
|
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
import io from 'socket.io-client';
|
|
3
|
+
import { toast } from '../../lib/sonner';
|
|
4
|
+
|
|
5
|
+
interface UseSessionSocketProps {
|
|
6
|
+
userId: string | null | undefined;
|
|
7
|
+
activeSessionId: string | null | undefined;
|
|
8
|
+
refreshSessions: () => Promise<void>;
|
|
9
|
+
logout: () => Promise<void>;
|
|
10
|
+
baseURL: string;
|
|
11
|
+
onRemoteSignOut?: () => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function useSessionSocket({ userId, activeSessionId, refreshSessions, logout, baseURL, onRemoteSignOut }: UseSessionSocketProps) {
|
|
15
|
+
const socketRef = useRef<any>(null);
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!userId || !baseURL) return;
|
|
19
|
+
|
|
20
|
+
if (!socketRef.current) {
|
|
21
|
+
socketRef.current = io(baseURL, {
|
|
22
|
+
transports: ['websocket'],
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
const socket = socketRef.current;
|
|
26
|
+
|
|
27
|
+
socket.on('connect', () => {
|
|
28
|
+
console.log('Socket connected:', socket.id);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
socket.emit('join', { userId: `user:${userId}` });
|
|
32
|
+
console.log('Emitting join for room:', `user:${userId}`);
|
|
33
|
+
|
|
34
|
+
socket.on('session_update', (data: { type: string; sessionId: string }) => {
|
|
35
|
+
console.log('Received session_update:', data);
|
|
36
|
+
if (data.sessionId === activeSessionId) {
|
|
37
|
+
if (onRemoteSignOut) onRemoteSignOut();
|
|
38
|
+
else toast.info('You have been signed out remotely.');
|
|
39
|
+
logout();
|
|
40
|
+
} else {
|
|
41
|
+
refreshSessions();
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return () => {
|
|
46
|
+
socket.emit('leave', { userId: `user:${userId}` });
|
|
47
|
+
socket.off('session_update');
|
|
48
|
+
};
|
|
49
|
+
}, [userId, baseURL, activeSessionId, refreshSessions, logout, onRemoteSignOut]);
|
|
50
|
+
}
|
package/src/ui/index.ts
CHANGED
|
@@ -8,6 +8,7 @@ export { default as OxySignInButton } from './components/OxySignInButton';
|
|
|
8
8
|
export { default as OxyLogo } from './components/OxyLogo';
|
|
9
9
|
export { default as Avatar } from './components/Avatar';
|
|
10
10
|
export { default as FollowButton } from './components/FollowButton';
|
|
11
|
+
export { default as OxyPayButton } from './components/OxyPayButton';
|
|
11
12
|
export { FontLoader, setupFonts } from './components/FontLoader';
|
|
12
13
|
|
|
13
14
|
// Export icon components
|
|
@@ -21,41 +22,6 @@ export {
|
|
|
21
22
|
OxyContextProviderProps
|
|
22
23
|
} from './context/OxyContext';
|
|
23
24
|
|
|
24
|
-
// Redux store exports - NEW ARCHITECTURE
|
|
25
|
-
export {
|
|
26
|
-
setupOxyStore,
|
|
27
|
-
oxyReducers,
|
|
28
|
-
// Individual slices
|
|
29
|
-
authSlice,
|
|
30
|
-
authActions,
|
|
31
|
-
authSelectors,
|
|
32
|
-
authReducer,
|
|
33
|
-
followSlice,
|
|
34
|
-
followActions,
|
|
35
|
-
followSelectors,
|
|
36
|
-
followThunks,
|
|
37
|
-
followReducer,
|
|
38
|
-
// Action creators
|
|
39
|
-
loginStart,
|
|
40
|
-
loginSuccess,
|
|
41
|
-
loginFailure,
|
|
42
|
-
logout,
|
|
43
|
-
setFollowingStatus,
|
|
44
|
-
clearFollowError,
|
|
45
|
-
resetFollowState,
|
|
46
|
-
fetchFollowStatus,
|
|
47
|
-
toggleFollowUser,
|
|
48
|
-
// Types
|
|
49
|
-
AuthState,
|
|
50
|
-
FollowState,
|
|
51
|
-
initialAuthState,
|
|
52
|
-
initialFollowState
|
|
53
|
-
} from './store';
|
|
54
|
-
|
|
55
|
-
// Legacy store exports (deprecated)
|
|
56
|
-
export { store } from './store';
|
|
57
|
-
export type { RootState, AppDispatch } from './store';
|
|
58
|
-
|
|
59
25
|
// Export styles
|
|
60
26
|
export { fontFamilies, fontStyles } from './styles/fonts';
|
|
61
27
|
|
|
@@ -63,8 +29,7 @@ export { fontFamilies, fontStyles } from './styles/fonts';
|
|
|
63
29
|
export * from './navigation/types';
|
|
64
30
|
|
|
65
31
|
// Hooks
|
|
66
|
-
export {
|
|
67
|
-
export { default as useAuthFetch } from './hooks/useAuthFetch';
|
|
32
|
+
export { useFollow } from './hooks';
|
|
68
33
|
|
|
69
34
|
// Screens
|
|
70
35
|
export { default as ProfileScreen } from './screens/ProfileScreen';
|