@oxyhq/services 5.11.11 → 5.12.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 +48 -7
- package/lib/commonjs/core/OxyServices.js +162 -12
- package/lib/commonjs/core/OxyServices.js.map +1 -1
- package/lib/commonjs/i18n/index.js +40 -0
- package/lib/commonjs/i18n/index.js.map +1 -0
- package/lib/commonjs/i18n/locales/en-US.json +681 -0
- package/lib/commonjs/i18n/locales/es-ES.json +689 -0
- package/lib/commonjs/ui/components/FollowButton.js +1 -1
- 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/Header.js +4 -3
- package/lib/commonjs/ui/components/Header.js.map +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js +112 -105
- 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/Section.js +1 -1
- package/lib/commonjs/ui/components/StepBasedScreen.js +17 -17
- package/lib/commonjs/ui/components/StepBasedScreen.js.map +1 -1
- package/lib/commonjs/ui/components/internal/GroupedPillButtons.js +15 -3
- package/lib/commonjs/ui/components/internal/GroupedPillButtons.js.map +1 -1
- package/lib/commonjs/ui/components/internal/PinInput.js +10 -4
- package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +128 -12
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/hooks/useI18n.js +22 -0
- package/lib/commonjs/ui/hooks/useI18n.js.map +1 -0
- package/lib/commonjs/ui/navigation/OxyRouter.js +11 -131
- package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -1
- package/lib/commonjs/ui/navigation/routes.js +127 -0
- package/lib/commonjs/ui/navigation/routes.js.map +1 -0
- package/lib/commonjs/ui/navigation/types.js +7 -0
- package/lib/commonjs/ui/navigation/types.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountCenterScreen.js +55 -47
- package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js +69 -61
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +378 -37
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +52 -34
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FeedbackScreen.js +40 -36
- package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +105 -78
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PaymentGatewayScreen.js +2 -2
- package/lib/commonjs/ui/screens/PaymentGatewayScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +92 -60
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ProfileScreen.js +21 -11
- package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/RecoverAccountScreen.js +30 -8
- package/lib/commonjs/ui/screens/RecoverAccountScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SignInScreen.js +47 -26
- package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js +31 -24
- package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js +11 -7
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js +12 -6
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js +11 -7
- package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +15 -11
- package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js +19 -27
- package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +8 -4
- package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js +14 -10
- package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +7 -3
- package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/RecoverRequestStep.js +19 -14
- package/lib/commonjs/ui/screens/steps/RecoverRequestStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/RecoverResetPasswordStep.js +130 -0
- package/lib/commonjs/ui/screens/steps/RecoverResetPasswordStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/RecoverSuccessStep.js +13 -13
- package/lib/commonjs/ui/screens/steps/RecoverSuccessStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/RecoverVerifyStep.js +14 -20
- package/lib/commonjs/ui/screens/steps/RecoverVerifyStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignInPasswordStep.js +22 -8
- package/lib/commonjs/ui/screens/steps/SignInPasswordStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignInTotpStep.js +161 -0
- package/lib/commonjs/ui/screens/steps/SignInTotpStep.js.map +1 -0
- package/lib/commonjs/ui/screens/steps/SignInUsernameStep.js +12 -6
- package/lib/commonjs/ui/screens/steps/SignInUsernameStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignUpIdentityStep.js +10 -6
- package/lib/commonjs/ui/screens/steps/SignUpIdentityStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignUpSecurityStep.js +10 -6
- package/lib/commonjs/ui/screens/steps/SignUpSecurityStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignUpSummaryStep.js +34 -4
- package/lib/commonjs/ui/screens/steps/SignUpSummaryStep.js.map +1 -1
- package/lib/commonjs/ui/screens/steps/SignUpWelcomeStep.js +9 -10
- package/lib/commonjs/ui/screens/steps/SignUpWelcomeStep.js.map +1 -1
- package/lib/commonjs/ui/styles/authStyles.js +1 -2
- package/lib/commonjs/ui/styles/authStyles.js.map +1 -1
- package/lib/commonjs/utils/deviceManager.js +1 -1
- package/lib/commonjs/utils/deviceManager.js.map +1 -1
- package/lib/commonjs/utils/validationUtils.js +4 -2
- package/lib/commonjs/utils/validationUtils.js.map +1 -1
- package/lib/module/core/OxyServices.js +162 -12
- package/lib/module/core/OxyServices.js.map +1 -1
- package/lib/module/i18n/index.js +35 -0
- package/lib/module/i18n/index.js.map +1 -0
- package/lib/module/i18n/locales/en-US.json +681 -0
- package/lib/module/i18n/locales/es-ES.json +689 -0
- package/lib/module/ui/components/FollowButton.js +1 -1
- 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/Header.js +4 -3
- package/lib/module/ui/components/Header.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +111 -105
- 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 +1 -1
- package/lib/module/ui/components/StepBasedScreen.js +17 -17
- package/lib/module/ui/components/StepBasedScreen.js.map +1 -1
- package/lib/module/ui/components/internal/GroupedPillButtons.js +15 -3
- package/lib/module/ui/components/internal/GroupedPillButtons.js.map +1 -1
- package/lib/module/ui/components/internal/PinInput.js +9 -4
- package/lib/module/ui/components/internal/PinInput.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +128 -12
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/hooks/useI18n.js +18 -0
- package/lib/module/ui/hooks/useI18n.js.map +1 -0
- package/lib/module/ui/navigation/OxyRouter.js +7 -124
- package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
- package/lib/module/ui/navigation/routes.js +122 -0
- package/lib/module/ui/navigation/routes.js.map +1 -0
- package/lib/module/ui/navigation/types.js +19 -1
- package/lib/module/ui/navigation/types.js.map +1 -1
- package/lib/module/ui/screens/AccountCenterScreen.js +55 -47
- package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountOverviewScreen.js +69 -61
- package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js +378 -37
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSwitcherScreen.js +52 -34
- package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/module/ui/screens/FeedbackScreen.js +40 -36
- package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/module/ui/screens/LanguageSelectorScreen.js +107 -80
- package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
- package/lib/module/ui/screens/PaymentGatewayScreen.js +2 -2
- package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -1
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js +92 -60
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/module/ui/screens/ProfileScreen.js +21 -11
- package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/RecoverAccountScreen.js +30 -8
- package/lib/module/ui/screens/RecoverAccountScreen.js.map +1 -1
- package/lib/module/ui/screens/SignInScreen.js +47 -26
- package/lib/module/ui/screens/SignInScreen.js.map +1 -1
- package/lib/module/ui/screens/WelcomeNewUserScreen.js +31 -24
- package/lib/module/ui/screens/WelcomeNewUserScreen.js.map +1 -1
- package/lib/module/ui/screens/internal/SignInPasswordStep.js +11 -7
- package/lib/module/ui/screens/internal/SignInPasswordStep.js.map +1 -1
- package/lib/module/ui/screens/internal/SignInUsernameStep.js +12 -6
- package/lib/module/ui/screens/internal/SignInUsernameStep.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaAboutScreen.js +11 -7
- package/lib/module/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaCenterScreen.js +15 -11
- package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaFAQScreen.js +19 -27
- package/lib/module/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +8 -4
- package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaRewardsScreen.js +14 -10
- package/lib/module/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaRulesScreen.js +7 -3
- package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
- package/lib/module/ui/screens/steps/RecoverRequestStep.js +19 -14
- package/lib/module/ui/screens/steps/RecoverRequestStep.js.map +1 -1
- package/lib/module/ui/screens/steps/RecoverResetPasswordStep.js +125 -0
- package/lib/module/ui/screens/steps/RecoverResetPasswordStep.js.map +1 -0
- package/lib/module/ui/screens/steps/RecoverSuccessStep.js +13 -13
- package/lib/module/ui/screens/steps/RecoverSuccessStep.js.map +1 -1
- package/lib/module/ui/screens/steps/RecoverVerifyStep.js +14 -20
- package/lib/module/ui/screens/steps/RecoverVerifyStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignInPasswordStep.js +22 -8
- package/lib/module/ui/screens/steps/SignInPasswordStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignInTotpStep.js +156 -0
- package/lib/module/ui/screens/steps/SignInTotpStep.js.map +1 -0
- package/lib/module/ui/screens/steps/SignInUsernameStep.js +12 -6
- package/lib/module/ui/screens/steps/SignInUsernameStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignUpIdentityStep.js +10 -6
- package/lib/module/ui/screens/steps/SignUpIdentityStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignUpSecurityStep.js +10 -6
- package/lib/module/ui/screens/steps/SignUpSecurityStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignUpSummaryStep.js +34 -4
- package/lib/module/ui/screens/steps/SignUpSummaryStep.js.map +1 -1
- package/lib/module/ui/screens/steps/SignUpWelcomeStep.js +9 -10
- package/lib/module/ui/screens/steps/SignUpWelcomeStep.js.map +1 -1
- package/lib/module/ui/styles/authStyles.js +1 -2
- package/lib/module/ui/styles/authStyles.js.map +1 -1
- package/lib/module/utils/deviceManager.js +1 -1
- package/lib/module/utils/deviceManager.js.map +1 -1
- package/lib/module/utils/validationUtils.js +4 -2
- package/lib/module/utils/validationUtils.js.map +1 -1
- package/lib/typescript/core/OxyServices.d.ts +57 -3
- package/lib/typescript/core/OxyServices.d.ts.map +1 -1
- package/lib/typescript/i18n/index.d.ts +4 -0
- package/lib/typescript/i18n/index.d.ts.map +1 -0
- package/lib/typescript/models/interfaces.d.ts +4 -0
- package/lib/typescript/models/interfaces.d.ts.map +1 -1
- package/lib/typescript/ui/components/GroupedItem.d.ts.map +1 -1
- package/lib/typescript/ui/components/Header.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxyProvider.d.ts +1 -1
- package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/ui/components/ProfileCard.d.ts.map +1 -1
- package/lib/typescript/ui/components/StepBasedScreen.d.ts +2 -1
- package/lib/typescript/ui/components/StepBasedScreen.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 +6 -3
- package/lib/typescript/ui/components/internal/PinInput.d.ts.map +1 -1
- package/lib/typescript/ui/context/OxyContext.d.ts +7 -4
- package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/useI18n.d.ts +5 -0
- package/lib/typescript/ui/hooks/useI18n.d.ts.map +1 -0
- package/lib/typescript/ui/navigation/OxyRouter.d.ts.map +1 -1
- package/lib/typescript/ui/navigation/routes.d.ts +9 -0
- package/lib/typescript/ui/navigation/routes.d.ts.map +1 -0
- package/lib/typescript/ui/navigation/types.d.ts +24 -10
- 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/FeedbackScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/LanguageSelectorScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/ProfileScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts +2 -1
- package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaAboutScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaCenterScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaFAQScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaLeaderboardScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaRewardsScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaRulesScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/RecoverRequestStep.d.ts +4 -1
- package/lib/typescript/ui/screens/steps/RecoverRequestStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/RecoverResetPasswordStep.d.ts +24 -0
- package/lib/typescript/ui/screens/steps/RecoverResetPasswordStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/RecoverSuccessStep.d.ts +2 -1
- package/lib/typescript/ui/screens/steps/RecoverSuccessStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/RecoverVerifyStep.d.ts +3 -1
- package/lib/typescript/ui/screens/steps/RecoverVerifyStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignInPasswordStep.d.ts +1 -0
- package/lib/typescript/ui/screens/steps/SignInPasswordStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignInTotpStep.d.ts +19 -0
- package/lib/typescript/ui/screens/steps/SignInTotpStep.d.ts.map +1 -0
- package/lib/typescript/ui/screens/steps/SignInUsernameStep.d.ts +2 -1
- package/lib/typescript/ui/screens/steps/SignInUsernameStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignUpIdentityStep.d.ts +2 -1
- package/lib/typescript/ui/screens/steps/SignUpIdentityStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignUpSecurityStep.d.ts +2 -1
- package/lib/typescript/ui/screens/steps/SignUpSecurityStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignUpSummaryStep.d.ts +2 -1
- package/lib/typescript/ui/screens/steps/SignUpSummaryStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/steps/SignUpWelcomeStep.d.ts +2 -1
- package/lib/typescript/ui/screens/steps/SignUpWelcomeStep.d.ts.map +1 -1
- package/lib/typescript/ui/styles/authStyles.d.ts +0 -1
- package/lib/typescript/ui/styles/authStyles.d.ts.map +1 -1
- package/lib/typescript/utils/validationUtils.d.ts.map +1 -1
- package/package.json +49 -15
- package/src/core/OxyServices.ts +138 -19
- package/src/i18n/index.ts +39 -0
- package/src/i18n/locales/en-US.json +681 -0
- package/src/i18n/locales/es-ES.json +689 -0
- package/src/models/interfaces.ts +6 -1
- package/src/ui/components/FollowButton.tsx +2 -2
- package/src/ui/components/GroupedItem.tsx +2 -1
- package/src/ui/components/Header.tsx +4 -3
- package/src/ui/components/OxyProvider.tsx +107 -114
- package/src/ui/components/ProfileCard.tsx +5 -1
- package/src/ui/components/Section.tsx +1 -1
- package/src/ui/components/StepBasedScreen.tsx +17 -14
- package/src/ui/components/internal/GroupedPillButtons.tsx +10 -6
- package/src/ui/components/internal/PinInput.tsx +15 -6
- package/src/ui/context/OxyContext.tsx +123 -20
- package/src/ui/hooks/useI18n.ts +12 -0
- package/src/ui/navigation/OxyRouter.tsx +15 -134
- package/src/ui/navigation/routes.ts +153 -0
- package/src/ui/navigation/types.ts +28 -10
- package/src/ui/screens/AccountCenterScreen.tsx +47 -45
- package/src/ui/screens/AccountOverviewScreen.tsx +68 -70
- package/src/ui/screens/AccountSettingsScreen.tsx +265 -41
- package/src/ui/screens/AccountSwitcherScreen.tsx +35 -33
- package/src/ui/screens/FeedbackScreen.tsx +39 -37
- package/src/ui/screens/LanguageSelectorScreen.tsx +99 -70
- package/src/ui/screens/PaymentGatewayScreen.tsx +6 -6
- package/src/ui/screens/PremiumSubscriptionScreen.tsx +56 -54
- package/src/ui/screens/ProfileScreen.tsx +14 -8
- package/src/ui/screens/RecoverAccountScreen.tsx +29 -8
- package/src/ui/screens/SignInScreen.tsx +39 -30
- package/src/ui/screens/WelcomeNewUserScreen.tsx +31 -17
- package/src/ui/screens/internal/SignInPasswordStep.tsx +11 -8
- package/src/ui/screens/internal/SignInUsernameStep.tsx +10 -8
- package/src/ui/screens/karma/KarmaAboutScreen.tsx +23 -11
- package/src/ui/screens/karma/KarmaCenterScreen.tsx +21 -11
- package/src/ui/screens/karma/KarmaFAQScreen.tsx +15 -33
- package/src/ui/screens/karma/KarmaLeaderboardScreen.tsx +6 -4
- package/src/ui/screens/karma/KarmaRewardsScreen.tsx +28 -10
- package/src/ui/screens/karma/KarmaRulesScreen.tsx +5 -3
- package/src/ui/screens/steps/RecoverRequestStep.tsx +20 -17
- package/src/ui/screens/steps/RecoverResetPasswordStep.tsx +133 -0
- package/src/ui/screens/steps/RecoverSuccessStep.tsx +12 -19
- package/src/ui/screens/steps/RecoverVerifyStep.tsx +15 -24
- package/src/ui/screens/steps/SignInPasswordStep.tsx +19 -6
- package/src/ui/screens/steps/SignInTotpStep.tsx +129 -0
- package/src/ui/screens/steps/SignInUsernameStep.tsx +11 -10
- package/src/ui/screens/steps/SignUpIdentityStep.tsx +10 -11
- package/src/ui/screens/steps/SignUpSecurityStep.tsx +10 -11
- package/src/ui/screens/steps/SignUpSummaryStep.tsx +24 -9
- package/src/ui/screens/steps/SignUpWelcomeStep.tsx +8 -14
- package/src/ui/styles/authStyles.ts +0 -1
- package/src/utils/deviceManager.ts +1 -1
- package/src/utils/validationUtils.ts +5 -3
package/src/models/interfaces.ts
CHANGED
|
@@ -8,6 +8,11 @@ export interface User {
|
|
|
8
8
|
email?: string;
|
|
9
9
|
// Avatar file id (asset id)
|
|
10
10
|
avatar?: string;
|
|
11
|
+
// Privacy and security settings
|
|
12
|
+
privacySettings?: {
|
|
13
|
+
twoFactorEnabled?: boolean;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
};
|
|
11
16
|
name?: {
|
|
12
17
|
first?: string;
|
|
13
18
|
last?: string;
|
|
@@ -330,4 +335,4 @@ export interface DeviceSessionLogoutResponse {
|
|
|
330
335
|
export interface UpdateDeviceNameResponse {
|
|
331
336
|
message: string;
|
|
332
337
|
deviceName: string;
|
|
333
|
-
}
|
|
338
|
+
}
|
|
@@ -76,7 +76,7 @@ const FollowButton: React.FC<FollowButtonProps> = ({
|
|
|
76
76
|
event.stopPropagation?.();
|
|
77
77
|
}
|
|
78
78
|
if (disabled || isLoading) return;
|
|
79
|
-
|
|
79
|
+
|
|
80
80
|
// Press animation
|
|
81
81
|
scale.value = withTiming(0.95, { duration: 100 }, (finished) => {
|
|
82
82
|
if (finished) {
|
|
@@ -112,7 +112,7 @@ const FollowButton: React.FC<FollowButtonProps> = ({
|
|
|
112
112
|
// Animate button on follow/unfollow
|
|
113
113
|
useEffect(() => {
|
|
114
114
|
animationProgress.value = withTiming(isFollowing ? 1 : 0, { duration: 300, easing: Easing.inOut(Easing.ease) });
|
|
115
|
-
}, [isFollowing
|
|
115
|
+
}, [isFollowing]);
|
|
116
116
|
|
|
117
117
|
// Animated styles for better performance
|
|
118
118
|
const animatedButtonStyle = useAnimatedStyle(() => {
|
|
@@ -276,16 +276,17 @@ const styles = StyleSheet.create({
|
|
|
276
276
|
container: {
|
|
277
277
|
paddingTop: Platform.OS === 'ios' ? 50 : 16,
|
|
278
278
|
paddingBottom: 12,
|
|
279
|
-
position: 'absolute',
|
|
280
279
|
top: 0,
|
|
281
280
|
left: 0,
|
|
282
281
|
right: 0,
|
|
283
282
|
zIndex: 1000,
|
|
284
283
|
...Platform.select({
|
|
285
284
|
web: {
|
|
286
|
-
position: '
|
|
285
|
+
position: 'sticky' as any,
|
|
286
|
+
},
|
|
287
|
+
default: {
|
|
288
|
+
position: 'absolute',
|
|
287
289
|
},
|
|
288
|
-
default: {},
|
|
289
290
|
}),
|
|
290
291
|
},
|
|
291
292
|
content: {
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import { View, Text, StyleSheet, Dimensions, Platform, Animated, StatusBar, Keyboard, KeyboardEvent, AppState } from 'react-native';
|
|
1
|
+
import React, { useCallback, useRef, useState, useEffect, useMemo, forwardRef, useImperativeHandle } from 'react';
|
|
2
|
+
import { View, Text, StyleSheet, Platform, Animated, StatusBar, Keyboard, KeyboardEvent, AppState } from 'react-native';
|
|
4
3
|
import { SafeAreaProvider, useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
5
4
|
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
6
|
-
import type { OxyProviderProps } from '../navigation/types';
|
|
5
|
+
import type { OxyProviderProps, BottomSheetController } from '../navigation/types';
|
|
7
6
|
import { OxyContextProvider, useOxy } from '../context/OxyContext';
|
|
8
7
|
import OxyRouter from '../navigation/OxyRouter';
|
|
9
8
|
import { FontLoader, setupFonts } from './FontLoader';
|
|
@@ -36,8 +35,8 @@ const OxyProvider: React.FC<OxyProviderProps> = (props) => {
|
|
|
36
35
|
...bottomSheetProps
|
|
37
36
|
} = props;
|
|
38
37
|
|
|
39
|
-
// Create internal bottom sheet ref
|
|
40
|
-
const internalBottomSheetRef = useRef<
|
|
38
|
+
// Create typed internal bottom sheet controller ref
|
|
39
|
+
const internalBottomSheetRef = useRef<BottomSheetController>(null);
|
|
41
40
|
|
|
42
41
|
// Initialize React Query Client (use provided client or create a default one once)
|
|
43
42
|
const queryClientRef = useRef<QueryClient | null>(null);
|
|
@@ -68,6 +67,14 @@ const OxyProvider: React.FC<OxyProviderProps> = (props) => {
|
|
|
68
67
|
};
|
|
69
68
|
}, []);
|
|
70
69
|
|
|
70
|
+
// Mirror internal controller to external ref if provided (back-compat)
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (props.bottomSheetRef) {
|
|
73
|
+
props.bottomSheetRef.current = internalBottomSheetRef.current;
|
|
74
|
+
}
|
|
75
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
76
|
+
}, [props.bottomSheetRef]);
|
|
77
|
+
|
|
71
78
|
// If contextOnly is true, we just provide the context without the bottom sheet UI
|
|
72
79
|
if (contextOnly) {
|
|
73
80
|
return (
|
|
@@ -99,7 +106,7 @@ const OxyProvider: React.FC<OxyProviderProps> = (props) => {
|
|
|
99
106
|
<BottomSheetModalProvider>
|
|
100
107
|
<StatusBar translucent backgroundColor="transparent" />
|
|
101
108
|
<SafeAreaProvider>
|
|
102
|
-
<OxyBottomSheet {...bottomSheetProps}
|
|
109
|
+
<OxyBottomSheet {...bottomSheetProps} ref={internalBottomSheetRef} oxyServices={oxyServices} />
|
|
103
110
|
{children}
|
|
104
111
|
</SafeAreaProvider>
|
|
105
112
|
</BottomSheetModalProvider>
|
|
@@ -122,17 +129,19 @@ const OxyProvider: React.FC<OxyProviderProps> = (props) => {
|
|
|
122
129
|
* This is the original OxyProvider UI functionality, now extracted into its own component
|
|
123
130
|
* and reimplemented using BottomSheetModal for better Android compatibility
|
|
124
131
|
*/
|
|
125
|
-
|
|
132
|
+
type OxyBottomSheetProps = Omit<OxyProviderProps, 'children' | 'contextOnly' | 'queryClient' | 'bottomSheetRef'>;
|
|
133
|
+
|
|
134
|
+
const OxyBottomSheet = forwardRef<BottomSheetController, OxyBottomSheetProps>(({
|
|
126
135
|
oxyServices: providedOxyServices,
|
|
127
136
|
initialScreen = 'SignIn',
|
|
128
137
|
onClose,
|
|
129
138
|
onAuthenticated,
|
|
130
139
|
theme = 'light',
|
|
131
140
|
customStyles = {},
|
|
132
|
-
bottomSheetRef,
|
|
133
141
|
autoPresent = false,
|
|
134
142
|
showInternalToaster = true,
|
|
135
|
-
|
|
143
|
+
appInsets,
|
|
144
|
+
}, ref) => {
|
|
136
145
|
// Helper function to determine if native driver should be used
|
|
137
146
|
const shouldUseNativeDriver = () => {
|
|
138
147
|
return Platform.OS === 'ios';
|
|
@@ -142,96 +151,87 @@ const OxyBottomSheet: React.FC<OxyProviderProps> = ({
|
|
|
142
151
|
const oxyServices = providedOxyServices || contextOxy?.oxyServices;
|
|
143
152
|
// Use the internal ref (which is passed as a prop from OxyProvider)
|
|
144
153
|
const modalRef = useRef<BottomSheetModalRef>(null);
|
|
145
|
-
const
|
|
154
|
+
const isOpenRef = useRef(false);
|
|
155
|
+
const navigationRef = useRef<((screen: any, props?: Record<string, unknown>) => void) | null>(null);
|
|
146
156
|
// Remove contentHeight, containerWidth, and snap point state/logic
|
|
147
157
|
// Animation values - keep for content fade/slide
|
|
148
158
|
const fadeAnim = useRef(new Animated.Value(Platform.OS === 'android' ? 1 : 0)).current;
|
|
149
159
|
const slideAnim = useRef(new Animated.Value(Platform.OS === 'android' ? 0 : 50)).current;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
160
|
+
// Expose a clean, typed imperative API
|
|
161
|
+
useImperativeHandle(ref, () => ({
|
|
162
|
+
present: () => {
|
|
163
|
+
if (!isOpenRef.current) modalRef.current?.present?.();
|
|
164
|
+
},
|
|
165
|
+
dismiss: () => modalRef.current?.dismiss?.(),
|
|
166
|
+
expand: () => {
|
|
167
|
+
// Ensure presented, then animate content in
|
|
168
|
+
if (!isOpenRef.current) modalRef.current?.present?.();
|
|
169
|
+
Animated.parallel([
|
|
170
|
+
Animated.timing(fadeAnim, {
|
|
171
|
+
toValue: 1,
|
|
172
|
+
duration: 300,
|
|
173
|
+
useNativeDriver: shouldUseNativeDriver(),
|
|
174
|
+
}),
|
|
175
|
+
Animated.spring(slideAnim, {
|
|
176
|
+
toValue: 0,
|
|
177
|
+
friction: 8,
|
|
178
|
+
tension: 40,
|
|
179
|
+
useNativeDriver: shouldUseNativeDriver(),
|
|
180
|
+
}),
|
|
181
|
+
]).start();
|
|
182
|
+
},
|
|
183
|
+
collapse: () => modalRef.current?.collapse?.(),
|
|
184
|
+
snapToIndex: (index: number) => modalRef.current?.snapToIndex?.(index),
|
|
185
|
+
snapToPosition: (position: number | string) => modalRef.current?.snapToPosition?.(position as any),
|
|
186
|
+
navigate: (screen: any, props?: Record<string, any>) => {
|
|
187
|
+
if (navigationRef.current) {
|
|
188
|
+
navigationRef.current(screen, props);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
if (typeof document !== 'undefined') {
|
|
192
|
+
const event = new CustomEvent('oxy:navigate', { detail: { screen, props } });
|
|
193
|
+
document.dispatchEvent(event);
|
|
194
|
+
} else {
|
|
195
|
+
(globalThis as any).oxyNavigateEvent = { screen, props };
|
|
185
196
|
}
|
|
186
197
|
}
|
|
187
|
-
}, [
|
|
198
|
+
}), [fadeAnim, slideAnim]);
|
|
188
199
|
// Keyboard handling (unchanged)
|
|
189
200
|
const [keyboardVisible, setKeyboardVisible] = useState(false);
|
|
201
|
+
const [keyboardHeight, setKeyboardHeight] = useState(0);
|
|
190
202
|
const insets = useSafeAreaInsets();
|
|
191
203
|
useEffect(() => {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
()
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
)
|
|
204
|
+
// Use 'did' events on iOS to avoid multiple intermediate willShow updates
|
|
205
|
+
const showEvent = Platform.OS === 'ios' ? 'keyboardDidShow' : 'keyboardDidShow';
|
|
206
|
+
const hideEvent = Platform.OS === 'ios' ? 'keyboardDidHide' : 'keyboardDidHide';
|
|
207
|
+
let lastH = 0;
|
|
208
|
+
let lastTs = 0;
|
|
209
|
+
const MIN_DELTA = 8;
|
|
210
|
+
const MIN_INTERVAL = 80; // ms
|
|
211
|
+
const onShow = (e: KeyboardEvent) => {
|
|
212
|
+
const h = e?.endCoordinates?.height ?? 0;
|
|
213
|
+
const now = Date.now();
|
|
214
|
+
if (Math.abs(h - lastH) < MIN_DELTA && now - lastTs < MIN_INTERVAL) return;
|
|
215
|
+
lastH = h;
|
|
216
|
+
lastTs = now;
|
|
217
|
+
setKeyboardVisible(true);
|
|
218
|
+
setKeyboardHeight(h);
|
|
219
|
+
};
|
|
220
|
+
const onHide = () => {
|
|
221
|
+
lastH = 0;
|
|
222
|
+
lastTs = Date.now();
|
|
223
|
+
setKeyboardVisible(false);
|
|
224
|
+
setKeyboardHeight(0);
|
|
225
|
+
};
|
|
226
|
+
const showSub = Keyboard.addListener(showEvent as any, onShow as any);
|
|
227
|
+
const hideSub = Keyboard.addListener(hideEvent as any, onHide as any);
|
|
209
228
|
return () => {
|
|
210
|
-
|
|
211
|
-
|
|
229
|
+
showSub.remove();
|
|
230
|
+
hideSub.remove();
|
|
212
231
|
};
|
|
213
232
|
}, []);
|
|
214
233
|
// Present the modal when component mounts, but only if autoPresent is true
|
|
215
234
|
useEffect(() => {
|
|
216
|
-
if (bottomSheetRef && modalRef.current) {
|
|
217
|
-
// @ts-ignore
|
|
218
|
-
bottomSheetRef.current.expand = () => {
|
|
219
|
-
modalRef.current?.present();
|
|
220
|
-
Animated.parallel([
|
|
221
|
-
Animated.timing(fadeAnim, {
|
|
222
|
-
toValue: 1,
|
|
223
|
-
duration: 300,
|
|
224
|
-
useNativeDriver: shouldUseNativeDriver(),
|
|
225
|
-
}),
|
|
226
|
-
Animated.spring(slideAnim, {
|
|
227
|
-
toValue: 0,
|
|
228
|
-
friction: 8,
|
|
229
|
-
tension: 40,
|
|
230
|
-
useNativeDriver: shouldUseNativeDriver(),
|
|
231
|
-
}),
|
|
232
|
-
]).start();
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
235
|
if (autoPresent && modalRef.current) {
|
|
236
236
|
const timer = setTimeout(() => {
|
|
237
237
|
modalRef.current?.present();
|
|
@@ -251,7 +251,7 @@ const OxyBottomSheet: React.FC<OxyProviderProps> = ({
|
|
|
251
251
|
}, 100);
|
|
252
252
|
return () => clearTimeout(timer);
|
|
253
253
|
}
|
|
254
|
-
}, [
|
|
254
|
+
}, [modalRef, autoPresent]);
|
|
255
255
|
// Close the bottom sheet with animation (unchanged)
|
|
256
256
|
const handleClose = useCallback(() => {
|
|
257
257
|
Animated.timing(fadeAnim, {
|
|
@@ -266,7 +266,7 @@ const OxyBottomSheet: React.FC<OxyProviderProps> = ({
|
|
|
266
266
|
}, Platform.OS === 'android' ? 150 : 100);
|
|
267
267
|
}
|
|
268
268
|
});
|
|
269
|
-
}, [onClose
|
|
269
|
+
}, [onClose]);
|
|
270
270
|
// Handle authentication success (unchanged)
|
|
271
271
|
const handleAuthenticated = useCallback((user: any) => {
|
|
272
272
|
fadeAnim.stopAnimation();
|
|
@@ -280,7 +280,7 @@ const OxyBottomSheet: React.FC<OxyProviderProps> = ({
|
|
|
280
280
|
onClose();
|
|
281
281
|
}, 100);
|
|
282
282
|
}
|
|
283
|
-
}, [onAuthenticated, onClose
|
|
283
|
+
}, [onAuthenticated, onClose]);
|
|
284
284
|
// Backdrop rendering (unchanged)
|
|
285
285
|
const renderBackdrop = useCallback(
|
|
286
286
|
(props: BottomSheetBackdropProps) => (
|
|
@@ -293,19 +293,6 @@ const OxyBottomSheet: React.FC<OxyProviderProps> = ({
|
|
|
293
293
|
),
|
|
294
294
|
[]
|
|
295
295
|
);
|
|
296
|
-
// Memoize background style
|
|
297
|
-
const backgroundStyle = useMemo(() => {
|
|
298
|
-
const baseColor = customStyles.backgroundColor || (theme === 'light' ? '#FFFFFF' : '#121212');
|
|
299
|
-
return {
|
|
300
|
-
backgroundColor: baseColor,
|
|
301
|
-
opacity: 1,
|
|
302
|
-
...Platform.select({
|
|
303
|
-
android: { elevation: 24 },
|
|
304
|
-
})
|
|
305
|
-
};
|
|
306
|
-
}, [customStyles.backgroundColor, theme]);
|
|
307
|
-
// Handle sheet index changes (unchanged)
|
|
308
|
-
const handleSheetChanges = useCallback((index: number) => { }, []);
|
|
309
296
|
// Modernized BottomSheetModal usage
|
|
310
297
|
return (
|
|
311
298
|
<BottomSheetModal
|
|
@@ -315,8 +302,9 @@ const OxyBottomSheet: React.FC<OxyProviderProps> = ({
|
|
|
315
302
|
enablePanDownToClose
|
|
316
303
|
backdropComponent={renderBackdrop}
|
|
317
304
|
backgroundStyle={[
|
|
318
|
-
backgroundStyle,
|
|
319
305
|
{
|
|
306
|
+
borderBottomLeftRadius: 0,
|
|
307
|
+
borderBottomRightRadius: 0,
|
|
320
308
|
borderTopLeftRadius: 35,
|
|
321
309
|
borderTopRightRadius: 35,
|
|
322
310
|
}
|
|
@@ -326,27 +314,31 @@ const OxyBottomSheet: React.FC<OxyProviderProps> = ({
|
|
|
326
314
|
width: 40,
|
|
327
315
|
height: 4,
|
|
328
316
|
}}
|
|
329
|
-
|
|
317
|
+
handleStyle={{
|
|
318
|
+
position: 'absolute',
|
|
319
|
+
top: 0,
|
|
320
|
+
left: 0,
|
|
321
|
+
right: 0,
|
|
322
|
+
}}
|
|
330
323
|
style={styles.bottomSheetContainer}
|
|
331
324
|
keyboardBehavior="interactive"
|
|
332
325
|
keyboardBlurBehavior="restore"
|
|
333
|
-
android_keyboardInputMode="
|
|
326
|
+
android_keyboardInputMode="adjustPan"
|
|
334
327
|
enableOverDrag={false}
|
|
335
328
|
enableContentPanningGesture={true}
|
|
336
329
|
enableHandlePanningGesture={true}
|
|
337
330
|
overDragResistanceFactor={2.5}
|
|
338
331
|
enableBlurKeyboardOnGesture={true}
|
|
339
332
|
detached
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
}}
|
|
333
|
+
topInset={(insets?.top ?? 0) + (appInsets?.top ?? 0)}
|
|
334
|
+
bottomInset={((Platform.OS === 'android' ? (keyboardVisible ? keyboardHeight : 0) : 0)) + (appInsets?.bottom ?? 0)}
|
|
335
|
+
onChange={(index) => { isOpenRef.current = index !== -1; }}
|
|
336
|
+
onDismiss={() => { isOpenRef.current = false; }}
|
|
345
337
|
>
|
|
346
338
|
<BottomSheetScrollView
|
|
347
|
-
style={[
|
|
348
|
-
|
|
349
|
-
|
|
339
|
+
style={[styles.contentContainer]}
|
|
340
|
+
keyboardShouldPersistTaps="handled"
|
|
341
|
+
contentContainerStyle={{ paddingBottom: (insets?.bottom ?? 0) + (appInsets?.bottom ?? 0) }}
|
|
350
342
|
>
|
|
351
343
|
<View style={styles.centeredContentWrapper}>
|
|
352
344
|
<Animated.View
|
|
@@ -382,12 +374,13 @@ const OxyBottomSheet: React.FC<OxyProviderProps> = ({
|
|
|
382
374
|
)}
|
|
383
375
|
</BottomSheetModal>
|
|
384
376
|
);
|
|
385
|
-
};
|
|
377
|
+
});
|
|
386
378
|
|
|
387
379
|
const styles = StyleSheet.create({
|
|
388
380
|
bottomSheetContainer: {
|
|
389
381
|
maxWidth: 800,
|
|
390
382
|
width: '100%',
|
|
383
|
+
alignSelf: 'center',
|
|
391
384
|
marginHorizontal: 'auto',
|
|
392
385
|
},
|
|
393
386
|
contentContainer: {
|
|
@@ -397,7 +390,7 @@ const styles = StyleSheet.create({
|
|
|
397
390
|
},
|
|
398
391
|
centeredContentWrapper: {
|
|
399
392
|
width: '100%',
|
|
400
|
-
|
|
393
|
+
alignSelf: 'center',
|
|
401
394
|
},
|
|
402
395
|
animatedContent: {
|
|
403
396
|
width: '100%',
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
|
|
3
3
|
import { Ionicons } from '@expo/vector-icons';
|
|
4
|
+
import { useI18n } from '../hooks/useI18n';
|
|
4
5
|
import Avatar from './Avatar';
|
|
5
6
|
import { useOxy } from '../context/OxyContext';
|
|
6
7
|
import { fontFamilies } from '../styles/fonts';
|
|
@@ -27,6 +28,7 @@ const ProfileCard: React.FC<ProfileCardProps> = ({
|
|
|
27
28
|
}) => {
|
|
28
29
|
const isDarkTheme = theme === 'dark';
|
|
29
30
|
const { oxyServices } = useOxy();
|
|
31
|
+
const { t } = useI18n();
|
|
30
32
|
const textColor = isDarkTheme ? '#FFFFFF' : '#000000';
|
|
31
33
|
const secondaryBackgroundColor = isDarkTheme ? '#222222' : '#FFFFFF';
|
|
32
34
|
const primaryColor = '#0066CC';
|
|
@@ -58,7 +60,9 @@ const ProfileCard: React.FC<ProfileCardProps> = ({
|
|
|
58
60
|
style={styles.editProfileButton}
|
|
59
61
|
onPress={onEditPress}
|
|
60
62
|
>
|
|
61
|
-
<Text style={[styles.editProfileText, { color: primaryColor }]}>
|
|
63
|
+
<Text style={[styles.editProfileText, { color: primaryColor }]}>
|
|
64
|
+
{t('editProfile.title') || 'Edit Profile'}
|
|
65
|
+
</Text>
|
|
62
66
|
</TouchableOpacity>
|
|
63
67
|
)}
|
|
64
68
|
</View>
|
|
@@ -21,6 +21,7 @@ import Animated, {
|
|
|
21
21
|
} from 'react-native-reanimated';
|
|
22
22
|
import { useThemeColors, createAuthStyles } from '../styles';
|
|
23
23
|
import type { BaseScreenProps } from '../navigation/types';
|
|
24
|
+
import type { RouteName } from '../navigation/routes';
|
|
24
25
|
|
|
25
26
|
export interface StepConfig {
|
|
26
27
|
id: string;
|
|
@@ -39,7 +40,7 @@ export interface StepBasedScreenProps extends Omit<BaseScreenProps, 'navigate'>
|
|
|
39
40
|
onStepChange?: (currentStep: number, totalSteps: number) => void;
|
|
40
41
|
onComplete?: (stepData: any[]) => void;
|
|
41
42
|
stepData?: any[];
|
|
42
|
-
navigate: (screen:
|
|
43
|
+
navigate: (screen: RouteName, props?: Record<string, any>) => void;
|
|
43
44
|
oxyServices: any; // Required services for step components
|
|
44
45
|
}
|
|
45
46
|
|
|
@@ -128,7 +129,6 @@ const StepBasedScreen: React.FC<StepBasedScreenProps> = ({
|
|
|
128
129
|
lineHeight: 50.4, // 42 * 1.2
|
|
129
130
|
marginBottom: 12,
|
|
130
131
|
textAlign: 'left' as const,
|
|
131
|
-
letterSpacing: -0.5,
|
|
132
132
|
},
|
|
133
133
|
modernSubtitle: {
|
|
134
134
|
fontSize: 18,
|
|
@@ -138,7 +138,6 @@ const StepBasedScreen: React.FC<StepBasedScreenProps> = ({
|
|
|
138
138
|
},
|
|
139
139
|
modernInputContainer: {
|
|
140
140
|
width: '100%',
|
|
141
|
-
marginBottom: 24,
|
|
142
141
|
},
|
|
143
142
|
button: {
|
|
144
143
|
flexDirection: 'row' as const,
|
|
@@ -237,18 +236,22 @@ const StepBasedScreen: React.FC<StepBasedScreenProps> = ({
|
|
|
237
236
|
withTiming(0.95, { duration: 50 })
|
|
238
237
|
);
|
|
239
238
|
|
|
239
|
+
// Define a JS function for runOnJS to avoid inline closures
|
|
240
|
+
const applyStepChange = (targetStep: number, totalSteps: number) => {
|
|
241
|
+
setState(prev => ({
|
|
242
|
+
...prev,
|
|
243
|
+
currentStep: targetStep,
|
|
244
|
+
isTransitioning: false,
|
|
245
|
+
}));
|
|
246
|
+
onStepChangeRef.current?.(targetStep, totalSteps);
|
|
247
|
+
};
|
|
248
|
+
|
|
240
249
|
fadeAnim.value = withSequence(
|
|
241
250
|
withTiming(0, { duration: 200 }),
|
|
242
251
|
withTiming(0, { duration: 50 }, (finished) => {
|
|
243
252
|
if (finished) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
...prev,
|
|
247
|
-
currentStep: nextStep,
|
|
248
|
-
isTransitioning: false
|
|
249
|
-
}));
|
|
250
|
-
onStepChangeRef.current?.(nextStep, steps.length);
|
|
251
|
-
})();
|
|
253
|
+
// Call back to JS thread correctly
|
|
254
|
+
runOnJS(applyStepChange)(nextStep, steps.length);
|
|
252
255
|
|
|
253
256
|
// Reset animations with proper timing
|
|
254
257
|
slideAnim.value = withDelay(16, withTiming(-50, { duration: 0 }));
|
|
@@ -267,7 +270,7 @@ const StepBasedScreen: React.FC<StepBasedScreenProps> = ({
|
|
|
267
270
|
}
|
|
268
271
|
})
|
|
269
272
|
);
|
|
270
|
-
}, [
|
|
273
|
+
}, [enableAnimations, steps.length]);
|
|
271
274
|
|
|
272
275
|
// Navigation functions
|
|
273
276
|
const nextStep = useCallback(() => {
|
|
@@ -372,8 +375,8 @@ const StepBasedScreen: React.FC<StepBasedScreenProps> = ({
|
|
|
372
375
|
|
|
373
376
|
return (
|
|
374
377
|
<KeyboardAvoidingView
|
|
375
|
-
style={[styles.container
|
|
376
|
-
behavior={
|
|
378
|
+
style={[styles.container]}
|
|
379
|
+
behavior={undefined}
|
|
377
380
|
>
|
|
378
381
|
<StatusBar
|
|
379
382
|
barStyle={theme === 'dark' ? 'light-content' : 'dark-content'}
|
|
@@ -32,6 +32,7 @@ const GroupedPillButtons: React.FC<GroupedPillButtonsProps> = ({
|
|
|
32
32
|
gap: 6,
|
|
33
33
|
minWidth: 70,
|
|
34
34
|
borderWidth: 1,
|
|
35
|
+
flexShrink: 0,
|
|
35
36
|
...Platform.select({
|
|
36
37
|
web: {
|
|
37
38
|
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
|
@@ -122,7 +123,8 @@ const GroupedPillButtons: React.FC<GroupedPillButtonsProps> = ({
|
|
|
122
123
|
const baseTextStyle = {
|
|
123
124
|
fontSize: 15,
|
|
124
125
|
fontWeight: '600' as const,
|
|
125
|
-
|
|
126
|
+
// Avoid stretching that can cause wraps on native
|
|
127
|
+
flexShrink: 1,
|
|
126
128
|
};
|
|
127
129
|
|
|
128
130
|
let textColor = colors.text;
|
|
@@ -140,6 +142,7 @@ const GroupedPillButtons: React.FC<GroupedPillButtonsProps> = ({
|
|
|
140
142
|
return {
|
|
141
143
|
...baseTextStyle,
|
|
142
144
|
color: textColor,
|
|
145
|
+
...(Platform.OS === 'web' ? { whiteSpace: 'nowrap' as any } : null),
|
|
143
146
|
};
|
|
144
147
|
};
|
|
145
148
|
|
|
@@ -155,7 +158,8 @@ const GroupedPillButtons: React.FC<GroupedPillButtonsProps> = ({
|
|
|
155
158
|
};
|
|
156
159
|
|
|
157
160
|
const isBackButton = (button: ButtonConfig) => {
|
|
158
|
-
|
|
161
|
+
const text = typeof button.text === 'string' ? button.text.toLowerCase() : '';
|
|
162
|
+
return text.includes('back') ||
|
|
159
163
|
button.icon === 'arrow-back' ||
|
|
160
164
|
button.icon === 'chevron-back';
|
|
161
165
|
};
|
|
@@ -180,7 +184,7 @@ const GroupedPillButtons: React.FC<GroupedPillButtonsProps> = ({
|
|
|
180
184
|
// Single button: icon on right
|
|
181
185
|
return (
|
|
182
186
|
<>
|
|
183
|
-
<Text style={getTextStyle(button, colors)}>
|
|
187
|
+
<Text style={getTextStyle(button, colors)} numberOfLines={1} ellipsizeMode="tail">
|
|
184
188
|
{button.text}
|
|
185
189
|
</Text>
|
|
186
190
|
{button.icon && (
|
|
@@ -203,7 +207,7 @@ const GroupedPillButtons: React.FC<GroupedPillButtonsProps> = ({
|
|
|
203
207
|
color={iconColor}
|
|
204
208
|
/>
|
|
205
209
|
)}
|
|
206
|
-
<Text style={getTextStyle(button, colors)}>
|
|
210
|
+
<Text style={getTextStyle(button, colors)} numberOfLines={1} ellipsizeMode="tail">
|
|
207
211
|
{button.text}
|
|
208
212
|
</Text>
|
|
209
213
|
</>
|
|
@@ -212,7 +216,7 @@ const GroupedPillButtons: React.FC<GroupedPillButtonsProps> = ({
|
|
|
212
216
|
// Second button or forward/action button: text on left, icon on right
|
|
213
217
|
return (
|
|
214
218
|
<>
|
|
215
|
-
<Text style={getTextStyle(button, colors)}>
|
|
219
|
+
<Text style={getTextStyle(button, colors)} numberOfLines={1} ellipsizeMode="tail">
|
|
216
220
|
{button.text}
|
|
217
221
|
</Text>
|
|
218
222
|
{button.icon && (
|
|
@@ -254,4 +258,4 @@ const styles = StyleSheet.create({
|
|
|
254
258
|
},
|
|
255
259
|
});
|
|
256
260
|
|
|
257
|
-
export default GroupedPillButtons;
|
|
261
|
+
export default GroupedPillButtons;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { useRef } from 'react';
|
|
1
|
+
import React, { useRef, forwardRef, useImperativeHandle } from 'react';
|
|
3
2
|
import { View, TextInput, StyleSheet, Platform, type NativeSyntheticEvent, type TextInputKeyPressEventData } from 'react-native';
|
|
4
3
|
|
|
5
4
|
interface PinInputColors {
|
|
@@ -11,7 +10,7 @@ interface PinInputColors {
|
|
|
11
10
|
border: string;
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
interface PinInputProps {
|
|
13
|
+
export interface PinInputProps {
|
|
15
14
|
value: string;
|
|
16
15
|
onChange: (val: string) => void;
|
|
17
16
|
length?: number;
|
|
@@ -20,9 +19,19 @@ interface PinInputProps {
|
|
|
20
19
|
colors: PinInputColors;
|
|
21
20
|
}
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
export interface PinInputHandle {
|
|
23
|
+
focus: () => void;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const PinInput = forwardRef<PinInputHandle, PinInputProps>(({ value, onChange, length = 6, disabled, autoFocus, colors }, ref) => {
|
|
24
27
|
const inputs = useRef<Array<TextInput | null>>([]);
|
|
25
28
|
|
|
29
|
+
useImperativeHandle(ref, () => ({
|
|
30
|
+
focus: () => {
|
|
31
|
+
inputs.current[0]?.focus();
|
|
32
|
+
}
|
|
33
|
+
}), []);
|
|
34
|
+
|
|
26
35
|
const handleChange = (text: string, idx: number) => {
|
|
27
36
|
if (!/^[0-9]*$/.test(text)) return;
|
|
28
37
|
let newValue = value.split('');
|
|
@@ -74,7 +83,7 @@ const PinInput: React.FC<PinInputProps> = ({ value, onChange, length = 6, disabl
|
|
|
74
83
|
))}
|
|
75
84
|
</View>
|
|
76
85
|
);
|
|
77
|
-
};
|
|
86
|
+
});
|
|
78
87
|
|
|
79
88
|
const styles = StyleSheet.create({
|
|
80
89
|
pinContainer: {
|
|
@@ -109,4 +118,4 @@ const styles = StyleSheet.create({
|
|
|
109
118
|
},
|
|
110
119
|
});
|
|
111
120
|
|
|
112
|
-
export default PinInput;
|
|
121
|
+
export default PinInput;
|