@oxyhq/services 5.10.15 → 5.11.1
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 +604 -127
- package/lib/commonjs/assets/assets/icons/OxyServices.tsx +2 -2
- package/lib/commonjs/assets/assets/illustrations/HighFive.tsx +1 -1
- package/lib/commonjs/assets/icons/OxyServices.js +0 -2
- package/lib/commonjs/assets/icons/OxyServices.js.map +1 -1
- package/lib/commonjs/assets/illustrations/HighFive.js +0 -2
- package/lib/commonjs/assets/illustrations/HighFive.js.map +1 -1
- package/lib/commonjs/core/OxyServices.js +244 -26
- package/lib/commonjs/core/OxyServices.js.map +1 -1
- package/lib/commonjs/core/index.js +7 -0
- package/lib/commonjs/core/index.js.map +1 -1
- package/lib/commonjs/index.js +93 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/lib/sonner-safe.js +2 -0
- package/lib/commonjs/lib/sonner-safe.js.map +1 -1
- package/lib/commonjs/lib/sonner.js +2 -0
- package/lib/commonjs/lib/sonner.js.map +1 -1
- package/lib/commonjs/node/index.js +7 -0
- package/lib/commonjs/node/index.js.map +1 -1
- package/lib/commonjs/ui/components/Avatar.js +0 -2
- package/lib/commonjs/ui/components/Avatar.js.map +1 -1
- package/lib/commonjs/ui/components/FollowButton.js +4 -4
- package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
- package/lib/commonjs/ui/components/FontLoader.js +3 -2
- package/lib/commonjs/ui/components/FontLoader.js.map +1 -1
- package/lib/commonjs/ui/components/GroupedItem.js +7 -4
- package/lib/commonjs/ui/components/GroupedItem.js.map +1 -1
- package/lib/commonjs/ui/components/GroupedSection.js +1 -1
- package/lib/commonjs/ui/components/GroupedSection.js.map +1 -1
- package/lib/commonjs/ui/components/Header.js +0 -1
- package/lib/commonjs/ui/components/Header.js.map +1 -1
- package/lib/commonjs/ui/components/OxyLogo.js +0 -2
- package/lib/commonjs/ui/components/OxyLogo.js.map +1 -1
- package/lib/commonjs/ui/components/OxyPayButton.js +4 -5
- package/lib/commonjs/ui/components/OxyPayButton.js.map +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js +4 -3
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/OxySignInButton.js +0 -1
- package/lib/commonjs/ui/components/OxySignInButton.js.map +1 -1
- package/lib/commonjs/ui/components/ProfileCard.js +0 -1
- package/lib/commonjs/ui/components/ProfileCard.js.map +1 -1
- package/lib/commonjs/ui/components/QuickActions.js +0 -2
- package/lib/commonjs/ui/components/QuickActions.js.map +1 -1
- package/lib/commonjs/ui/components/Section.js +0 -1
- package/lib/commonjs/ui/components/Section.js.map +1 -1
- package/lib/commonjs/ui/components/SectionTitle.js +0 -2
- package/lib/commonjs/ui/components/SectionTitle.js.map +1 -1
- package/lib/commonjs/ui/components/icon/FAIRWalletIcon.js +0 -2
- package/lib/commonjs/ui/components/icon/FAIRWalletIcon.js.map +1 -1
- package/lib/commonjs/ui/components/icon/OxyIcon.js +0 -2
- package/lib/commonjs/ui/components/icon/OxyIcon.js.map +1 -1
- package/lib/commonjs/ui/components/internal/GroupedPillButtons.js +0 -2
- package/lib/commonjs/ui/components/internal/GroupedPillButtons.js.map +1 -1
- package/lib/commonjs/ui/components/internal/PinInput.js +4 -3
- package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -1
- package/lib/commonjs/ui/components/internal/TextField.js +3 -3
- package/lib/commonjs/ui/components/internal/TextField.js.map +1 -1
- package/lib/commonjs/ui/hooks/useAssets.js +263 -0
- package/lib/commonjs/ui/hooks/useAssets.js.map +1 -0
- package/lib/commonjs/ui/navigation/OxyRouter.js +1 -2
- package/lib/commonjs/ui/navigation/OxyRouter.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountCenterScreen.js +0 -2
- package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountManagementDemo.js +0 -1
- package/lib/commonjs/ui/screens/AccountManagementDemo.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +2 -2
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +5 -6
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AppInfoScreen.js +1 -2
- package/lib/commonjs/ui/screens/AppInfoScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FileManagementScreen.js +631 -430
- package/lib/commonjs/ui/screens/FileManagementScreen.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 +1 -2
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ProfileScreen.js +1 -2
- package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/RecoverAccountScreen.js +1 -2
- package/lib/commonjs/ui/screens/RecoverAccountScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SessionManagementScreen.js +1 -2
- package/lib/commonjs/ui/screens/SessionManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SignInScreen.js +1 -2
- package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/UserLinksScreen.js +0 -2
- package/lib/commonjs/ui/screens/UserLinksScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js +1 -2
- package/lib/commonjs/ui/screens/internal/SignInPasswordStep.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js +1 -2
- package/lib/commonjs/ui/screens/internal/SignInUsernameStep.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignUpIdentityStep.js +1 -2
- package/lib/commonjs/ui/screens/internal/SignUpIdentityStep.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignUpSecurityStep.js +1 -2
- package/lib/commonjs/ui/screens/internal/SignUpSecurityStep.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignUpSummaryStep.js +0 -1
- package/lib/commonjs/ui/screens/internal/SignUpSummaryStep.js.map +1 -1
- package/lib/commonjs/ui/screens/internal/SignUpWelcomeStep.js +0 -1
- package/lib/commonjs/ui/screens/internal/SignUpWelcomeStep.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js +0 -2
- package/lib/commonjs/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +1 -2
- package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +1 -2
- package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js +0 -2
- package/lib/commonjs/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +1 -2
- package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
- package/lib/commonjs/ui/stores/assetStore.js +225 -0
- package/lib/commonjs/ui/stores/assetStore.js.map +1 -0
- package/lib/commonjs/ui/stores/authStore.js +1 -1
- package/lib/commonjs/ui/stores/authStore.js.map +1 -1
- package/lib/commonjs/ui/stores/fileStore.js +153 -0
- package/lib/commonjs/ui/stores/fileStore.js.map +1 -0
- package/lib/commonjs/ui/stores/followStore.js +2 -2
- package/lib/commonjs/ui/stores/followStore.js.map +1 -1
- package/lib/commonjs/utils/asyncUtils.js +1 -1
- package/lib/commonjs/utils/asyncUtils.js.map +1 -1
- package/lib/commonjs/utils/errorUtils.js +19 -11
- package/lib/commonjs/utils/errorUtils.js.map +1 -1
- package/lib/commonjs/utils/hookUtils.js +1 -1
- package/lib/commonjs/utils/hookUtils.js.map +1 -1
- package/lib/commonjs/utils/loggerUtils.js.map +1 -1
- package/lib/commonjs/utils/validationUtils.js +2 -2
- package/lib/commonjs/utils/validationUtils.js.map +1 -1
- package/lib/module/assets/assets/icons/OxyServices.tsx +2 -2
- package/lib/module/assets/assets/illustrations/HighFive.tsx +1 -1
- package/lib/module/assets/icons/OxyServices.js +0 -1
- package/lib/module/assets/icons/OxyServices.js.map +1 -1
- package/lib/module/assets/illustrations/HighFive.js +0 -1
- package/lib/module/assets/illustrations/HighFive.js.map +1 -1
- package/lib/module/core/OxyServices.js +243 -25
- package/lib/module/core/OxyServices.js.map +1 -1
- package/lib/module/core/index.js +1 -1
- package/lib/module/core/index.js.map +1 -1
- package/lib/module/index.js +3 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/lib/sonner-safe.js +2 -0
- package/lib/module/lib/sonner-safe.js.map +1 -1
- package/lib/module/lib/sonner.js +3 -0
- package/lib/module/lib/sonner.js.map +1 -1
- package/lib/module/node/index.js +2 -2
- package/lib/module/node/index.js.map +1 -1
- package/lib/module/ui/components/Avatar.js +0 -1
- package/lib/module/ui/components/Avatar.js.map +1 -1
- package/lib/module/ui/components/FollowButton.js +4 -3
- package/lib/module/ui/components/FollowButton.js.map +1 -1
- package/lib/module/ui/components/FontLoader.js +3 -2
- package/lib/module/ui/components/FontLoader.js.map +1 -1
- package/lib/module/ui/components/GroupedItem.js +7 -3
- package/lib/module/ui/components/GroupedItem.js.map +1 -1
- package/lib/module/ui/components/GroupedSection.js +1 -1
- package/lib/module/ui/components/GroupedSection.js.map +1 -1
- package/lib/module/ui/components/Header.js +0 -1
- package/lib/module/ui/components/Header.js.map +1 -1
- package/lib/module/ui/components/OxyLogo.js +0 -1
- package/lib/module/ui/components/OxyLogo.js.map +1 -1
- package/lib/module/ui/components/OxyPayButton.js +4 -4
- package/lib/module/ui/components/OxyPayButton.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +4 -2
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/OxySignInButton.js +0 -1
- package/lib/module/ui/components/OxySignInButton.js.map +1 -1
- package/lib/module/ui/components/ProfileCard.js +0 -1
- package/lib/module/ui/components/ProfileCard.js.map +1 -1
- package/lib/module/ui/components/QuickActions.js +0 -1
- package/lib/module/ui/components/QuickActions.js.map +1 -1
- package/lib/module/ui/components/Section.js +0 -1
- package/lib/module/ui/components/Section.js.map +1 -1
- package/lib/module/ui/components/SectionTitle.js +0 -1
- package/lib/module/ui/components/SectionTitle.js.map +1 -1
- package/lib/module/ui/components/icon/FAIRWalletIcon.js +0 -1
- package/lib/module/ui/components/icon/FAIRWalletIcon.js.map +1 -1
- package/lib/module/ui/components/icon/OxyIcon.js +0 -1
- package/lib/module/ui/components/icon/OxyIcon.js.map +1 -1
- package/lib/module/ui/components/internal/GroupedPillButtons.js +0 -1
- package/lib/module/ui/components/internal/GroupedPillButtons.js.map +1 -1
- package/lib/module/ui/components/internal/PinInput.js +4 -2
- package/lib/module/ui/components/internal/PinInput.js.map +1 -1
- package/lib/module/ui/components/internal/TextField.js +3 -3
- package/lib/module/ui/components/internal/TextField.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/hooks/useAssets.js +257 -0
- package/lib/module/ui/hooks/useAssets.js.map +1 -0
- package/lib/module/ui/navigation/OxyRouter.js +1 -1
- package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
- package/lib/module/ui/screens/AccountCenterScreen.js +0 -1
- package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountManagementDemo.js +0 -1
- package/lib/module/ui/screens/AccountManagementDemo.js.map +1 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js +2 -2
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSwitcherScreen.js +5 -5
- package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/module/ui/screens/AppInfoScreen.js +1 -1
- package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
- package/lib/module/ui/screens/FileManagementScreen.js +633 -432
- package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/PaymentGatewayScreen.js +1 -1
- package/lib/module/ui/screens/PaymentGatewayScreen.js.map +1 -1
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js +1 -1
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/module/ui/screens/ProfileScreen.js +1 -1
- package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/RecoverAccountScreen.js +1 -1
- package/lib/module/ui/screens/RecoverAccountScreen.js.map +1 -1
- package/lib/module/ui/screens/SessionManagementScreen.js +1 -1
- package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/SignInScreen.js +1 -1
- package/lib/module/ui/screens/SignInScreen.js.map +1 -1
- package/lib/module/ui/screens/UserLinksScreen.js +0 -1
- package/lib/module/ui/screens/UserLinksScreen.js.map +1 -1
- package/lib/module/ui/screens/internal/SignInPasswordStep.js +1 -1
- package/lib/module/ui/screens/internal/SignInPasswordStep.js.map +1 -1
- package/lib/module/ui/screens/internal/SignInUsernameStep.js +1 -1
- package/lib/module/ui/screens/internal/SignInUsernameStep.js.map +1 -1
- package/lib/module/ui/screens/internal/SignUpIdentityStep.js +1 -1
- package/lib/module/ui/screens/internal/SignUpIdentityStep.js.map +1 -1
- package/lib/module/ui/screens/internal/SignUpSecurityStep.js +1 -1
- package/lib/module/ui/screens/internal/SignUpSecurityStep.js.map +1 -1
- package/lib/module/ui/screens/internal/SignUpSummaryStep.js +0 -1
- package/lib/module/ui/screens/internal/SignUpSummaryStep.js.map +1 -1
- package/lib/module/ui/screens/internal/SignUpWelcomeStep.js +0 -1
- package/lib/module/ui/screens/internal/SignUpWelcomeStep.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaAboutScreen.js +0 -1
- package/lib/module/ui/screens/karma/KarmaAboutScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaCenterScreen.js +1 -1
- package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +1 -1
- package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaRewardsScreen.js +0 -1
- package/lib/module/ui/screens/karma/KarmaRewardsScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaRulesScreen.js +1 -1
- package/lib/module/ui/screens/karma/KarmaRulesScreen.js.map +1 -1
- package/lib/module/ui/stores/assetStore.js +212 -0
- package/lib/module/ui/stores/assetStore.js.map +1 -0
- package/lib/module/ui/stores/authStore.js +1 -1
- package/lib/module/ui/stores/authStore.js.map +1 -1
- package/lib/module/ui/stores/fileStore.js +145 -0
- package/lib/module/ui/stores/fileStore.js.map +1 -0
- package/lib/module/ui/stores/followStore.js +2 -2
- package/lib/module/ui/stores/followStore.js.map +1 -1
- package/lib/module/ui/styles/fonts.js.map +1 -1
- package/lib/module/ui/styles/theme.js.map +1 -1
- package/lib/module/utils/asyncUtils.js +1 -1
- package/lib/module/utils/asyncUtils.js.map +1 -1
- package/lib/module/utils/errorUtils.js +19 -11
- package/lib/module/utils/errorUtils.js.map +1 -1
- package/lib/module/utils/hookUtils.js +1 -1
- package/lib/module/utils/hookUtils.js.map +1 -1
- package/lib/module/utils/loggerUtils.js.map +1 -1
- package/lib/module/utils/validationUtils.js +2 -2
- package/lib/module/utils/validationUtils.js.map +1 -1
- package/lib/typescript/assets/icons/OxyServices.d.ts +2 -2
- package/lib/typescript/assets/icons/OxyServices.d.ts.map +1 -1
- package/lib/typescript/assets/illustrations/HighFive.d.ts +1 -1
- package/lib/typescript/assets/illustrations/HighFive.d.ts.map +1 -1
- package/lib/typescript/core/OxyServices.d.ts +69 -12
- package/lib/typescript/core/OxyServices.d.ts.map +1 -1
- package/lib/typescript/core/index.d.ts +1 -1
- package/lib/typescript/core/index.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +4 -2
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/lib/sonner-safe.d.ts +2 -1
- package/lib/typescript/lib/sonner-safe.d.ts.map +1 -1
- package/lib/typescript/lib/sonner.d.ts +11 -3
- package/lib/typescript/lib/sonner.d.ts.map +1 -1
- package/lib/typescript/models/interfaces.d.ts +105 -6
- package/lib/typescript/models/interfaces.d.ts.map +1 -1
- package/lib/typescript/node/index.d.ts +2 -2
- package/lib/typescript/node/index.d.ts.map +1 -1
- package/lib/typescript/types/expo-vector-icons.d.ts +8 -1
- package/lib/typescript/types/express.d.ts +22 -3
- package/lib/typescript/ui/components/Avatar.d.ts +2 -2
- package/lib/typescript/ui/components/Avatar.d.ts.map +1 -1
- package/lib/typescript/ui/components/FollowButton.d.ts +2 -2
- package/lib/typescript/ui/components/FollowButton.d.ts.map +1 -1
- package/lib/typescript/ui/components/FontLoader.d.ts +1 -1
- package/lib/typescript/ui/components/FontLoader.d.ts.map +1 -1
- package/lib/typescript/ui/components/GroupedItem.d.ts +2 -1
- package/lib/typescript/ui/components/GroupedItem.d.ts.map +1 -1
- package/lib/typescript/ui/components/GroupedSection.d.ts +2 -1
- package/lib/typescript/ui/components/GroupedSection.d.ts.map +1 -1
- package/lib/typescript/ui/components/Header.d.ts +1 -1
- package/lib/typescript/ui/components/Header.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxyLogo.d.ts +2 -2
- package/lib/typescript/ui/components/OxyLogo.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxyPayButton.d.ts +2 -2
- package/lib/typescript/ui/components/OxyPayButton.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxyProvider.d.ts +2 -2
- package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxySignInButton.d.ts +2 -2
- package/lib/typescript/ui/components/OxySignInButton.d.ts.map +1 -1
- package/lib/typescript/ui/components/ProfileCard.d.ts +1 -1
- package/lib/typescript/ui/components/ProfileCard.d.ts.map +1 -1
- package/lib/typescript/ui/components/QuickActions.d.ts +1 -1
- package/lib/typescript/ui/components/QuickActions.d.ts.map +1 -1
- package/lib/typescript/ui/components/Section.d.ts +1 -1
- package/lib/typescript/ui/components/Section.d.ts.map +1 -1
- package/lib/typescript/ui/components/SectionTitle.d.ts +1 -1
- package/lib/typescript/ui/components/SectionTitle.d.ts.map +1 -1
- package/lib/typescript/ui/components/icon/FAIRWalletIcon.d.ts +1 -1
- package/lib/typescript/ui/components/icon/FAIRWalletIcon.d.ts.map +1 -1
- package/lib/typescript/ui/components/icon/OxyIcon.d.ts +1 -1
- package/lib/typescript/ui/components/icon/OxyIcon.d.ts.map +1 -1
- package/lib/typescript/ui/components/internal/GroupedPillButtons.d.ts +1 -1
- package/lib/typescript/ui/components/internal/GroupedPillButtons.d.ts.map +1 -1
- package/lib/typescript/ui/components/internal/PinInput.d.ts +1 -1
- package/lib/typescript/ui/components/internal/PinInput.d.ts.map +1 -1
- package/lib/typescript/ui/components/internal/TextField.d.ts +1 -1
- package/lib/typescript/ui/components/internal/TextField.d.ts.map +1 -1
- package/lib/typescript/ui/context/OxyContext.d.ts +3 -3
- package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/useAssets.d.ts +35 -0
- package/lib/typescript/ui/hooks/useAssets.d.ts.map +1 -0
- package/lib/typescript/ui/navigation/OxyRouter.d.ts +2 -2
- package/lib/typescript/ui/navigation/OxyRouter.d.ts.map +1 -1
- package/lib/typescript/ui/navigation/types.d.ts +7 -7
- package/lib/typescript/ui/navigation/types.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountCenterScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/AccountCenterScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountManagementDemo.d.ts +1 -1
- package/lib/typescript/ui/screens/AccountManagementDemo.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts +1 -1
- package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts +1 -1
- package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/AccountSwitcherScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AppInfoScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/AppInfoScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/FeedbackScreen.d.ts +1 -1
- package/lib/typescript/ui/screens/FeedbackScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/FileManagementScreen.d.ts +1 -1
- package/lib/typescript/ui/screens/FileManagementScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/PaymentGatewayScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/PaymentGatewayScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/PremiumSubscriptionScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/ProfileScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/ProfileScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts +1 -1
- package/lib/typescript/ui/screens/RecoverAccountScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SessionManagementScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/SessionManagementScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SignInScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SignUpScreen.d.ts +1 -1
- package/lib/typescript/ui/screens/SignUpScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/UserLinksScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/UserLinksScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts +1 -1
- package/lib/typescript/ui/screens/internal/SignInPasswordStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts +1 -1
- package/lib/typescript/ui/screens/internal/SignInUsernameStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignUpIdentityStep.d.ts +1 -1
- package/lib/typescript/ui/screens/internal/SignUpIdentityStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignUpSecurityStep.d.ts +1 -1
- package/lib/typescript/ui/screens/internal/SignUpSecurityStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignUpSummaryStep.d.ts +1 -1
- package/lib/typescript/ui/screens/internal/SignUpSummaryStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/internal/SignUpWelcomeStep.d.ts +1 -1
- package/lib/typescript/ui/screens/internal/SignUpWelcomeStep.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaAboutScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/karma/KarmaAboutScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaCenterScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/karma/KarmaCenterScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaFAQScreen.d.ts +1 -1
- package/lib/typescript/ui/screens/karma/KarmaFAQScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaLeaderboardScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/karma/KarmaLeaderboardScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaRewardsScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/karma/KarmaRewardsScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaRulesScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/karma/KarmaRulesScreen.d.ts.map +1 -1
- package/lib/typescript/ui/stores/assetStore.d.ts +54 -0
- package/lib/typescript/ui/stores/assetStore.d.ts.map +1 -0
- package/lib/typescript/ui/stores/fileStore.d.ts +31 -0
- package/lib/typescript/ui/stores/fileStore.d.ts.map +1 -0
- package/lib/typescript/ui/stores/followStore.d.ts +1 -1
- package/lib/typescript/ui/stores/followStore.d.ts.map +1 -1
- package/lib/typescript/ui/styles/fonts.d.ts +1 -1
- package/lib/typescript/ui/styles/fonts.d.ts.map +1 -1
- package/lib/typescript/ui/styles/theme.d.ts +1 -1
- package/lib/typescript/ui/styles/theme.d.ts.map +1 -1
- package/lib/typescript/utils/asyncUtils.d.ts.map +1 -1
- package/lib/typescript/utils/errorUtils.d.ts +5 -5
- package/lib/typescript/utils/errorUtils.d.ts.map +1 -1
- package/lib/typescript/utils/hookUtils.d.ts +4 -4
- package/lib/typescript/utils/hookUtils.d.ts.map +1 -1
- package/lib/typescript/utils/loggerUtils.d.ts +18 -18
- package/lib/typescript/utils/loggerUtils.d.ts.map +1 -1
- package/lib/typescript/utils/validationUtils.d.ts +6 -6
- package/lib/typescript/utils/validationUtils.d.ts.map +1 -1
- package/package.json +149 -143
- package/src/assets/icons/OxyServices.tsx +2 -2
- package/src/assets/illustrations/HighFive.tsx +1 -1
- package/src/core/OxyServices.ts +268 -41
- package/src/core/__tests__/OxyServices.test.ts +180 -0
- package/src/core/index.ts +1 -1
- package/src/index.ts +16 -2
- package/src/lib/sonner-safe.ts +4 -1
- package/src/lib/sonner.ts +19 -2
- package/src/models/interfaces.ts +117 -6
- package/src/node/index.ts +2 -2
- package/src/types/expo-vector-icons.d.ts +8 -1
- package/src/types/express.d.ts +22 -3
- package/src/ui/components/Avatar.tsx +2 -2
- package/src/ui/components/FollowButton.tsx +10 -8
- package/src/ui/components/FontLoader.tsx +5 -3
- package/src/ui/components/GroupedItem.tsx +12 -2
- package/src/ui/components/GroupedSection.tsx +3 -1
- package/src/ui/components/Header.tsx +1 -1
- package/src/ui/components/OxyLogo.tsx +2 -2
- package/src/ui/components/OxyPayButton.tsx +6 -5
- package/src/ui/components/OxyProvider.tsx +7 -4
- package/src/ui/components/OxySignInButton.tsx +2 -2
- package/src/ui/components/ProfileCard.tsx +1 -1
- package/src/ui/components/QuickActions.tsx +1 -1
- package/src/ui/components/Section.tsx +1 -1
- package/src/ui/components/SectionTitle.tsx +1 -1
- package/src/ui/components/icon/FAIRWalletIcon.tsx +1 -1
- package/src/ui/components/icon/OxyIcon.tsx +1 -1
- package/src/ui/components/internal/GroupedPillButtons.tsx +1 -1
- package/src/ui/components/internal/PinInput.tsx +3 -2
- package/src/ui/components/internal/TextField.tsx +9 -11
- package/src/ui/context/OxyContext.tsx +3 -3
- package/src/ui/hooks/useAssets.ts +306 -0
- package/src/ui/navigation/OxyRouter.tsx +3 -2
- package/src/ui/navigation/types.ts +8 -8
- package/src/ui/screens/AccountCenterScreen.tsx +2 -2
- package/src/ui/screens/AccountManagementDemo.tsx +1 -1
- package/src/ui/screens/AccountOverviewScreen.tsx +1 -1
- package/src/ui/screens/AccountSettingsScreen.tsx +3 -3
- package/src/ui/screens/AccountSwitcherScreen.tsx +9 -8
- package/src/ui/screens/AppInfoScreen.tsx +3 -2
- package/src/ui/screens/FeedbackScreen.tsx +1 -1
- package/src/ui/screens/FileManagementScreen.tsx +619 -494
- package/src/ui/screens/PaymentGatewayScreen.tsx +3 -2
- package/src/ui/screens/PremiumSubscriptionScreen.tsx +3 -2
- package/src/ui/screens/ProfileScreen.tsx +3 -2
- package/src/ui/screens/RecoverAccountScreen.tsx +3 -2
- package/src/ui/screens/SessionManagementScreen.tsx +4 -3
- package/src/ui/screens/SignInScreen.tsx +3 -2
- package/src/ui/screens/SignUpScreen.tsx +1 -1
- package/src/ui/screens/UserLinksScreen.tsx +2 -2
- package/src/ui/screens/internal/SignInPasswordStep.tsx +3 -2
- package/src/ui/screens/internal/SignInUsernameStep.tsx +3 -2
- package/src/ui/screens/internal/SignUpIdentityStep.tsx +3 -2
- package/src/ui/screens/internal/SignUpSecurityStep.tsx +3 -2
- package/src/ui/screens/internal/SignUpSummaryStep.tsx +1 -1
- package/src/ui/screens/internal/SignUpWelcomeStep.tsx +1 -1
- package/src/ui/screens/karma/KarmaAboutScreen.tsx +2 -2
- package/src/ui/screens/karma/KarmaCenterScreen.tsx +3 -2
- package/src/ui/screens/karma/KarmaFAQScreen.tsx +1 -1
- package/src/ui/screens/karma/KarmaLeaderboardScreen.tsx +3 -2
- package/src/ui/screens/karma/KarmaRewardsScreen.tsx +2 -2
- package/src/ui/screens/karma/KarmaRulesScreen.tsx +3 -2
- package/src/ui/stores/assetStore.ts +281 -0
- package/src/ui/stores/authStore.ts +1 -1
- package/src/ui/stores/fileStore.ts +118 -0
- package/src/ui/stores/followStore.ts +4 -4
- package/src/ui/styles/fonts.ts +1 -1
- package/src/ui/styles/theme.ts +1 -1
- package/src/utils/__tests__/validationUtils.test.ts +236 -0
- package/src/utils/asyncUtils.ts +4 -4
- package/src/utils/errorUtils.ts +35 -23
- package/src/utils/hookUtils.ts +7 -7
- package/src/utils/loggerUtils.ts +18 -18
- package/src/utils/validationUtils.ts +8 -8
|
@@ -1,30 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import React, { useState, useEffect, useCallback, useMemo } from 'react';
|
|
4
|
-
import { View, Text, TouchableOpacity, StyleSheet, ScrollView, ActivityIndicator, Platform, RefreshControl, Modal, TextInput, Image
|
|
3
|
+
import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
|
|
4
|
+
import { View, Text, TouchableOpacity, StyleSheet, ScrollView, ActivityIndicator, Platform, RefreshControl, Modal, TextInput, Image // kept for Image.getSize only
|
|
5
|
+
} from 'react-native';
|
|
6
|
+
import { Image as ExpoImage } from 'expo-image';
|
|
5
7
|
import { useOxy } from '../context/OxyContext';
|
|
6
8
|
import { fontFamilies } from '../styles/fonts';
|
|
7
9
|
import { toast } from '../../lib/sonner';
|
|
8
10
|
import { Ionicons } from '@expo/vector-icons';
|
|
11
|
+
import { useFileStore, useFiles, useUploading as useUploadingStore, useUploadAggregateProgress, useDeleting as useDeletingStore } from '../stores/fileStore';
|
|
12
|
+
import Header from '../components/Header';
|
|
13
|
+
import { GroupedSection } from '../components';
|
|
9
14
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
10
15
|
// Add this helper function near the top (after imports):
|
|
11
|
-
async function uploadFileRaw(file, userId) {
|
|
12
|
-
|
|
13
|
-
const mimeType = file.type || 'application/octet-stream';
|
|
14
|
-
const res = await fetch('/api/files/upload-raw', {
|
|
15
|
-
method: 'POST',
|
|
16
|
-
headers: {
|
|
17
|
-
'Content-Type': mimeType,
|
|
18
|
-
'X-File-Name': encodeURIComponent(fileName),
|
|
19
|
-
'X-User-Id': userId
|
|
20
|
-
},
|
|
21
|
-
body: file,
|
|
22
|
-
credentials: 'include' // if you use cookies/session
|
|
23
|
-
});
|
|
24
|
-
if (!res.ok) {
|
|
25
|
-
throw new Error(await res.text());
|
|
26
|
-
}
|
|
27
|
-
return await res.json();
|
|
16
|
+
async function uploadFileRaw(file, userId, oxyServices) {
|
|
17
|
+
return await oxyServices.uploadRawFile(file);
|
|
28
18
|
}
|
|
29
19
|
const FileManagementScreen = ({
|
|
30
20
|
onClose,
|
|
@@ -50,12 +40,12 @@ const FileManagementScreen = ({
|
|
|
50
40
|
console.log('[FileManagementScreen] Available content width:', availableContentWidth);
|
|
51
41
|
console.log('[FileManagementScreen] Spacing fix applied: 4px uniform gap both horizontal and vertical');
|
|
52
42
|
}, [containerWidth]);
|
|
53
|
-
const
|
|
43
|
+
const files = useFiles();
|
|
44
|
+
const uploading = useUploadingStore();
|
|
45
|
+
const uploadProgress = useUploadAggregateProgress();
|
|
46
|
+
const deleting = useDeletingStore();
|
|
54
47
|
const [loading, setLoading] = useState(true);
|
|
55
48
|
const [refreshing, setRefreshing] = useState(false);
|
|
56
|
-
const [uploading, setUploading] = useState(false);
|
|
57
|
-
const [uploadProgress, setUploadProgress] = useState(null);
|
|
58
|
-
const [deleting, setDeleting] = useState(null);
|
|
59
49
|
const [selectedFile, setSelectedFile] = useState(null);
|
|
60
50
|
const [showFileDetails, setShowFileDetails] = useState(false);
|
|
61
51
|
const [openedFile, setOpenedFile] = useState(null);
|
|
@@ -64,11 +54,66 @@ const FileManagementScreen = ({
|
|
|
64
54
|
const [showFileDetailsInViewer, setShowFileDetailsInViewer] = useState(false);
|
|
65
55
|
const [viewMode, setViewMode] = useState('all');
|
|
66
56
|
const [searchQuery, setSearchQuery] = useState('');
|
|
67
|
-
|
|
57
|
+
// Derived filtered files (avoid setState loops)
|
|
58
|
+
const filteredFiles = useMemo(() => {
|
|
59
|
+
let filteredByMode = files;
|
|
60
|
+
if (viewMode === 'photos') {
|
|
61
|
+
filteredByMode = files.filter(file => file.contentType.startsWith('image/'));
|
|
62
|
+
}
|
|
63
|
+
if (!searchQuery.trim()) {
|
|
64
|
+
return filteredByMode;
|
|
65
|
+
}
|
|
66
|
+
const query = searchQuery.toLowerCase();
|
|
67
|
+
return filteredByMode.filter(file => file.filename.toLowerCase().includes(query) || file.contentType.toLowerCase().includes(query) || file.metadata?.description && file.metadata.description.toLowerCase().includes(query));
|
|
68
|
+
}, [files, searchQuery, viewMode]);
|
|
68
69
|
const [isDragging, setIsDragging] = useState(false);
|
|
69
70
|
const [photoDimensions, setPhotoDimensions] = useState({});
|
|
70
71
|
const [loadingDimensions, setLoadingDimensions] = useState(false);
|
|
71
72
|
const [hoveredPreview, setHoveredPreview] = useState(null);
|
|
73
|
+
const uploadStartRef = useRef(null);
|
|
74
|
+
const MIN_BANNER_MS = 600;
|
|
75
|
+
const endUpload = useCallback(() => {
|
|
76
|
+
const started = uploadStartRef.current;
|
|
77
|
+
const elapsed = started ? Date.now() - started : MIN_BANNER_MS;
|
|
78
|
+
const remaining = elapsed < MIN_BANNER_MS ? MIN_BANNER_MS - elapsed : 0;
|
|
79
|
+
setTimeout(() => {
|
|
80
|
+
useFileStore.getState().setUploading(false);
|
|
81
|
+
uploadStartRef.current = null;
|
|
82
|
+
}, remaining);
|
|
83
|
+
}, []);
|
|
84
|
+
|
|
85
|
+
// Helper to safely request a thumbnail variant only for image mime types.
|
|
86
|
+
// Prevents backend warnings: "Variant thumb not supported for mime application/pdf".
|
|
87
|
+
const getSafeDownloadUrl = useCallback((file, variant = 'thumb') => {
|
|
88
|
+
const isImage = file.contentType.startsWith('image/');
|
|
89
|
+
const isVideo = file.contentType.startsWith('video/');
|
|
90
|
+
|
|
91
|
+
// Prefer explicit variant key if variants metadata present
|
|
92
|
+
if (file.variants && file.variants.length > 0) {
|
|
93
|
+
// For videos, try 'poster' regardless of requested variant
|
|
94
|
+
if (isVideo) {
|
|
95
|
+
const poster = file.variants.find(v => v.type === 'poster');
|
|
96
|
+
if (poster) return oxyServices.getFileDownloadUrl(file.id, 'poster');
|
|
97
|
+
}
|
|
98
|
+
if (isImage) {
|
|
99
|
+
const desired = file.variants.find(v => v.type === variant);
|
|
100
|
+
if (desired) return oxyServices.getFileDownloadUrl(file.id, variant);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (isImage) {
|
|
104
|
+
return oxyServices.getFileDownloadUrl(file.id, variant);
|
|
105
|
+
}
|
|
106
|
+
if (isVideo) {
|
|
107
|
+
// Fallback to poster if backend supports implicit generation
|
|
108
|
+
try {
|
|
109
|
+
return oxyServices.getFileDownloadUrl(file.id, 'poster');
|
|
110
|
+
} catch {
|
|
111
|
+
return oxyServices.getFileDownloadUrl(file.id);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Other mime types: no variant
|
|
115
|
+
return oxyServices.getFileDownloadUrl(file.id);
|
|
116
|
+
}, [oxyServices]);
|
|
72
117
|
|
|
73
118
|
// Memoize theme-related calculations to prevent unnecessary recalculations
|
|
74
119
|
const themeStyles = useMemo(() => {
|
|
@@ -89,16 +134,32 @@ const FileManagementScreen = ({
|
|
|
89
134
|
const backgroundColor = themeStyles.backgroundColor;
|
|
90
135
|
const borderColor = themeStyles.borderColor;
|
|
91
136
|
const targetUserId = userId || user?.id;
|
|
92
|
-
const
|
|
137
|
+
const storeSetUploading = useFileStore(s => s.setUploading);
|
|
138
|
+
const storeSetUploadProgress = useFileStore(s => s.setUploadProgress);
|
|
139
|
+
const storeSetDeleting = useFileStore(s => s.setDeleting);
|
|
140
|
+
const loadFiles = useCallback(async (mode = 'initial') => {
|
|
93
141
|
if (!targetUserId) return;
|
|
94
142
|
try {
|
|
95
|
-
if (
|
|
143
|
+
if (mode === 'refresh') {
|
|
96
144
|
setRefreshing(true);
|
|
97
|
-
} else {
|
|
145
|
+
} else if (mode === 'initial') {
|
|
98
146
|
setLoading(true);
|
|
99
147
|
}
|
|
100
|
-
const response = await oxyServices.listUserFiles(
|
|
101
|
-
|
|
148
|
+
const response = await oxyServices.listUserFiles();
|
|
149
|
+
const assets = (response.files || []).map(f => ({
|
|
150
|
+
id: f.id,
|
|
151
|
+
filename: f.originalName || f.sha256,
|
|
152
|
+
contentType: f.mime,
|
|
153
|
+
length: f.size,
|
|
154
|
+
chunkSize: 0,
|
|
155
|
+
uploadDate: f.createdAt,
|
|
156
|
+
metadata: f.metadata || {},
|
|
157
|
+
variants: f.variants || []
|
|
158
|
+
}));
|
|
159
|
+
// Merge to preserve existing order & allow incremental updates
|
|
160
|
+
useFileStore.getState().setFiles(assets, {
|
|
161
|
+
merge: true
|
|
162
|
+
});
|
|
102
163
|
} catch (error) {
|
|
103
164
|
console.error('Failed to load files:', error);
|
|
104
165
|
toast.error(error.message || 'Failed to load files');
|
|
@@ -108,24 +169,7 @@ const FileManagementScreen = ({
|
|
|
108
169
|
}
|
|
109
170
|
}, [targetUserId, oxyServices]);
|
|
110
171
|
|
|
111
|
-
//
|
|
112
|
-
useEffect(() => {
|
|
113
|
-
let filteredByMode = files;
|
|
114
|
-
|
|
115
|
-
// Filter by view mode first
|
|
116
|
-
if (viewMode === 'photos') {
|
|
117
|
-
filteredByMode = files.filter(file => file.contentType.startsWith('image/'));
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Then filter by search query
|
|
121
|
-
if (!searchQuery.trim()) {
|
|
122
|
-
setFilteredFiles(filteredByMode);
|
|
123
|
-
} else {
|
|
124
|
-
const query = searchQuery.toLowerCase();
|
|
125
|
-
const filtered = filteredByMode.filter(file => file.filename.toLowerCase().includes(query) || file.contentType.toLowerCase().includes(query) || file.metadata?.description && file.metadata.description.toLowerCase().includes(query));
|
|
126
|
-
setFilteredFiles(filtered);
|
|
127
|
-
}
|
|
128
|
-
}, [files, searchQuery, viewMode]);
|
|
172
|
+
// (removed effect; filteredFiles is memoized)
|
|
129
173
|
|
|
130
174
|
// Load photo dimensions for justified grid
|
|
131
175
|
const loadPhotoDimensions = useCallback(async photos => {
|
|
@@ -145,7 +189,7 @@ const FileManagementScreen = ({
|
|
|
145
189
|
try {
|
|
146
190
|
await Promise.all(photosToLoad.map(async photo => {
|
|
147
191
|
try {
|
|
148
|
-
const downloadUrl =
|
|
192
|
+
const downloadUrl = getSafeDownloadUrl(photo, 'thumb');
|
|
149
193
|
if (Platform.OS === 'web') {
|
|
150
194
|
const img = new window.Image();
|
|
151
195
|
await new Promise((resolve, reject) => {
|
|
@@ -224,7 +268,7 @@ const FileManagementScreen = ({
|
|
|
224
268
|
if (selectedFiles.length === 0) return;
|
|
225
269
|
if (!targetUserId) return; // Guard clause to ensure userId is defined
|
|
226
270
|
try {
|
|
227
|
-
|
|
271
|
+
storeSetUploadProgress({
|
|
228
272
|
current: 0,
|
|
229
273
|
total: selectedFiles.length
|
|
230
274
|
});
|
|
@@ -239,12 +283,55 @@ const FileManagementScreen = ({
|
|
|
239
283
|
let failureCount = 0;
|
|
240
284
|
const errors = [];
|
|
241
285
|
for (let i = 0; i < selectedFiles.length; i++) {
|
|
242
|
-
|
|
286
|
+
storeSetUploadProgress({
|
|
243
287
|
current: i + 1,
|
|
244
288
|
total: selectedFiles.length
|
|
245
289
|
});
|
|
246
290
|
try {
|
|
247
|
-
|
|
291
|
+
const raw = selectedFiles[i];
|
|
292
|
+
const optimisticId = `temp-${Date.now()}-${i}`;
|
|
293
|
+
const optimisticFile = {
|
|
294
|
+
id: optimisticId,
|
|
295
|
+
filename: raw.name,
|
|
296
|
+
contentType: raw.type || 'application/octet-stream',
|
|
297
|
+
length: raw.size,
|
|
298
|
+
chunkSize: 0,
|
|
299
|
+
uploadDate: new Date().toISOString(),
|
|
300
|
+
metadata: {
|
|
301
|
+
uploading: true
|
|
302
|
+
},
|
|
303
|
+
variants: []
|
|
304
|
+
};
|
|
305
|
+
useFileStore.getState().addFile(optimisticFile, {
|
|
306
|
+
prepend: true
|
|
307
|
+
});
|
|
308
|
+
const result = await uploadFileRaw(raw, targetUserId, oxyServices);
|
|
309
|
+
// Attempt to refresh file list incrementally – fetch single file metadata if API allows
|
|
310
|
+
if (result?.file || result?.files?.[0]) {
|
|
311
|
+
const f = result.file || result.files[0];
|
|
312
|
+
const merged = {
|
|
313
|
+
id: f.id,
|
|
314
|
+
filename: f.originalName || f.sha256 || raw.name,
|
|
315
|
+
contentType: f.mime || raw.type || 'application/octet-stream',
|
|
316
|
+
length: f.size || raw.size,
|
|
317
|
+
chunkSize: 0,
|
|
318
|
+
uploadDate: f.createdAt || new Date().toISOString(),
|
|
319
|
+
metadata: f.metadata || {},
|
|
320
|
+
variants: f.variants || []
|
|
321
|
+
};
|
|
322
|
+
// Remove optimistic then add real
|
|
323
|
+
useFileStore.getState().removeFile(optimisticId);
|
|
324
|
+
useFileStore.getState().addFile(merged, {
|
|
325
|
+
prepend: true
|
|
326
|
+
});
|
|
327
|
+
} else {
|
|
328
|
+
// Fallback: will reconcile on later list refresh
|
|
329
|
+
useFileStore.getState().updateFile(optimisticId, {
|
|
330
|
+
metadata: {
|
|
331
|
+
uploading: false
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
}
|
|
248
335
|
successCount++;
|
|
249
336
|
} catch (error) {
|
|
250
337
|
failureCount++;
|
|
@@ -258,29 +345,51 @@ const FileManagementScreen = ({
|
|
|
258
345
|
const errorMessage = `${failureCount} file(s) failed to upload${errors.length > 0 ? ':\n' + errors.slice(0, 3).join('\n') + (errors.length > 3 ? '\n...' : '') : ''}`;
|
|
259
346
|
toast.error(errorMessage);
|
|
260
347
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
348
|
+
// Silent background refresh to ensure metadata/variants updated
|
|
349
|
+
setTimeout(() => {
|
|
350
|
+
loadFiles('silent');
|
|
351
|
+
}, 1200);
|
|
264
352
|
} catch (error) {
|
|
265
353
|
console.error('Upload error:', error);
|
|
266
354
|
toast.error(error.message || 'Failed to upload files');
|
|
267
355
|
} finally {
|
|
268
|
-
|
|
356
|
+
storeSetUploadProgress(null);
|
|
269
357
|
}
|
|
270
358
|
};
|
|
271
359
|
const handleFileUpload = async () => {
|
|
272
360
|
try {
|
|
273
|
-
|
|
274
|
-
|
|
361
|
+
uploadStartRef.current = Date.now();
|
|
362
|
+
storeSetUploading(true);
|
|
363
|
+
storeSetUploadProgress(null);
|
|
275
364
|
if (Platform.OS === 'web') {
|
|
276
365
|
// Web file picker implementation
|
|
277
366
|
const input = document.createElement('input');
|
|
278
367
|
input.type = 'file';
|
|
279
368
|
input.multiple = true;
|
|
280
369
|
input.accept = '*/*';
|
|
370
|
+
// Fallback: if the user cancels the dialog (no onchange fires or 0 files), hide banner
|
|
371
|
+
const cancellationTimer = setTimeout(() => {
|
|
372
|
+
const state = useFileStore.getState();
|
|
373
|
+
if (state.uploading && uploadStartRef.current && !state.uploadProgress) {
|
|
374
|
+
// No selection happened; treat as cancel
|
|
375
|
+
endUpload();
|
|
376
|
+
}
|
|
377
|
+
}, 1500); // allow enough time for user to pick
|
|
378
|
+
|
|
281
379
|
input.onchange = async e => {
|
|
282
|
-
|
|
380
|
+
clearTimeout(cancellationTimer);
|
|
381
|
+
const selectedFiles = Array.from(e.target.files || []);
|
|
382
|
+
if (selectedFiles.length === 0) {
|
|
383
|
+
// User explicitly canceled (some browsers still fire onchange with empty list)
|
|
384
|
+
endUpload();
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
storeSetUploadProgress({
|
|
388
|
+
current: 0,
|
|
389
|
+
total: selectedFiles.length
|
|
390
|
+
});
|
|
283
391
|
await processFileUploads(selectedFiles);
|
|
392
|
+
endUpload();
|
|
284
393
|
};
|
|
285
394
|
input.click();
|
|
286
395
|
} else {
|
|
@@ -296,8 +405,11 @@ const FileManagementScreen = ({
|
|
|
296
405
|
} catch (error) {
|
|
297
406
|
toast.error(error.message || 'Failed to upload file');
|
|
298
407
|
} finally {
|
|
299
|
-
|
|
300
|
-
|
|
408
|
+
// IMPORTANT: Do NOT call endUpload here.
|
|
409
|
+
// We only want to hide the banner after the actual upload(s) complete.
|
|
410
|
+
// The input.onchange handler invokes processFileUploads then calls endUpload().
|
|
411
|
+
// Calling endUpload here caused the banner to disappear while files were still uploading.
|
|
412
|
+
storeSetUploadProgress(null); // keep clearing any stale progress
|
|
301
413
|
}
|
|
302
414
|
};
|
|
303
415
|
const handleFileDelete = async (fileId, filename) => {
|
|
@@ -314,15 +426,16 @@ const FileManagementScreen = ({
|
|
|
314
426
|
});
|
|
315
427
|
console.log('Target user ID:', targetUserId);
|
|
316
428
|
console.log('Current user ID:', user?.id);
|
|
317
|
-
|
|
429
|
+
storeSetDeleting(fileId);
|
|
318
430
|
const result = await oxyServices.deleteFile(fileId);
|
|
319
431
|
console.log('Delete result:', result);
|
|
320
432
|
toast.success('File deleted successfully');
|
|
321
433
|
|
|
322
434
|
// Reload files after successful deletion
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
435
|
+
// Optimistic remove
|
|
436
|
+
useFileStore.getState().removeFile(fileId);
|
|
437
|
+
// Silent background reconcile
|
|
438
|
+
setTimeout(() => loadFiles('silent'), 800);
|
|
326
439
|
} catch (error) {
|
|
327
440
|
console.error('Delete error:', error);
|
|
328
441
|
console.error('Error details:', error.response?.data || error.message);
|
|
@@ -331,16 +444,14 @@ const FileManagementScreen = ({
|
|
|
331
444
|
if (error.message?.includes('File not found') || error.message?.includes('404')) {
|
|
332
445
|
toast.error('File not found. It may have already been deleted.');
|
|
333
446
|
// Still reload files to refresh the list
|
|
334
|
-
setTimeout(
|
|
335
|
-
await loadFiles();
|
|
336
|
-
}, 500);
|
|
447
|
+
setTimeout(() => loadFiles('silent'), 800);
|
|
337
448
|
} else if (error.message?.includes('permission') || error.message?.includes('403')) {
|
|
338
449
|
toast.error('You do not have permission to delete this file.');
|
|
339
450
|
} else {
|
|
340
451
|
toast.error(error.message || 'Failed to delete file');
|
|
341
452
|
}
|
|
342
453
|
} finally {
|
|
343
|
-
|
|
454
|
+
storeSetDeleting(null);
|
|
344
455
|
}
|
|
345
456
|
};
|
|
346
457
|
|
|
@@ -351,24 +462,68 @@ const FileManagementScreen = ({
|
|
|
351
462
|
setIsDragging(true);
|
|
352
463
|
}
|
|
353
464
|
};
|
|
465
|
+
const handleDragEnter = e => {
|
|
466
|
+
if (Platform.OS === 'web' && user?.id === targetUserId) {
|
|
467
|
+
e.preventDefault();
|
|
468
|
+
setIsDragging(true);
|
|
469
|
+
}
|
|
470
|
+
};
|
|
354
471
|
const handleDragLeave = e => {
|
|
355
472
|
if (Platform.OS === 'web') {
|
|
356
473
|
e.preventDefault();
|
|
357
474
|
setIsDragging(false);
|
|
358
475
|
}
|
|
359
476
|
};
|
|
477
|
+
|
|
478
|
+
// Global drag listeners (web) to catch drags outside component bounds
|
|
479
|
+
useEffect(() => {
|
|
480
|
+
if (Platform.OS !== 'web' || user?.id !== targetUserId) return;
|
|
481
|
+
const onDocDragEnter = e => {
|
|
482
|
+
if (e?.dataTransfer?.types?.includes('Files')) setIsDragging(true);
|
|
483
|
+
};
|
|
484
|
+
const onDocDragOver = e => {
|
|
485
|
+
if (e?.dataTransfer?.types?.includes('Files')) {
|
|
486
|
+
e.preventDefault();
|
|
487
|
+
setIsDragging(true);
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
const onDocDrop = e => {
|
|
491
|
+
if (e?.dataTransfer?.files?.length) {
|
|
492
|
+
e.preventDefault();
|
|
493
|
+
setIsDragging(false);
|
|
494
|
+
}
|
|
495
|
+
};
|
|
496
|
+
const onDocDragLeave = e => {
|
|
497
|
+
if (!e.relatedTarget && e.screenX === 0 && e.screenY === 0) setIsDragging(false);
|
|
498
|
+
};
|
|
499
|
+
document.addEventListener('dragenter', onDocDragEnter);
|
|
500
|
+
document.addEventListener('dragover', onDocDragOver);
|
|
501
|
+
document.addEventListener('drop', onDocDrop);
|
|
502
|
+
document.addEventListener('dragleave', onDocDragLeave);
|
|
503
|
+
return () => {
|
|
504
|
+
document.removeEventListener('dragenter', onDocDragEnter);
|
|
505
|
+
document.removeEventListener('dragover', onDocDragOver);
|
|
506
|
+
document.removeEventListener('drop', onDocDrop);
|
|
507
|
+
document.removeEventListener('dragleave', onDocDragLeave);
|
|
508
|
+
};
|
|
509
|
+
}, [user?.id, targetUserId]);
|
|
360
510
|
const handleDrop = async e => {
|
|
361
511
|
if (Platform.OS === 'web' && user?.id === targetUserId) {
|
|
362
512
|
e.preventDefault();
|
|
363
513
|
setIsDragging(false);
|
|
364
|
-
|
|
514
|
+
uploadStartRef.current = Date.now();
|
|
515
|
+
storeSetUploading(true);
|
|
365
516
|
try {
|
|
366
517
|
const files = Array.from(e.dataTransfer.files);
|
|
518
|
+
if (files.length > 0) storeSetUploadProgress({
|
|
519
|
+
current: 0,
|
|
520
|
+
total: files.length
|
|
521
|
+
});
|
|
367
522
|
await processFileUploads(files);
|
|
368
523
|
} catch (error) {
|
|
369
524
|
toast.error(error.message || 'Failed to upload files');
|
|
370
525
|
} finally {
|
|
371
|
-
|
|
526
|
+
endUpload();
|
|
372
527
|
}
|
|
373
528
|
}
|
|
374
529
|
};
|
|
@@ -423,7 +578,7 @@ const FileManagementScreen = ({
|
|
|
423
578
|
const k = 1024;
|
|
424
579
|
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
425
580
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
426
|
-
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
581
|
+
return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
427
582
|
};
|
|
428
583
|
const getFileIcon = contentType => {
|
|
429
584
|
if (contentType.startsWith('image/')) return 'image';
|
|
@@ -483,7 +638,7 @@ const FileManagementScreen = ({
|
|
|
483
638
|
setShowFileDetails(true);
|
|
484
639
|
};
|
|
485
640
|
const renderSimplePhotoItem = useCallback((photo, index) => {
|
|
486
|
-
const downloadUrl =
|
|
641
|
+
const downloadUrl = getSafeDownloadUrl(photo, 'thumb');
|
|
487
642
|
|
|
488
643
|
// Calculate photo item width based on actual container size from bottom sheet
|
|
489
644
|
let itemsPerRow = 3; // Default for mobile
|
|
@@ -505,41 +660,24 @@ const FileManagementScreen = ({
|
|
|
505
660
|
activeOpacity: 0.8,
|
|
506
661
|
children: /*#__PURE__*/_jsx(View, {
|
|
507
662
|
style: styles.simplePhotoContainer,
|
|
508
|
-
children:
|
|
509
|
-
src: downloadUrl,
|
|
510
|
-
alt: photo.filename,
|
|
511
|
-
style: {
|
|
512
|
-
width: '100%',
|
|
513
|
-
height: '100%',
|
|
514
|
-
objectFit: 'cover',
|
|
515
|
-
borderRadius: 8,
|
|
516
|
-
transition: 'transform 0.2s ease'
|
|
517
|
-
},
|
|
518
|
-
loading: "lazy",
|
|
519
|
-
onError: e => {
|
|
520
|
-
console.error('Photo failed to load:', e);
|
|
521
|
-
},
|
|
522
|
-
onMouseEnter: e => {
|
|
523
|
-
e.currentTarget.style.transform = 'scale(1.05)';
|
|
524
|
-
},
|
|
525
|
-
onMouseLeave: e => {
|
|
526
|
-
e.currentTarget.style.transform = 'scale(1)';
|
|
527
|
-
}
|
|
528
|
-
}) : /*#__PURE__*/_jsx(Image, {
|
|
663
|
+
children: /*#__PURE__*/_jsx(ExpoImage, {
|
|
529
664
|
source: {
|
|
530
665
|
uri: downloadUrl
|
|
531
666
|
},
|
|
532
667
|
style: styles.simplePhotoImage,
|
|
533
|
-
|
|
668
|
+
contentFit: "cover",
|
|
669
|
+
transition: 120,
|
|
670
|
+
cachePolicy: "memory-disk",
|
|
534
671
|
onError: e => {
|
|
535
|
-
console.error('Photo failed to load:', e);
|
|
536
|
-
}
|
|
672
|
+
console.error('Photo failed to load:', e?.nativeEvent ?? e);
|
|
673
|
+
},
|
|
674
|
+
accessibilityLabel: photo.filename
|
|
537
675
|
})
|
|
538
676
|
})
|
|
539
677
|
}, photo.id);
|
|
540
678
|
}, [oxyServices, containerWidth]);
|
|
541
679
|
const renderJustifiedPhotoItem = useCallback((photo, width, height, isLast) => {
|
|
542
|
-
const downloadUrl =
|
|
680
|
+
const downloadUrl = getSafeDownloadUrl(photo, 'thumb');
|
|
543
681
|
return /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
544
682
|
style: [styles.justifiedPhotoItem, {
|
|
545
683
|
width,
|
|
@@ -549,46 +687,33 @@ const FileManagementScreen = ({
|
|
|
549
687
|
activeOpacity: 0.8,
|
|
550
688
|
children: /*#__PURE__*/_jsx(View, {
|
|
551
689
|
style: styles.justifiedPhotoContainer,
|
|
552
|
-
children:
|
|
553
|
-
src: downloadUrl,
|
|
554
|
-
alt: photo.filename,
|
|
555
|
-
style: {
|
|
556
|
-
width: '100%',
|
|
557
|
-
height: '100%',
|
|
558
|
-
objectFit: 'cover',
|
|
559
|
-
borderRadius: 6,
|
|
560
|
-
transition: 'transform 0.2s ease, box-shadow 0.2s ease'
|
|
561
|
-
},
|
|
562
|
-
loading: "lazy",
|
|
563
|
-
onError: e => {
|
|
564
|
-
console.error('Photo failed to load:', e);
|
|
565
|
-
},
|
|
566
|
-
onMouseEnter: e => {
|
|
567
|
-
e.currentTarget.style.transform = 'scale(1.02)';
|
|
568
|
-
e.currentTarget.style.boxShadow = '0 8px 25px rgba(0,0,0,0.15)';
|
|
569
|
-
e.currentTarget.style.zIndex = '10';
|
|
570
|
-
},
|
|
571
|
-
onMouseLeave: e => {
|
|
572
|
-
e.currentTarget.style.transform = 'scale(1)';
|
|
573
|
-
e.currentTarget.style.boxShadow = '0 2px 8px rgba(0,0,0,0.1)';
|
|
574
|
-
e.currentTarget.style.zIndex = '1';
|
|
575
|
-
}
|
|
576
|
-
}) : /*#__PURE__*/_jsx(Image, {
|
|
690
|
+
children: /*#__PURE__*/_jsx(ExpoImage, {
|
|
577
691
|
source: {
|
|
578
692
|
uri: downloadUrl
|
|
579
693
|
},
|
|
580
694
|
style: styles.justifiedPhotoImage,
|
|
581
|
-
|
|
695
|
+
contentFit: "cover",
|
|
696
|
+
transition: 120,
|
|
697
|
+
cachePolicy: "memory-disk",
|
|
582
698
|
onError: e => {
|
|
583
|
-
console.error('Photo failed to load:', e);
|
|
584
|
-
}
|
|
699
|
+
console.error('Photo failed to load:', e?.nativeEvent ?? e);
|
|
700
|
+
},
|
|
701
|
+
accessibilityLabel: photo.filename
|
|
585
702
|
})
|
|
586
703
|
})
|
|
587
704
|
}, photo.id);
|
|
588
705
|
}, [oxyServices]);
|
|
706
|
+
|
|
707
|
+
// Run initial load once per targetUserId change to avoid accidental loops
|
|
708
|
+
const lastLoadedFor = useRef(undefined);
|
|
589
709
|
useEffect(() => {
|
|
590
|
-
|
|
591
|
-
|
|
710
|
+
const key = targetUserId || 'anonymous';
|
|
711
|
+
if (lastLoadedFor.current !== key) {
|
|
712
|
+
lastLoadedFor.current = key;
|
|
713
|
+
loadFiles('initial');
|
|
714
|
+
}
|
|
715
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
716
|
+
}, [targetUserId]);
|
|
592
717
|
const renderFileItem = file => {
|
|
593
718
|
const isImage = file.contentType.startsWith('image/');
|
|
594
719
|
const isPDF = file.contentType.includes('pdf');
|
|
@@ -612,35 +737,19 @@ const FileManagementScreen = ({
|
|
|
612
737
|
onMouseEnter: () => setHoveredPreview(file.id),
|
|
613
738
|
onMouseLeave: () => setHoveredPreview(null)
|
|
614
739
|
}),
|
|
615
|
-
children: [isImage &&
|
|
616
|
-
src: oxyServices.getFileDownloadUrl(file.id),
|
|
617
|
-
style: {
|
|
618
|
-
width: '100%',
|
|
619
|
-
height: '100%',
|
|
620
|
-
objectFit: 'cover',
|
|
621
|
-
borderRadius: 8,
|
|
622
|
-
transition: 'transform 0.2s ease',
|
|
623
|
-
transform: hoveredPreview === file.id ? 'scale(1.05)' : 'scale(1)'
|
|
624
|
-
},
|
|
625
|
-
onError: e => {
|
|
626
|
-
// Show fallback icon if image fails to load
|
|
627
|
-
e.currentTarget.style.display = 'none';
|
|
628
|
-
const fallbackElement = e.currentTarget.parentElement?.querySelector('[data-fallback="true"]');
|
|
629
|
-
if (fallbackElement) {
|
|
630
|
-
fallbackElement.style.display = 'flex';
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
}) : /*#__PURE__*/_jsx(Image, {
|
|
740
|
+
children: [isImage && /*#__PURE__*/_jsx(ExpoImage, {
|
|
634
741
|
source: {
|
|
635
|
-
uri:
|
|
742
|
+
uri: getSafeDownloadUrl(file, 'thumb')
|
|
636
743
|
},
|
|
637
744
|
style: styles.previewImage,
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
745
|
+
contentFit: "cover",
|
|
746
|
+
transition: 120,
|
|
747
|
+
cachePolicy: "memory-disk",
|
|
748
|
+
onError: _ => {
|
|
749
|
+
console.warn('Failed to load image preview.');
|
|
750
|
+
},
|
|
751
|
+
accessibilityLabel: file.filename
|
|
752
|
+
}), isPDF && /*#__PURE__*/_jsxs(View, {
|
|
644
753
|
style: styles.pdfPreview,
|
|
645
754
|
children: [/*#__PURE__*/_jsx(Ionicons, {
|
|
646
755
|
name: "document",
|
|
@@ -653,16 +762,26 @@ const FileManagementScreen = ({
|
|
|
653
762
|
children: "PDF"
|
|
654
763
|
})]
|
|
655
764
|
}), isVideo && /*#__PURE__*/_jsxs(View, {
|
|
656
|
-
style: styles.
|
|
657
|
-
children: [/*#__PURE__*/_jsx(
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
765
|
+
style: styles.videoPreviewWrapper,
|
|
766
|
+
children: [/*#__PURE__*/_jsx(ExpoImage, {
|
|
767
|
+
source: {
|
|
768
|
+
uri: getSafeDownloadUrl(file, 'thumb')
|
|
769
|
+
},
|
|
770
|
+
style: styles.videoPosterImage,
|
|
771
|
+
contentFit: "cover",
|
|
772
|
+
transition: 120,
|
|
773
|
+
cachePolicy: "memory-disk",
|
|
774
|
+
onError: _ => {
|
|
775
|
+
// If thumbnail not available, we still show icon overlay
|
|
776
|
+
},
|
|
777
|
+
accessibilityLabel: file.filename + ' video thumbnail'
|
|
778
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
779
|
+
style: styles.videoOverlay,
|
|
780
|
+
children: /*#__PURE__*/_jsx(Ionicons, {
|
|
781
|
+
name: "play",
|
|
782
|
+
size: 24,
|
|
783
|
+
color: "#FFFFFF"
|
|
784
|
+
})
|
|
666
785
|
})]
|
|
667
786
|
}), /*#__PURE__*/_jsx(View, {
|
|
668
787
|
style: [styles.fallbackIcon, {
|
|
@@ -755,8 +874,78 @@ const FileManagementScreen = ({
|
|
|
755
874
|
})]
|
|
756
875
|
}, file.id);
|
|
757
876
|
};
|
|
877
|
+
|
|
878
|
+
// GroupedSection-based file items (for 'all' view) replacing legacy flat list look
|
|
879
|
+
const groupedFileItems = useMemo(() => {
|
|
880
|
+
return filteredFiles.filter(f => true) // placeholder for future filtering
|
|
881
|
+
.sort((a, b) => new Date(b.uploadDate).getTime() - new Date(a.uploadDate).getTime()).map(file => {
|
|
882
|
+
const isImage = file.contentType.startsWith('image/');
|
|
883
|
+
const isVideo = file.contentType.startsWith('video/');
|
|
884
|
+
const hasPreview = isImage || isVideo;
|
|
885
|
+
const previewUrl = hasPreview ? isVideo ? getSafeDownloadUrl(file, 'poster') : getSafeDownloadUrl(file, 'thumb') : undefined;
|
|
886
|
+
return {
|
|
887
|
+
id: file.id,
|
|
888
|
+
image: previewUrl,
|
|
889
|
+
imageSize: 44,
|
|
890
|
+
icon: !previewUrl ? getFileIcon(file.contentType) : undefined,
|
|
891
|
+
iconColor: themeStyles.primaryColor,
|
|
892
|
+
title: file.filename,
|
|
893
|
+
subtitle: `${formatFileSize(file.length)} • ${new Date(file.uploadDate).toLocaleDateString()}`,
|
|
894
|
+
theme: theme,
|
|
895
|
+
onPress: () => handleFileOpen(file),
|
|
896
|
+
showChevron: false,
|
|
897
|
+
dense: true,
|
|
898
|
+
multiRow: !!file.metadata?.description,
|
|
899
|
+
customContent: /*#__PURE__*/_jsxs(View, {
|
|
900
|
+
style: styles.groupedActions,
|
|
901
|
+
children: [(isImage || isVideo || file.contentType.includes('pdf')) && /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
902
|
+
style: [styles.groupedActionBtn, {
|
|
903
|
+
backgroundColor: themeStyles.isDarkTheme ? '#333333' : '#F0F0F0'
|
|
904
|
+
}],
|
|
905
|
+
onPress: () => handleFileOpen(file),
|
|
906
|
+
children: /*#__PURE__*/_jsx(Ionicons, {
|
|
907
|
+
name: "eye",
|
|
908
|
+
size: 18,
|
|
909
|
+
color: themeStyles.primaryColor
|
|
910
|
+
})
|
|
911
|
+
}), /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
912
|
+
style: [styles.groupedActionBtn, {
|
|
913
|
+
backgroundColor: themeStyles.isDarkTheme ? '#333333' : '#F0F0F0'
|
|
914
|
+
}],
|
|
915
|
+
onPress: () => handleFileDownload(file.id, file.filename),
|
|
916
|
+
children: /*#__PURE__*/_jsx(Ionicons, {
|
|
917
|
+
name: "download",
|
|
918
|
+
size: 18,
|
|
919
|
+
color: themeStyles.primaryColor
|
|
920
|
+
})
|
|
921
|
+
}), /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
922
|
+
style: [styles.groupedActionBtn, {
|
|
923
|
+
backgroundColor: themeStyles.isDarkTheme ? '#400000' : '#FFEBEE'
|
|
924
|
+
}],
|
|
925
|
+
onPress: () => handleFileDelete(file.id, file.filename),
|
|
926
|
+
disabled: deleting === file.id,
|
|
927
|
+
children: deleting === file.id ? /*#__PURE__*/_jsx(ActivityIndicator, {
|
|
928
|
+
size: "small",
|
|
929
|
+
color: themeStyles.dangerColor
|
|
930
|
+
}) : /*#__PURE__*/_jsx(Ionicons, {
|
|
931
|
+
name: "trash",
|
|
932
|
+
size: 18,
|
|
933
|
+
color: themeStyles.dangerColor
|
|
934
|
+
})
|
|
935
|
+
})]
|
|
936
|
+
}),
|
|
937
|
+
customContentBelow: file.metadata?.description ? /*#__PURE__*/_jsx(Text, {
|
|
938
|
+
style: [styles.groupedDescription, {
|
|
939
|
+
color: themeStyles.isDarkTheme ? '#AAAAAA' : '#666666'
|
|
940
|
+
}],
|
|
941
|
+
numberOfLines: 2,
|
|
942
|
+
children: file.metadata.description
|
|
943
|
+
}) : undefined
|
|
944
|
+
}; // GroupedSectionItem shape
|
|
945
|
+
});
|
|
946
|
+
}, [filteredFiles, theme, themeStyles, deleting, handleFileDownload, handleFileDelete, handleFileOpen, getSafeDownloadUrl]);
|
|
758
947
|
const renderPhotoItem = (photo, index) => {
|
|
759
|
-
const downloadUrl =
|
|
948
|
+
const downloadUrl = getSafeDownloadUrl(photo, 'thumb');
|
|
760
949
|
|
|
761
950
|
// Calculate photo item width based on actual container size from bottom sheet
|
|
762
951
|
let itemsPerRow = 3; // Default for mobile
|
|
@@ -777,36 +966,18 @@ const FileManagementScreen = ({
|
|
|
777
966
|
activeOpacity: 0.8,
|
|
778
967
|
children: /*#__PURE__*/_jsx(View, {
|
|
779
968
|
style: styles.photoContainer,
|
|
780
|
-
children:
|
|
781
|
-
src: downloadUrl,
|
|
782
|
-
alt: photo.filename,
|
|
783
|
-
style: {
|
|
784
|
-
width: '100%',
|
|
785
|
-
height: '100%',
|
|
786
|
-
objectFit: 'cover',
|
|
787
|
-
borderRadius: 8,
|
|
788
|
-
transition: 'transform 0.2s ease'
|
|
789
|
-
},
|
|
790
|
-
loading: "lazy",
|
|
791
|
-
onError: e => {
|
|
792
|
-
console.error('Photo failed to load:', e);
|
|
793
|
-
// Could replace with placeholder image
|
|
794
|
-
},
|
|
795
|
-
onMouseEnter: e => {
|
|
796
|
-
e.currentTarget.style.transform = 'scale(1.02)';
|
|
797
|
-
},
|
|
798
|
-
onMouseLeave: e => {
|
|
799
|
-
e.currentTarget.style.transform = 'scale(1)';
|
|
800
|
-
}
|
|
801
|
-
}) : /*#__PURE__*/_jsx(Image, {
|
|
969
|
+
children: /*#__PURE__*/_jsx(ExpoImage, {
|
|
802
970
|
source: {
|
|
803
971
|
uri: downloadUrl
|
|
804
972
|
},
|
|
805
973
|
style: styles.photoImage,
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
974
|
+
contentFit: "cover",
|
|
975
|
+
transition: 120,
|
|
976
|
+
cachePolicy: "memory-disk",
|
|
977
|
+
onError: _ => {
|
|
978
|
+
console.warn('Failed to load image preview for photo:', photo.id);
|
|
979
|
+
},
|
|
980
|
+
accessibilityLabel: photo.filename
|
|
810
981
|
})
|
|
811
982
|
})
|
|
812
983
|
}, photo.id);
|
|
@@ -825,11 +996,11 @@ const FileManagementScreen = ({
|
|
|
825
996
|
color: themeStyles.textColor
|
|
826
997
|
}],
|
|
827
998
|
children: "No Photos Yet"
|
|
828
|
-
}), /*#__PURE__*/
|
|
999
|
+
}), /*#__PURE__*/_jsxs(Text, {
|
|
829
1000
|
style: [styles.emptyStateDescription, {
|
|
830
1001
|
color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
|
|
831
1002
|
}],
|
|
832
|
-
children: user?.id === targetUserId ? `Upload photos to get started. You can select multiple photos at once${Platform.OS === 'web' ? ' or drag & drop them here.' : '.'}` : "This user hasn't uploaded any photos yet"
|
|
1003
|
+
children: [" ", user?.id === targetUserId ? `Upload photos to get started. You can select multiple photos at once${Platform.OS === 'web' ? ' or drag & drop them here.' : '.'}` : "This user hasn't uploaded any photos yet", " "]
|
|
833
1004
|
}), user?.id === targetUserId && /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
834
1005
|
style: [styles.emptyStateButton, {
|
|
835
1006
|
backgroundColor: themeStyles.primaryColor
|
|
@@ -857,7 +1028,7 @@ const FileManagementScreen = ({
|
|
|
857
1028
|
contentContainerStyle: styles.photoScrollContainer,
|
|
858
1029
|
refreshControl: /*#__PURE__*/_jsx(RefreshControl, {
|
|
859
1030
|
refreshing: refreshing,
|
|
860
|
-
onRefresh: () => loadFiles(
|
|
1031
|
+
onRefresh: () => loadFiles('refresh'),
|
|
861
1032
|
tintColor: themeStyles.primaryColor
|
|
862
1033
|
}),
|
|
863
1034
|
showsVerticalScrollIndicator: false,
|
|
@@ -899,7 +1070,9 @@ const FileManagementScreen = ({
|
|
|
899
1070
|
// Load dimensions for new photos
|
|
900
1071
|
React.useEffect(() => {
|
|
901
1072
|
loadPhotoDimensions(photos);
|
|
902
|
-
|
|
1073
|
+
// Depend only on photo IDs to avoid re-running from dimension state changes
|
|
1074
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1075
|
+
}, [photos.map(p => p.id).join(',')]);
|
|
903
1076
|
|
|
904
1077
|
// Group photos by date
|
|
905
1078
|
const photosByDate = React.useMemo(() => {
|
|
@@ -1338,31 +1511,22 @@ const FileManagementScreen = ({
|
|
|
1338
1511
|
})]
|
|
1339
1512
|
}) : isImage && fileContent ? /*#__PURE__*/_jsx(View, {
|
|
1340
1513
|
style: styles.imageContainer,
|
|
1341
|
-
children:
|
|
1342
|
-
src: fileContent,
|
|
1343
|
-
alt: openedFile.filename,
|
|
1344
|
-
style: {
|
|
1345
|
-
maxWidth: '100%',
|
|
1346
|
-
maxHeight: '80vh',
|
|
1347
|
-
objectFit: 'contain',
|
|
1348
|
-
borderRadius: 8
|
|
1349
|
-
},
|
|
1350
|
-
onError: e => {
|
|
1351
|
-
console.error('Image failed to load:', e);
|
|
1352
|
-
}
|
|
1353
|
-
}) : /*#__PURE__*/_jsx(Image, {
|
|
1514
|
+
children: /*#__PURE__*/_jsx(ExpoImage, {
|
|
1354
1515
|
source: {
|
|
1355
1516
|
uri: fileContent
|
|
1356
1517
|
},
|
|
1357
1518
|
style: {
|
|
1358
1519
|
width: '100%',
|
|
1359
1520
|
height: 400,
|
|
1360
|
-
resizeMode: 'contain',
|
|
1361
1521
|
borderRadius: 8
|
|
1362
1522
|
},
|
|
1523
|
+
contentFit: "contain",
|
|
1524
|
+
transition: 120,
|
|
1525
|
+
cachePolicy: "memory-disk",
|
|
1363
1526
|
onError: e => {
|
|
1364
|
-
console.error('Image failed to load:', e);
|
|
1365
|
-
}
|
|
1527
|
+
console.error('Image failed to load:', e?.nativeEvent ?? e);
|
|
1528
|
+
},
|
|
1529
|
+
accessibilityLabel: openedFile.filename
|
|
1366
1530
|
})
|
|
1367
1531
|
}) : isText && fileContent ? /*#__PURE__*/_jsx(View, {
|
|
1368
1532
|
style: [styles.textContainer, {
|
|
@@ -1525,157 +1689,76 @@ const FileManagementScreen = ({
|
|
|
1525
1689
|
});
|
|
1526
1690
|
}
|
|
1527
1691
|
return /*#__PURE__*/_jsxs(View, {
|
|
1528
|
-
style: [styles.container,
|
|
1529
|
-
backgroundColor
|
|
1530
|
-
}, isDragging && Platform.OS === 'web' && styles.dragOverlay],
|
|
1692
|
+
style: [styles.container, isDragging && Platform.OS === 'web' && styles.dragOverlay],
|
|
1531
1693
|
...(Platform.OS === 'web' && user?.id === targetUserId ? {
|
|
1532
1694
|
onDragOver: handleDragOver,
|
|
1695
|
+
onDragEnter: handleDragEnter,
|
|
1533
1696
|
onDragLeave: handleDragLeave,
|
|
1534
1697
|
onDrop: handleDrop
|
|
1535
1698
|
} : {}),
|
|
1536
|
-
children: [/*#__PURE__*/
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
default: {}
|
|
1553
|
-
})
|
|
1554
|
-
}],
|
|
1555
|
-
children: [/*#__PURE__*/_jsx(TouchableOpacity, {
|
|
1556
|
-
style: [styles.backButton, {
|
|
1557
|
-
backgroundColor: themeStyles.isDarkTheme ? '#2A2A2A' : '#F8F9FA',
|
|
1558
|
-
borderRadius: 12
|
|
1699
|
+
children: [/*#__PURE__*/_jsx(Header, {
|
|
1700
|
+
title: viewMode === 'photos' ? 'Photos' : 'File Management',
|
|
1701
|
+
subtitle: `${filteredFiles.length} ${filteredFiles.length === 1 ? 'item' : 'items'}`,
|
|
1702
|
+
onBack: onClose || goBack,
|
|
1703
|
+
theme: theme,
|
|
1704
|
+
showBackButton: true,
|
|
1705
|
+
variant: "minimal",
|
|
1706
|
+
elevation: "none",
|
|
1707
|
+
titleAlignment: "left"
|
|
1708
|
+
}), /*#__PURE__*/_jsxs(View, {
|
|
1709
|
+
style: styles.controlsBar,
|
|
1710
|
+
children: [/*#__PURE__*/_jsxs(View, {
|
|
1711
|
+
style: [styles.viewModeToggle, {
|
|
1712
|
+
backgroundColor: themeStyles.isDarkTheme ? '#181818' : '#FFFFFF',
|
|
1713
|
+
borderWidth: 1,
|
|
1714
|
+
borderColor: themeStyles.isDarkTheme ? '#2A2A2A' : '#E8E9EA'
|
|
1559
1715
|
}],
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
size: 22,
|
|
1564
|
-
color: themeStyles.textColor
|
|
1565
|
-
})
|
|
1566
|
-
}), /*#__PURE__*/_jsxs(View, {
|
|
1567
|
-
style: styles.headerTitleContainer,
|
|
1568
|
-
children: [/*#__PURE__*/_jsx(Text, {
|
|
1569
|
-
style: [styles.headerTitle, {
|
|
1570
|
-
color: themeStyles.textColor
|
|
1571
|
-
}],
|
|
1572
|
-
children: viewMode === 'photos' ? 'Photos' : 'File Management'
|
|
1573
|
-
}), /*#__PURE__*/_jsxs(Text, {
|
|
1574
|
-
style: [styles.headerSubtitle, {
|
|
1575
|
-
color: themeStyles.isDarkTheme ? '#AAAAAA' : '#666666'
|
|
1576
|
-
}],
|
|
1577
|
-
children: [filteredFiles.length, " ", filteredFiles.length === 1 ? 'item' : 'items']
|
|
1578
|
-
})]
|
|
1579
|
-
}), /*#__PURE__*/_jsxs(View, {
|
|
1580
|
-
style: styles.headerActions,
|
|
1581
|
-
children: [/*#__PURE__*/_jsxs(View, {
|
|
1582
|
-
style: [styles.viewModeToggle, {
|
|
1583
|
-
backgroundColor: themeStyles.isDarkTheme ? '#2A2A2A' : '#F8F9FA',
|
|
1584
|
-
borderWidth: 1,
|
|
1585
|
-
borderColor: themeStyles.isDarkTheme ? '#3A3A3A' : '#E8E9EA',
|
|
1586
|
-
shadowColor: '#000000',
|
|
1587
|
-
shadowOffset: {
|
|
1588
|
-
width: 0,
|
|
1589
|
-
height: 1
|
|
1590
|
-
},
|
|
1591
|
-
shadowOpacity: themeStyles.isDarkTheme ? 0.3 : 0.05,
|
|
1592
|
-
shadowRadius: 4,
|
|
1593
|
-
elevation: 2
|
|
1716
|
+
children: [/*#__PURE__*/_jsx(TouchableOpacity, {
|
|
1717
|
+
style: [styles.viewModeButton, viewMode === 'all' && {
|
|
1718
|
+
backgroundColor: themeStyles.primaryColor
|
|
1594
1719
|
}],
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
shadowRadius: 4,
|
|
1605
|
-
elevation: 3
|
|
1606
|
-
}],
|
|
1607
|
-
onPress: () => setViewMode('all'),
|
|
1608
|
-
children: /*#__PURE__*/_jsx(Ionicons, {
|
|
1609
|
-
name: "folder",
|
|
1610
|
-
size: 18,
|
|
1611
|
-
color: viewMode === 'all' ? '#FFFFFF' : themeStyles.textColor
|
|
1612
|
-
})
|
|
1613
|
-
}), /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
1614
|
-
style: [styles.viewModeButton, viewMode === 'photos' && {
|
|
1615
|
-
backgroundColor: themeStyles.primaryColor,
|
|
1616
|
-
shadowColor: themeStyles.primaryColor,
|
|
1617
|
-
shadowOffset: {
|
|
1618
|
-
width: 0,
|
|
1619
|
-
height: 2
|
|
1620
|
-
},
|
|
1621
|
-
shadowOpacity: 0.3,
|
|
1622
|
-
shadowRadius: 4,
|
|
1623
|
-
elevation: 3
|
|
1624
|
-
}],
|
|
1625
|
-
onPress: () => setViewMode('photos'),
|
|
1626
|
-
children: /*#__PURE__*/_jsx(Ionicons, {
|
|
1627
|
-
name: "images",
|
|
1628
|
-
size: 18,
|
|
1629
|
-
color: viewMode === 'photos' ? '#FFFFFF' : themeStyles.textColor
|
|
1630
|
-
})
|
|
1631
|
-
})]
|
|
1632
|
-
}), user?.id === targetUserId && /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
1633
|
-
style: [styles.uploadButton, {
|
|
1634
|
-
backgroundColor: themeStyles.primaryColor,
|
|
1635
|
-
shadowColor: themeStyles.primaryColor,
|
|
1636
|
-
shadowOffset: {
|
|
1637
|
-
width: 0,
|
|
1638
|
-
height: 3
|
|
1639
|
-
},
|
|
1640
|
-
shadowOpacity: 0.4,
|
|
1641
|
-
shadowRadius: 6,
|
|
1642
|
-
elevation: 5,
|
|
1643
|
-
transform: uploading ? [{
|
|
1644
|
-
scale: 0.95
|
|
1645
|
-
}] : [{
|
|
1646
|
-
scale: 1
|
|
1647
|
-
}]
|
|
1720
|
+
onPress: () => setViewMode('all'),
|
|
1721
|
+
children: /*#__PURE__*/_jsx(Ionicons, {
|
|
1722
|
+
name: "folder",
|
|
1723
|
+
size: 18,
|
|
1724
|
+
color: viewMode === 'all' ? '#FFFFFF' : themeStyles.textColor
|
|
1725
|
+
})
|
|
1726
|
+
}), /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
1727
|
+
style: [styles.viewModeButton, viewMode === 'photos' && {
|
|
1728
|
+
backgroundColor: themeStyles.primaryColor
|
|
1648
1729
|
}],
|
|
1649
|
-
onPress:
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
size: "small",
|
|
1655
|
-
color: "#FFFFFF"
|
|
1656
|
-
}), uploadProgress && /*#__PURE__*/_jsxs(Text, {
|
|
1657
|
-
style: styles.uploadProgressText,
|
|
1658
|
-
children: [uploadProgress.current, "/", uploadProgress.total]
|
|
1659
|
-
})]
|
|
1660
|
-
}) : /*#__PURE__*/_jsx(Ionicons, {
|
|
1661
|
-
name: "add",
|
|
1662
|
-
size: 26,
|
|
1663
|
-
color: "#FFFFFF"
|
|
1730
|
+
onPress: () => setViewMode('photos'),
|
|
1731
|
+
children: /*#__PURE__*/_jsx(Ionicons, {
|
|
1732
|
+
name: "images",
|
|
1733
|
+
size: 18,
|
|
1734
|
+
color: viewMode === 'photos' ? '#FFFFFF' : themeStyles.textColor
|
|
1664
1735
|
})
|
|
1665
1736
|
})]
|
|
1737
|
+
}), user?.id === targetUserId && /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
1738
|
+
style: [styles.uploadButton, {
|
|
1739
|
+
backgroundColor: themeStyles.primaryColor
|
|
1740
|
+
}],
|
|
1741
|
+
onPress: handleFileUpload,
|
|
1742
|
+
disabled: uploading,
|
|
1743
|
+
children: uploading ? /*#__PURE__*/_jsxs(View, {
|
|
1744
|
+
style: styles.uploadProgress,
|
|
1745
|
+
children: [/*#__PURE__*/_jsx(ActivityIndicator, {
|
|
1746
|
+
size: "small",
|
|
1747
|
+
color: "#FFFFFF"
|
|
1748
|
+
}), uploadProgress && /*#__PURE__*/_jsxs(Text, {
|
|
1749
|
+
style: styles.uploadProgressText,
|
|
1750
|
+
children: [uploadProgress.current, "/", uploadProgress.total]
|
|
1751
|
+
})]
|
|
1752
|
+
}) : /*#__PURE__*/_jsx(Ionicons, {
|
|
1753
|
+
name: "add",
|
|
1754
|
+
size: 22,
|
|
1755
|
+
color: "#FFFFFF"
|
|
1756
|
+
})
|
|
1666
1757
|
})]
|
|
1667
1758
|
}), files.length > 0 && (viewMode === 'all' || files.some(f => f.contentType.startsWith('image/'))) && /*#__PURE__*/_jsxs(View, {
|
|
1668
1759
|
style: [styles.searchContainer, {
|
|
1669
1760
|
backgroundColor: themeStyles.isDarkTheme ? '#1A1A1A' : '#FFFFFF',
|
|
1670
|
-
borderColor: themeStyles.isDarkTheme ? '#3A3A3A' : '#E8E9EA'
|
|
1671
|
-
shadowColor: '#000000',
|
|
1672
|
-
shadowOffset: {
|
|
1673
|
-
width: 0,
|
|
1674
|
-
height: 1
|
|
1675
|
-
},
|
|
1676
|
-
shadowOpacity: themeStyles.isDarkTheme ? 0.2 : 0.05,
|
|
1677
|
-
shadowRadius: 4,
|
|
1678
|
-
elevation: 2
|
|
1761
|
+
borderColor: themeStyles.isDarkTheme ? '#3A3A3A' : '#E8E9EA'
|
|
1679
1762
|
}],
|
|
1680
1763
|
children: [/*#__PURE__*/_jsx(Ionicons, {
|
|
1681
1764
|
name: "search",
|
|
@@ -1701,15 +1784,7 @@ const FileManagementScreen = ({
|
|
|
1701
1784
|
}), files.length > 0 && /*#__PURE__*/_jsxs(View, {
|
|
1702
1785
|
style: [styles.statsContainer, {
|
|
1703
1786
|
backgroundColor: themeStyles.isDarkTheme ? '#1A1A1A' : '#FFFFFF',
|
|
1704
|
-
borderColor: themeStyles.isDarkTheme ? '#3A3A3A' : '#E8E9EA'
|
|
1705
|
-
shadowColor: '#000000',
|
|
1706
|
-
shadowOffset: {
|
|
1707
|
-
width: 0,
|
|
1708
|
-
height: 1
|
|
1709
|
-
},
|
|
1710
|
-
shadowOpacity: themeStyles.isDarkTheme ? 0.2 : 0.05,
|
|
1711
|
-
shadowRadius: 4,
|
|
1712
|
-
elevation: 2
|
|
1787
|
+
borderColor: themeStyles.isDarkTheme ? '#3A3A3A' : '#E8E9EA'
|
|
1713
1788
|
}],
|
|
1714
1789
|
children: [/*#__PURE__*/_jsxs(View, {
|
|
1715
1790
|
style: styles.statItem,
|
|
@@ -1756,7 +1831,7 @@ const FileManagementScreen = ({
|
|
|
1756
1831
|
contentContainerStyle: styles.scrollContainer,
|
|
1757
1832
|
refreshControl: /*#__PURE__*/_jsx(RefreshControl, {
|
|
1758
1833
|
refreshing: refreshing,
|
|
1759
|
-
onRefresh: () => loadFiles(
|
|
1834
|
+
onRefresh: () => loadFiles('refresh'),
|
|
1760
1835
|
tintColor: themeStyles.primaryColor
|
|
1761
1836
|
}),
|
|
1762
1837
|
children: filteredFiles.length === 0 && searchQuery.length > 0 ? /*#__PURE__*/_jsxs(View, {
|
|
@@ -1789,10 +1864,37 @@ const FileManagementScreen = ({
|
|
|
1789
1864
|
children: "Clear Search"
|
|
1790
1865
|
})]
|
|
1791
1866
|
})]
|
|
1792
|
-
}) : filteredFiles.length === 0 ? renderEmptyState() : /*#__PURE__*/_jsx(
|
|
1793
|
-
|
|
1867
|
+
}) : filteredFiles.length === 0 ? renderEmptyState() : /*#__PURE__*/_jsx(GroupedSection, {
|
|
1868
|
+
items: groupedFileItems,
|
|
1869
|
+
theme: theme
|
|
1870
|
+
})
|
|
1871
|
+
}), renderFileDetailsModal(), uploading && /*#__PURE__*/_jsx(View, {
|
|
1872
|
+
pointerEvents: "none",
|
|
1873
|
+
style: styles.uploadBannerContainer,
|
|
1874
|
+
children: /*#__PURE__*/_jsxs(View, {
|
|
1875
|
+
style: [styles.uploadBanner, {
|
|
1876
|
+
backgroundColor: themeStyles.isDarkTheme ? '#222831EE' : '#FFFFFFEE',
|
|
1877
|
+
borderColor: themeStyles.borderColor
|
|
1878
|
+
}],
|
|
1879
|
+
children: [/*#__PURE__*/_jsx(Ionicons, {
|
|
1880
|
+
name: "cloud-upload",
|
|
1881
|
+
size: 18,
|
|
1882
|
+
color: themeStyles.primaryColor
|
|
1883
|
+
}), /*#__PURE__*/_jsxs(Text, {
|
|
1884
|
+
style: [styles.uploadBannerText, {
|
|
1885
|
+
color: themeStyles.textColor
|
|
1886
|
+
}],
|
|
1887
|
+
children: ["Uploading", uploadProgress ? ` ${uploadProgress.current}/${uploadProgress.total}` : '...']
|
|
1888
|
+
}), /*#__PURE__*/_jsx(View, {
|
|
1889
|
+
style: styles.uploadBannerDots,
|
|
1890
|
+
children: [0, 1, 2].map(i => /*#__PURE__*/_jsx(View, {
|
|
1891
|
+
style: [styles.dot, {
|
|
1892
|
+
opacity: (Date.now() / 400 + i) % 3 < 1 ? 1 : 0.25
|
|
1893
|
+
}]
|
|
1894
|
+
}, i))
|
|
1895
|
+
})]
|
|
1794
1896
|
})
|
|
1795
|
-
}),
|
|
1897
|
+
}), isDragging && Platform.OS === 'web' && /*#__PURE__*/_jsx(View, {
|
|
1796
1898
|
style: styles.dragDropOverlay,
|
|
1797
1899
|
children: /*#__PURE__*/_jsxs(View, {
|
|
1798
1900
|
style: styles.dragDropContent,
|
|
@@ -1820,9 +1922,9 @@ const styles = StyleSheet.create({
|
|
|
1820
1922
|
flex: 1
|
|
1821
1923
|
},
|
|
1822
1924
|
dragOverlay: {
|
|
1823
|
-
backgroundColor: 'rgba(0, 122, 255, 0.
|
|
1824
|
-
borderWidth:
|
|
1825
|
-
borderColor: '#
|
|
1925
|
+
backgroundColor: 'rgba(0, 122, 255, 0.06)',
|
|
1926
|
+
borderWidth: 1,
|
|
1927
|
+
borderColor: '#66AFFF',
|
|
1826
1928
|
borderStyle: 'dashed'
|
|
1827
1929
|
},
|
|
1828
1930
|
centerContent: {
|
|
@@ -1833,8 +1935,8 @@ const styles = StyleSheet.create({
|
|
|
1833
1935
|
flexDirection: 'row',
|
|
1834
1936
|
alignItems: 'center',
|
|
1835
1937
|
justifyContent: 'space-between',
|
|
1836
|
-
paddingHorizontal:
|
|
1837
|
-
paddingVertical:
|
|
1938
|
+
paddingHorizontal: 16,
|
|
1939
|
+
paddingVertical: 12,
|
|
1838
1940
|
borderBottomWidth: 1,
|
|
1839
1941
|
position: 'relative'
|
|
1840
1942
|
},
|
|
@@ -1883,16 +1985,57 @@ const styles = StyleSheet.create({
|
|
|
1883
1985
|
fontWeight: '600',
|
|
1884
1986
|
marginTop: 2
|
|
1885
1987
|
},
|
|
1988
|
+
uploadBannerContainer: {
|
|
1989
|
+
position: 'absolute',
|
|
1990
|
+
top: 72,
|
|
1991
|
+
// below header
|
|
1992
|
+
left: 0,
|
|
1993
|
+
right: 0,
|
|
1994
|
+
alignItems: 'center',
|
|
1995
|
+
zIndex: 50
|
|
1996
|
+
},
|
|
1997
|
+
uploadBanner: {
|
|
1998
|
+
flexDirection: 'row',
|
|
1999
|
+
alignItems: 'center',
|
|
2000
|
+
paddingHorizontal: 14,
|
|
2001
|
+
paddingVertical: 8,
|
|
2002
|
+
borderRadius: 24,
|
|
2003
|
+
gap: 8,
|
|
2004
|
+
borderWidth: 1,
|
|
2005
|
+
shadowColor: '#000',
|
|
2006
|
+
shadowOpacity: 0.1,
|
|
2007
|
+
shadowRadius: 6,
|
|
2008
|
+
shadowOffset: {
|
|
2009
|
+
width: 0,
|
|
2010
|
+
height: 2
|
|
2011
|
+
},
|
|
2012
|
+
elevation: 2
|
|
2013
|
+
},
|
|
2014
|
+
uploadBannerText: {
|
|
2015
|
+
fontSize: 13,
|
|
2016
|
+
fontWeight: '500'
|
|
2017
|
+
},
|
|
2018
|
+
uploadBannerDots: {
|
|
2019
|
+
flexDirection: 'row',
|
|
2020
|
+
gap: 4,
|
|
2021
|
+
marginLeft: 2
|
|
2022
|
+
},
|
|
2023
|
+
dot: {
|
|
2024
|
+
width: 6,
|
|
2025
|
+
height: 6,
|
|
2026
|
+
borderRadius: 3,
|
|
2027
|
+
backgroundColor: '#007AFF'
|
|
2028
|
+
},
|
|
1886
2029
|
searchContainer: {
|
|
1887
2030
|
flexDirection: 'row',
|
|
1888
2031
|
alignItems: 'center',
|
|
1889
|
-
paddingHorizontal:
|
|
1890
|
-
paddingVertical:
|
|
1891
|
-
marginHorizontal:
|
|
1892
|
-
marginTop:
|
|
1893
|
-
borderRadius:
|
|
2032
|
+
paddingHorizontal: 14,
|
|
2033
|
+
paddingVertical: 10,
|
|
2034
|
+
marginHorizontal: 16,
|
|
2035
|
+
marginTop: 12,
|
|
2036
|
+
borderRadius: 10,
|
|
1894
2037
|
borderWidth: 1,
|
|
1895
|
-
gap:
|
|
2038
|
+
gap: 10
|
|
1896
2039
|
},
|
|
1897
2040
|
searchInput: {
|
|
1898
2041
|
flex: 1,
|
|
@@ -1911,11 +2054,11 @@ const styles = StyleSheet.create({
|
|
|
1911
2054
|
},
|
|
1912
2055
|
statsContainer: {
|
|
1913
2056
|
flexDirection: 'row',
|
|
1914
|
-
paddingHorizontal:
|
|
1915
|
-
paddingVertical:
|
|
1916
|
-
marginHorizontal:
|
|
1917
|
-
marginTop:
|
|
1918
|
-
borderRadius:
|
|
2057
|
+
paddingHorizontal: 14,
|
|
2058
|
+
paddingVertical: 10,
|
|
2059
|
+
marginHorizontal: 16,
|
|
2060
|
+
marginTop: 12,
|
|
2061
|
+
borderRadius: 10,
|
|
1919
2062
|
borderWidth: 1
|
|
1920
2063
|
},
|
|
1921
2064
|
statItem: {
|
|
@@ -1924,31 +2067,31 @@ const styles = StyleSheet.create({
|
|
|
1924
2067
|
paddingVertical: 4
|
|
1925
2068
|
},
|
|
1926
2069
|
statValue: {
|
|
1927
|
-
fontSize:
|
|
2070
|
+
fontSize: 20,
|
|
1928
2071
|
fontWeight: '800',
|
|
1929
2072
|
fontFamily: fontFamilies.phuduBold,
|
|
1930
2073
|
letterSpacing: -0.5,
|
|
1931
|
-
lineHeight:
|
|
2074
|
+
lineHeight: 24
|
|
1932
2075
|
},
|
|
1933
2076
|
statLabel: {
|
|
1934
|
-
fontSize:
|
|
2077
|
+
fontSize: 12,
|
|
1935
2078
|
fontWeight: '500',
|
|
1936
2079
|
fontFamily: fontFamilies.phuduMedium,
|
|
1937
|
-
marginTop:
|
|
1938
|
-
letterSpacing: 0.
|
|
2080
|
+
marginTop: 2,
|
|
2081
|
+
letterSpacing: 0.2
|
|
1939
2082
|
},
|
|
1940
2083
|
scrollView: {
|
|
1941
2084
|
flex: 1
|
|
1942
2085
|
},
|
|
1943
2086
|
scrollContainer: {
|
|
1944
|
-
padding:
|
|
2087
|
+
padding: 12
|
|
1945
2088
|
},
|
|
1946
2089
|
fileItem: {
|
|
1947
2090
|
flexDirection: 'row',
|
|
1948
2091
|
alignItems: 'center',
|
|
1949
|
-
padding:
|
|
1950
|
-
marginBottom:
|
|
1951
|
-
borderRadius:
|
|
2092
|
+
padding: 10,
|
|
2093
|
+
marginBottom: 8,
|
|
2094
|
+
borderRadius: 10,
|
|
1952
2095
|
borderWidth: 1
|
|
1953
2096
|
},
|
|
1954
2097
|
fileContent: {
|
|
@@ -1964,15 +2107,15 @@ const styles = StyleSheet.create({
|
|
|
1964
2107
|
marginRight: 12
|
|
1965
2108
|
},
|
|
1966
2109
|
filePreviewContainer: {
|
|
1967
|
-
width:
|
|
1968
|
-
height:
|
|
1969
|
-
marginRight:
|
|
2110
|
+
width: 52,
|
|
2111
|
+
height: 52,
|
|
2112
|
+
marginRight: 10
|
|
1970
2113
|
},
|
|
1971
2114
|
filePreview: {
|
|
1972
2115
|
width: '100%',
|
|
1973
2116
|
height: '100%',
|
|
1974
2117
|
borderRadius: 8,
|
|
1975
|
-
backgroundColor: '
|
|
2118
|
+
backgroundColor: 'transparent',
|
|
1976
2119
|
alignItems: 'center',
|
|
1977
2120
|
justifyContent: 'center',
|
|
1978
2121
|
overflow: 'hidden',
|
|
@@ -2015,7 +2158,7 @@ const styles = StyleSheet.create({
|
|
|
2015
2158
|
bottom: 0,
|
|
2016
2159
|
alignItems: 'center',
|
|
2017
2160
|
justifyContent: 'center',
|
|
2018
|
-
backgroundColor: '
|
|
2161
|
+
backgroundColor: 'transparent',
|
|
2019
2162
|
borderRadius: 8
|
|
2020
2163
|
},
|
|
2021
2164
|
previewOverlay: {
|
|
@@ -2024,11 +2167,57 @@ const styles = StyleSheet.create({
|
|
|
2024
2167
|
left: 0,
|
|
2025
2168
|
right: 0,
|
|
2026
2169
|
bottom: 0,
|
|
2027
|
-
backgroundColor: 'rgba(0, 0, 0, 0.
|
|
2170
|
+
backgroundColor: 'rgba(0, 0, 0, 0.25)',
|
|
2028
2171
|
alignItems: 'center',
|
|
2029
2172
|
justifyContent: 'center',
|
|
2030
2173
|
borderRadius: 8
|
|
2031
2174
|
},
|
|
2175
|
+
groupedActions: {
|
|
2176
|
+
flexDirection: 'row',
|
|
2177
|
+
alignItems: 'center',
|
|
2178
|
+
gap: 6,
|
|
2179
|
+
marginLeft: 12
|
|
2180
|
+
},
|
|
2181
|
+
groupedActionBtn: {
|
|
2182
|
+
width: 34,
|
|
2183
|
+
height: 34,
|
|
2184
|
+
borderRadius: 8,
|
|
2185
|
+
alignItems: 'center',
|
|
2186
|
+
justifyContent: 'center'
|
|
2187
|
+
},
|
|
2188
|
+
groupedDescription: {
|
|
2189
|
+
fontSize: 12,
|
|
2190
|
+
lineHeight: 16,
|
|
2191
|
+
marginTop: 6
|
|
2192
|
+
},
|
|
2193
|
+
videoPreviewWrapper: {
|
|
2194
|
+
width: '100%',
|
|
2195
|
+
height: '100%',
|
|
2196
|
+
borderRadius: 8,
|
|
2197
|
+
overflow: 'hidden',
|
|
2198
|
+
backgroundColor: '#000000',
|
|
2199
|
+
alignItems: 'center',
|
|
2200
|
+
justifyContent: 'center'
|
|
2201
|
+
},
|
|
2202
|
+
videoPosterImage: {
|
|
2203
|
+
position: 'absolute',
|
|
2204
|
+
top: 0,
|
|
2205
|
+
left: 0,
|
|
2206
|
+
right: 0,
|
|
2207
|
+
bottom: 0,
|
|
2208
|
+
width: '100%',
|
|
2209
|
+
height: '100%'
|
|
2210
|
+
},
|
|
2211
|
+
videoOverlay: {
|
|
2212
|
+
position: 'absolute',
|
|
2213
|
+
top: 0,
|
|
2214
|
+
left: 0,
|
|
2215
|
+
right: 0,
|
|
2216
|
+
bottom: 0,
|
|
2217
|
+
alignItems: 'center',
|
|
2218
|
+
justifyContent: 'center',
|
|
2219
|
+
backgroundColor: 'rgba(0,0,0,0.25)'
|
|
2220
|
+
},
|
|
2032
2221
|
fileInfo: {
|
|
2033
2222
|
flex: 1
|
|
2034
2223
|
},
|
|
@@ -2050,16 +2239,19 @@ const styles = StyleSheet.create({
|
|
|
2050
2239
|
gap: 8
|
|
2051
2240
|
},
|
|
2052
2241
|
actionButton: {
|
|
2053
|
-
width:
|
|
2054
|
-
height:
|
|
2055
|
-
borderRadius:
|
|
2242
|
+
width: 36,
|
|
2243
|
+
height: 36,
|
|
2244
|
+
borderRadius: 18,
|
|
2056
2245
|
alignItems: 'center',
|
|
2057
|
-
justifyContent: 'center'
|
|
2246
|
+
justifyContent: 'center',
|
|
2247
|
+
borderWidth: 1,
|
|
2248
|
+
borderColor: '#E0E0E0',
|
|
2249
|
+
backgroundColor: 'transparent'
|
|
2058
2250
|
},
|
|
2059
2251
|
emptyState: {
|
|
2060
2252
|
alignItems: 'center',
|
|
2061
|
-
paddingVertical:
|
|
2062
|
-
paddingHorizontal:
|
|
2253
|
+
paddingVertical: 40,
|
|
2254
|
+
paddingHorizontal: 24
|
|
2063
2255
|
},
|
|
2064
2256
|
emptyStateTitle: {
|
|
2065
2257
|
fontSize: 24,
|
|
@@ -2099,8 +2291,8 @@ const styles = StyleSheet.create({
|
|
|
2099
2291
|
flexDirection: 'row',
|
|
2100
2292
|
alignItems: 'center',
|
|
2101
2293
|
justifyContent: 'space-between',
|
|
2102
|
-
paddingHorizontal:
|
|
2103
|
-
paddingVertical:
|
|
2294
|
+
paddingHorizontal: 16,
|
|
2295
|
+
paddingVertical: 12,
|
|
2104
2296
|
borderBottomWidth: 1
|
|
2105
2297
|
},
|
|
2106
2298
|
modalCloseButton: {
|
|
@@ -2116,11 +2308,11 @@ const styles = StyleSheet.create({
|
|
|
2116
2308
|
},
|
|
2117
2309
|
modalContent: {
|
|
2118
2310
|
flex: 1,
|
|
2119
|
-
padding:
|
|
2311
|
+
padding: 16
|
|
2120
2312
|
},
|
|
2121
2313
|
fileDetailCard: {
|
|
2122
|
-
padding:
|
|
2123
|
-
borderRadius:
|
|
2314
|
+
padding: 18,
|
|
2315
|
+
borderRadius: 14,
|
|
2124
2316
|
borderWidth: 1,
|
|
2125
2317
|
alignItems: 'center'
|
|
2126
2318
|
},
|
|
@@ -2182,25 +2374,25 @@ const styles = StyleSheet.create({
|
|
|
2182
2374
|
left: 0,
|
|
2183
2375
|
right: 0,
|
|
2184
2376
|
bottom: 0,
|
|
2185
|
-
backgroundColor: 'rgba(0, 0, 0, 0.
|
|
2377
|
+
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
2186
2378
|
justifyContent: 'center',
|
|
2187
2379
|
alignItems: 'center',
|
|
2188
2380
|
zIndex: 1000
|
|
2189
2381
|
},
|
|
2190
2382
|
dragDropContent: {
|
|
2191
2383
|
alignItems: 'center',
|
|
2192
|
-
backgroundColor: 'rgba(255, 255, 255, 0.
|
|
2193
|
-
padding:
|
|
2194
|
-
borderRadius:
|
|
2195
|
-
borderWidth:
|
|
2196
|
-
borderColor: '#
|
|
2384
|
+
backgroundColor: 'rgba(255, 255, 255, 0.95)',
|
|
2385
|
+
padding: 20,
|
|
2386
|
+
borderRadius: 14,
|
|
2387
|
+
borderWidth: 1,
|
|
2388
|
+
borderColor: '#66AFFF',
|
|
2197
2389
|
borderStyle: 'dashed'
|
|
2198
2390
|
},
|
|
2199
2391
|
dragDropTitle: {
|
|
2200
|
-
fontSize:
|
|
2392
|
+
fontSize: 20,
|
|
2201
2393
|
fontWeight: 'bold',
|
|
2202
|
-
marginTop:
|
|
2203
|
-
marginBottom:
|
|
2394
|
+
marginTop: 12,
|
|
2395
|
+
marginBottom: 6
|
|
2204
2396
|
},
|
|
2205
2397
|
dragDropSubtitle: {
|
|
2206
2398
|
fontSize: 16,
|
|
@@ -2213,8 +2405,8 @@ const styles = StyleSheet.create({
|
|
|
2213
2405
|
fileViewerHeader: {
|
|
2214
2406
|
flexDirection: 'row',
|
|
2215
2407
|
alignItems: 'center',
|
|
2216
|
-
paddingHorizontal:
|
|
2217
|
-
paddingVertical:
|
|
2408
|
+
paddingHorizontal: 16,
|
|
2409
|
+
paddingVertical: 12,
|
|
2218
2410
|
borderBottomWidth: 1
|
|
2219
2411
|
},
|
|
2220
2412
|
fileViewerTitleContainer: {
|
|
@@ -2242,7 +2434,7 @@ const styles = StyleSheet.create({
|
|
|
2242
2434
|
},
|
|
2243
2435
|
fileViewerContentContainer: {
|
|
2244
2436
|
flexGrow: 1,
|
|
2245
|
-
padding:
|
|
2437
|
+
padding: 14
|
|
2246
2438
|
},
|
|
2247
2439
|
fileViewerLoading: {
|
|
2248
2440
|
flex: 1,
|
|
@@ -2260,10 +2452,10 @@ const styles = StyleSheet.create({
|
|
|
2260
2452
|
},
|
|
2261
2453
|
textContainer: {
|
|
2262
2454
|
flex: 1,
|
|
2263
|
-
borderRadius:
|
|
2455
|
+
borderRadius: 10,
|
|
2264
2456
|
borderWidth: 1,
|
|
2265
|
-
padding:
|
|
2266
|
-
minHeight:
|
|
2457
|
+
padding: 12,
|
|
2458
|
+
minHeight: 180,
|
|
2267
2459
|
maxHeight: '80%'
|
|
2268
2460
|
},
|
|
2269
2461
|
textContent: {
|
|
@@ -2275,8 +2467,8 @@ const styles = StyleSheet.create({
|
|
|
2275
2467
|
flex: 1,
|
|
2276
2468
|
justifyContent: 'center',
|
|
2277
2469
|
alignItems: 'center',
|
|
2278
|
-
paddingVertical:
|
|
2279
|
-
paddingHorizontal:
|
|
2470
|
+
paddingVertical: 40,
|
|
2471
|
+
paddingHorizontal: 24
|
|
2280
2472
|
},
|
|
2281
2473
|
unsupportedFileTitle: {
|
|
2282
2474
|
fontSize: 24,
|
|
@@ -2295,9 +2487,9 @@ const styles = StyleSheet.create({
|
|
|
2295
2487
|
downloadButtonLarge: {
|
|
2296
2488
|
flexDirection: 'row',
|
|
2297
2489
|
alignItems: 'center',
|
|
2298
|
-
paddingHorizontal:
|
|
2299
|
-
paddingVertical:
|
|
2300
|
-
borderRadius:
|
|
2490
|
+
paddingHorizontal: 18,
|
|
2491
|
+
paddingVertical: 12,
|
|
2492
|
+
borderRadius: 20,
|
|
2301
2493
|
gap: 8
|
|
2302
2494
|
},
|
|
2303
2495
|
downloadButtonText: {
|
|
@@ -2323,10 +2515,10 @@ const styles = StyleSheet.create({
|
|
|
2323
2515
|
},
|
|
2324
2516
|
// File Details in Viewer styles
|
|
2325
2517
|
fileDetailsSection: {
|
|
2326
|
-
margin:
|
|
2518
|
+
margin: 12,
|
|
2327
2519
|
marginTop: 0,
|
|
2328
|
-
padding:
|
|
2329
|
-
borderRadius:
|
|
2520
|
+
padding: 14,
|
|
2521
|
+
borderRadius: 10,
|
|
2330
2522
|
borderWidth: 1
|
|
2331
2523
|
},
|
|
2332
2524
|
fileDetailsSectionTitle: {
|
|
@@ -2369,6 +2561,15 @@ const styles = StyleSheet.create({
|
|
|
2369
2561
|
alignItems: 'center',
|
|
2370
2562
|
gap: 16
|
|
2371
2563
|
},
|
|
2564
|
+
controlsBar: {
|
|
2565
|
+
flexDirection: 'row',
|
|
2566
|
+
alignItems: 'center',
|
|
2567
|
+
justifyContent: 'space-between',
|
|
2568
|
+
paddingHorizontal: 16,
|
|
2569
|
+
paddingTop: 8,
|
|
2570
|
+
paddingBottom: 4,
|
|
2571
|
+
gap: 12
|
|
2572
|
+
},
|
|
2372
2573
|
viewModeToggle: {
|
|
2373
2574
|
flexDirection: 'row',
|
|
2374
2575
|
borderRadius: 24,
|
|
@@ -2386,17 +2587,17 @@ const styles = StyleSheet.create({
|
|
|
2386
2587
|
},
|
|
2387
2588
|
// Photo Grid styles
|
|
2388
2589
|
photoScrollContainer: {
|
|
2389
|
-
padding:
|
|
2590
|
+
padding: 10
|
|
2390
2591
|
},
|
|
2391
2592
|
photoDateSection: {
|
|
2392
|
-
marginBottom:
|
|
2593
|
+
marginBottom: 16
|
|
2393
2594
|
},
|
|
2394
2595
|
photoDateHeader: {
|
|
2395
|
-
fontSize:
|
|
2596
|
+
fontSize: 16,
|
|
2396
2597
|
fontWeight: '600',
|
|
2397
2598
|
fontFamily: fontFamilies.phuduSemiBold,
|
|
2398
|
-
marginBottom:
|
|
2399
|
-
paddingHorizontal:
|
|
2599
|
+
marginBottom: 8,
|
|
2600
|
+
paddingHorizontal: 2
|
|
2400
2601
|
},
|
|
2401
2602
|
photoGrid: {
|
|
2402
2603
|
flexDirection: 'row',
|
|
@@ -2448,7 +2649,7 @@ const styles = StyleSheet.create({
|
|
|
2448
2649
|
position: 'relative',
|
|
2449
2650
|
borderRadius: 6,
|
|
2450
2651
|
overflow: 'hidden',
|
|
2451
|
-
backgroundColor: '
|
|
2652
|
+
backgroundColor: 'transparent'
|
|
2452
2653
|
},
|
|
2453
2654
|
justifiedPhotoImage: {
|
|
2454
2655
|
width: '100%',
|
|
@@ -2459,7 +2660,7 @@ const styles = StyleSheet.create({
|
|
|
2459
2660
|
simplePhotoItem: {
|
|
2460
2661
|
borderRadius: 8,
|
|
2461
2662
|
overflow: 'hidden',
|
|
2462
|
-
backgroundColor: '
|
|
2663
|
+
backgroundColor: 'transparent'
|
|
2463
2664
|
},
|
|
2464
2665
|
simplePhotoContainer: {
|
|
2465
2666
|
width: '100%',
|