@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
|
@@ -6,30 +6,20 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
|
+
var _expoImage = require("expo-image");
|
|
9
10
|
var _OxyContext = require("../context/OxyContext");
|
|
10
11
|
var _fonts = require("../styles/fonts");
|
|
11
12
|
var _sonner = require("../../lib/sonner");
|
|
12
13
|
var _vectorIcons = require("@expo/vector-icons");
|
|
14
|
+
var _fileStore = require("../stores/fileStore");
|
|
15
|
+
var _Header = _interopRequireDefault(require("../components/Header"));
|
|
16
|
+
var _components = require("../components");
|
|
13
17
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
18
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
19
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
15
20
|
// Add this helper function near the top (after imports):
|
|
16
|
-
async function uploadFileRaw(file, userId) {
|
|
17
|
-
|
|
18
|
-
const mimeType = file.type || 'application/octet-stream';
|
|
19
|
-
const res = await fetch('/api/files/upload-raw', {
|
|
20
|
-
method: 'POST',
|
|
21
|
-
headers: {
|
|
22
|
-
'Content-Type': mimeType,
|
|
23
|
-
'X-File-Name': encodeURIComponent(fileName),
|
|
24
|
-
'X-User-Id': userId
|
|
25
|
-
},
|
|
26
|
-
body: file,
|
|
27
|
-
credentials: 'include' // if you use cookies/session
|
|
28
|
-
});
|
|
29
|
-
if (!res.ok) {
|
|
30
|
-
throw new Error(await res.text());
|
|
31
|
-
}
|
|
32
|
-
return await res.json();
|
|
21
|
+
async function uploadFileRaw(file, userId, oxyServices) {
|
|
22
|
+
return await oxyServices.uploadRawFile(file);
|
|
33
23
|
}
|
|
34
24
|
const FileManagementScreen = ({
|
|
35
25
|
onClose,
|
|
@@ -55,12 +45,12 @@ const FileManagementScreen = ({
|
|
|
55
45
|
console.log('[FileManagementScreen] Available content width:', availableContentWidth);
|
|
56
46
|
console.log('[FileManagementScreen] Spacing fix applied: 4px uniform gap both horizontal and vertical');
|
|
57
47
|
}, [containerWidth]);
|
|
58
|
-
const
|
|
48
|
+
const files = (0, _fileStore.useFiles)();
|
|
49
|
+
const uploading = (0, _fileStore.useUploading)();
|
|
50
|
+
const uploadProgress = (0, _fileStore.useUploadAggregateProgress)();
|
|
51
|
+
const deleting = (0, _fileStore.useDeleting)();
|
|
59
52
|
const [loading, setLoading] = (0, _react.useState)(true);
|
|
60
53
|
const [refreshing, setRefreshing] = (0, _react.useState)(false);
|
|
61
|
-
const [uploading, setUploading] = (0, _react.useState)(false);
|
|
62
|
-
const [uploadProgress, setUploadProgress] = (0, _react.useState)(null);
|
|
63
|
-
const [deleting, setDeleting] = (0, _react.useState)(null);
|
|
64
54
|
const [selectedFile, setSelectedFile] = (0, _react.useState)(null);
|
|
65
55
|
const [showFileDetails, setShowFileDetails] = (0, _react.useState)(false);
|
|
66
56
|
const [openedFile, setOpenedFile] = (0, _react.useState)(null);
|
|
@@ -69,11 +59,66 @@ const FileManagementScreen = ({
|
|
|
69
59
|
const [showFileDetailsInViewer, setShowFileDetailsInViewer] = (0, _react.useState)(false);
|
|
70
60
|
const [viewMode, setViewMode] = (0, _react.useState)('all');
|
|
71
61
|
const [searchQuery, setSearchQuery] = (0, _react.useState)('');
|
|
72
|
-
|
|
62
|
+
// Derived filtered files (avoid setState loops)
|
|
63
|
+
const filteredFiles = (0, _react.useMemo)(() => {
|
|
64
|
+
let filteredByMode = files;
|
|
65
|
+
if (viewMode === 'photos') {
|
|
66
|
+
filteredByMode = files.filter(file => file.contentType.startsWith('image/'));
|
|
67
|
+
}
|
|
68
|
+
if (!searchQuery.trim()) {
|
|
69
|
+
return filteredByMode;
|
|
70
|
+
}
|
|
71
|
+
const query = searchQuery.toLowerCase();
|
|
72
|
+
return filteredByMode.filter(file => file.filename.toLowerCase().includes(query) || file.contentType.toLowerCase().includes(query) || file.metadata?.description && file.metadata.description.toLowerCase().includes(query));
|
|
73
|
+
}, [files, searchQuery, viewMode]);
|
|
73
74
|
const [isDragging, setIsDragging] = (0, _react.useState)(false);
|
|
74
75
|
const [photoDimensions, setPhotoDimensions] = (0, _react.useState)({});
|
|
75
76
|
const [loadingDimensions, setLoadingDimensions] = (0, _react.useState)(false);
|
|
76
77
|
const [hoveredPreview, setHoveredPreview] = (0, _react.useState)(null);
|
|
78
|
+
const uploadStartRef = (0, _react.useRef)(null);
|
|
79
|
+
const MIN_BANNER_MS = 600;
|
|
80
|
+
const endUpload = (0, _react.useCallback)(() => {
|
|
81
|
+
const started = uploadStartRef.current;
|
|
82
|
+
const elapsed = started ? Date.now() - started : MIN_BANNER_MS;
|
|
83
|
+
const remaining = elapsed < MIN_BANNER_MS ? MIN_BANNER_MS - elapsed : 0;
|
|
84
|
+
setTimeout(() => {
|
|
85
|
+
_fileStore.useFileStore.getState().setUploading(false);
|
|
86
|
+
uploadStartRef.current = null;
|
|
87
|
+
}, remaining);
|
|
88
|
+
}, []);
|
|
89
|
+
|
|
90
|
+
// Helper to safely request a thumbnail variant only for image mime types.
|
|
91
|
+
// Prevents backend warnings: "Variant thumb not supported for mime application/pdf".
|
|
92
|
+
const getSafeDownloadUrl = (0, _react.useCallback)((file, variant = 'thumb') => {
|
|
93
|
+
const isImage = file.contentType.startsWith('image/');
|
|
94
|
+
const isVideo = file.contentType.startsWith('video/');
|
|
95
|
+
|
|
96
|
+
// Prefer explicit variant key if variants metadata present
|
|
97
|
+
if (file.variants && file.variants.length > 0) {
|
|
98
|
+
// For videos, try 'poster' regardless of requested variant
|
|
99
|
+
if (isVideo) {
|
|
100
|
+
const poster = file.variants.find(v => v.type === 'poster');
|
|
101
|
+
if (poster) return oxyServices.getFileDownloadUrl(file.id, 'poster');
|
|
102
|
+
}
|
|
103
|
+
if (isImage) {
|
|
104
|
+
const desired = file.variants.find(v => v.type === variant);
|
|
105
|
+
if (desired) return oxyServices.getFileDownloadUrl(file.id, variant);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (isImage) {
|
|
109
|
+
return oxyServices.getFileDownloadUrl(file.id, variant);
|
|
110
|
+
}
|
|
111
|
+
if (isVideo) {
|
|
112
|
+
// Fallback to poster if backend supports implicit generation
|
|
113
|
+
try {
|
|
114
|
+
return oxyServices.getFileDownloadUrl(file.id, 'poster');
|
|
115
|
+
} catch {
|
|
116
|
+
return oxyServices.getFileDownloadUrl(file.id);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Other mime types: no variant
|
|
120
|
+
return oxyServices.getFileDownloadUrl(file.id);
|
|
121
|
+
}, [oxyServices]);
|
|
77
122
|
|
|
78
123
|
// Memoize theme-related calculations to prevent unnecessary recalculations
|
|
79
124
|
const themeStyles = (0, _react.useMemo)(() => {
|
|
@@ -94,16 +139,32 @@ const FileManagementScreen = ({
|
|
|
94
139
|
const backgroundColor = themeStyles.backgroundColor;
|
|
95
140
|
const borderColor = themeStyles.borderColor;
|
|
96
141
|
const targetUserId = userId || user?.id;
|
|
97
|
-
const
|
|
142
|
+
const storeSetUploading = (0, _fileStore.useFileStore)(s => s.setUploading);
|
|
143
|
+
const storeSetUploadProgress = (0, _fileStore.useFileStore)(s => s.setUploadProgress);
|
|
144
|
+
const storeSetDeleting = (0, _fileStore.useFileStore)(s => s.setDeleting);
|
|
145
|
+
const loadFiles = (0, _react.useCallback)(async (mode = 'initial') => {
|
|
98
146
|
if (!targetUserId) return;
|
|
99
147
|
try {
|
|
100
|
-
if (
|
|
148
|
+
if (mode === 'refresh') {
|
|
101
149
|
setRefreshing(true);
|
|
102
|
-
} else {
|
|
150
|
+
} else if (mode === 'initial') {
|
|
103
151
|
setLoading(true);
|
|
104
152
|
}
|
|
105
|
-
const response = await oxyServices.listUserFiles(
|
|
106
|
-
|
|
153
|
+
const response = await oxyServices.listUserFiles();
|
|
154
|
+
const assets = (response.files || []).map(f => ({
|
|
155
|
+
id: f.id,
|
|
156
|
+
filename: f.originalName || f.sha256,
|
|
157
|
+
contentType: f.mime,
|
|
158
|
+
length: f.size,
|
|
159
|
+
chunkSize: 0,
|
|
160
|
+
uploadDate: f.createdAt,
|
|
161
|
+
metadata: f.metadata || {},
|
|
162
|
+
variants: f.variants || []
|
|
163
|
+
}));
|
|
164
|
+
// Merge to preserve existing order & allow incremental updates
|
|
165
|
+
_fileStore.useFileStore.getState().setFiles(assets, {
|
|
166
|
+
merge: true
|
|
167
|
+
});
|
|
107
168
|
} catch (error) {
|
|
108
169
|
console.error('Failed to load files:', error);
|
|
109
170
|
_sonner.toast.error(error.message || 'Failed to load files');
|
|
@@ -113,24 +174,7 @@ const FileManagementScreen = ({
|
|
|
113
174
|
}
|
|
114
175
|
}, [targetUserId, oxyServices]);
|
|
115
176
|
|
|
116
|
-
//
|
|
117
|
-
(0, _react.useEffect)(() => {
|
|
118
|
-
let filteredByMode = files;
|
|
119
|
-
|
|
120
|
-
// Filter by view mode first
|
|
121
|
-
if (viewMode === 'photos') {
|
|
122
|
-
filteredByMode = files.filter(file => file.contentType.startsWith('image/'));
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Then filter by search query
|
|
126
|
-
if (!searchQuery.trim()) {
|
|
127
|
-
setFilteredFiles(filteredByMode);
|
|
128
|
-
} else {
|
|
129
|
-
const query = searchQuery.toLowerCase();
|
|
130
|
-
const filtered = filteredByMode.filter(file => file.filename.toLowerCase().includes(query) || file.contentType.toLowerCase().includes(query) || file.metadata?.description && file.metadata.description.toLowerCase().includes(query));
|
|
131
|
-
setFilteredFiles(filtered);
|
|
132
|
-
}
|
|
133
|
-
}, [files, searchQuery, viewMode]);
|
|
177
|
+
// (removed effect; filteredFiles is memoized)
|
|
134
178
|
|
|
135
179
|
// Load photo dimensions for justified grid
|
|
136
180
|
const loadPhotoDimensions = (0, _react.useCallback)(async photos => {
|
|
@@ -150,7 +194,7 @@ const FileManagementScreen = ({
|
|
|
150
194
|
try {
|
|
151
195
|
await Promise.all(photosToLoad.map(async photo => {
|
|
152
196
|
try {
|
|
153
|
-
const downloadUrl =
|
|
197
|
+
const downloadUrl = getSafeDownloadUrl(photo, 'thumb');
|
|
154
198
|
if (_reactNative.Platform.OS === 'web') {
|
|
155
199
|
const img = new window.Image();
|
|
156
200
|
await new Promise((resolve, reject) => {
|
|
@@ -229,7 +273,7 @@ const FileManagementScreen = ({
|
|
|
229
273
|
if (selectedFiles.length === 0) return;
|
|
230
274
|
if (!targetUserId) return; // Guard clause to ensure userId is defined
|
|
231
275
|
try {
|
|
232
|
-
|
|
276
|
+
storeSetUploadProgress({
|
|
233
277
|
current: 0,
|
|
234
278
|
total: selectedFiles.length
|
|
235
279
|
});
|
|
@@ -244,12 +288,55 @@ const FileManagementScreen = ({
|
|
|
244
288
|
let failureCount = 0;
|
|
245
289
|
const errors = [];
|
|
246
290
|
for (let i = 0; i < selectedFiles.length; i++) {
|
|
247
|
-
|
|
291
|
+
storeSetUploadProgress({
|
|
248
292
|
current: i + 1,
|
|
249
293
|
total: selectedFiles.length
|
|
250
294
|
});
|
|
251
295
|
try {
|
|
252
|
-
|
|
296
|
+
const raw = selectedFiles[i];
|
|
297
|
+
const optimisticId = `temp-${Date.now()}-${i}`;
|
|
298
|
+
const optimisticFile = {
|
|
299
|
+
id: optimisticId,
|
|
300
|
+
filename: raw.name,
|
|
301
|
+
contentType: raw.type || 'application/octet-stream',
|
|
302
|
+
length: raw.size,
|
|
303
|
+
chunkSize: 0,
|
|
304
|
+
uploadDate: new Date().toISOString(),
|
|
305
|
+
metadata: {
|
|
306
|
+
uploading: true
|
|
307
|
+
},
|
|
308
|
+
variants: []
|
|
309
|
+
};
|
|
310
|
+
_fileStore.useFileStore.getState().addFile(optimisticFile, {
|
|
311
|
+
prepend: true
|
|
312
|
+
});
|
|
313
|
+
const result = await uploadFileRaw(raw, targetUserId, oxyServices);
|
|
314
|
+
// Attempt to refresh file list incrementally – fetch single file metadata if API allows
|
|
315
|
+
if (result?.file || result?.files?.[0]) {
|
|
316
|
+
const f = result.file || result.files[0];
|
|
317
|
+
const merged = {
|
|
318
|
+
id: f.id,
|
|
319
|
+
filename: f.originalName || f.sha256 || raw.name,
|
|
320
|
+
contentType: f.mime || raw.type || 'application/octet-stream',
|
|
321
|
+
length: f.size || raw.size,
|
|
322
|
+
chunkSize: 0,
|
|
323
|
+
uploadDate: f.createdAt || new Date().toISOString(),
|
|
324
|
+
metadata: f.metadata || {},
|
|
325
|
+
variants: f.variants || []
|
|
326
|
+
};
|
|
327
|
+
// Remove optimistic then add real
|
|
328
|
+
_fileStore.useFileStore.getState().removeFile(optimisticId);
|
|
329
|
+
_fileStore.useFileStore.getState().addFile(merged, {
|
|
330
|
+
prepend: true
|
|
331
|
+
});
|
|
332
|
+
} else {
|
|
333
|
+
// Fallback: will reconcile on later list refresh
|
|
334
|
+
_fileStore.useFileStore.getState().updateFile(optimisticId, {
|
|
335
|
+
metadata: {
|
|
336
|
+
uploading: false
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
}
|
|
253
340
|
successCount++;
|
|
254
341
|
} catch (error) {
|
|
255
342
|
failureCount++;
|
|
@@ -263,29 +350,51 @@ const FileManagementScreen = ({
|
|
|
263
350
|
const errorMessage = `${failureCount} file(s) failed to upload${errors.length > 0 ? ':\n' + errors.slice(0, 3).join('\n') + (errors.length > 3 ? '\n...' : '') : ''}`;
|
|
264
351
|
_sonner.toast.error(errorMessage);
|
|
265
352
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
353
|
+
// Silent background refresh to ensure metadata/variants updated
|
|
354
|
+
setTimeout(() => {
|
|
355
|
+
loadFiles('silent');
|
|
356
|
+
}, 1200);
|
|
269
357
|
} catch (error) {
|
|
270
358
|
console.error('Upload error:', error);
|
|
271
359
|
_sonner.toast.error(error.message || 'Failed to upload files');
|
|
272
360
|
} finally {
|
|
273
|
-
|
|
361
|
+
storeSetUploadProgress(null);
|
|
274
362
|
}
|
|
275
363
|
};
|
|
276
364
|
const handleFileUpload = async () => {
|
|
277
365
|
try {
|
|
278
|
-
|
|
279
|
-
|
|
366
|
+
uploadStartRef.current = Date.now();
|
|
367
|
+
storeSetUploading(true);
|
|
368
|
+
storeSetUploadProgress(null);
|
|
280
369
|
if (_reactNative.Platform.OS === 'web') {
|
|
281
370
|
// Web file picker implementation
|
|
282
371
|
const input = document.createElement('input');
|
|
283
372
|
input.type = 'file';
|
|
284
373
|
input.multiple = true;
|
|
285
374
|
input.accept = '*/*';
|
|
375
|
+
// Fallback: if the user cancels the dialog (no onchange fires or 0 files), hide banner
|
|
376
|
+
const cancellationTimer = setTimeout(() => {
|
|
377
|
+
const state = _fileStore.useFileStore.getState();
|
|
378
|
+
if (state.uploading && uploadStartRef.current && !state.uploadProgress) {
|
|
379
|
+
// No selection happened; treat as cancel
|
|
380
|
+
endUpload();
|
|
381
|
+
}
|
|
382
|
+
}, 1500); // allow enough time for user to pick
|
|
383
|
+
|
|
286
384
|
input.onchange = async e => {
|
|
287
|
-
|
|
385
|
+
clearTimeout(cancellationTimer);
|
|
386
|
+
const selectedFiles = Array.from(e.target.files || []);
|
|
387
|
+
if (selectedFiles.length === 0) {
|
|
388
|
+
// User explicitly canceled (some browsers still fire onchange with empty list)
|
|
389
|
+
endUpload();
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
storeSetUploadProgress({
|
|
393
|
+
current: 0,
|
|
394
|
+
total: selectedFiles.length
|
|
395
|
+
});
|
|
288
396
|
await processFileUploads(selectedFiles);
|
|
397
|
+
endUpload();
|
|
289
398
|
};
|
|
290
399
|
input.click();
|
|
291
400
|
} else {
|
|
@@ -301,8 +410,11 @@ const FileManagementScreen = ({
|
|
|
301
410
|
} catch (error) {
|
|
302
411
|
_sonner.toast.error(error.message || 'Failed to upload file');
|
|
303
412
|
} finally {
|
|
304
|
-
|
|
305
|
-
|
|
413
|
+
// IMPORTANT: Do NOT call endUpload here.
|
|
414
|
+
// We only want to hide the banner after the actual upload(s) complete.
|
|
415
|
+
// The input.onchange handler invokes processFileUploads then calls endUpload().
|
|
416
|
+
// Calling endUpload here caused the banner to disappear while files were still uploading.
|
|
417
|
+
storeSetUploadProgress(null); // keep clearing any stale progress
|
|
306
418
|
}
|
|
307
419
|
};
|
|
308
420
|
const handleFileDelete = async (fileId, filename) => {
|
|
@@ -319,15 +431,16 @@ const FileManagementScreen = ({
|
|
|
319
431
|
});
|
|
320
432
|
console.log('Target user ID:', targetUserId);
|
|
321
433
|
console.log('Current user ID:', user?.id);
|
|
322
|
-
|
|
434
|
+
storeSetDeleting(fileId);
|
|
323
435
|
const result = await oxyServices.deleteFile(fileId);
|
|
324
436
|
console.log('Delete result:', result);
|
|
325
437
|
_sonner.toast.success('File deleted successfully');
|
|
326
438
|
|
|
327
439
|
// Reload files after successful deletion
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
440
|
+
// Optimistic remove
|
|
441
|
+
_fileStore.useFileStore.getState().removeFile(fileId);
|
|
442
|
+
// Silent background reconcile
|
|
443
|
+
setTimeout(() => loadFiles('silent'), 800);
|
|
331
444
|
} catch (error) {
|
|
332
445
|
console.error('Delete error:', error);
|
|
333
446
|
console.error('Error details:', error.response?.data || error.message);
|
|
@@ -336,16 +449,14 @@ const FileManagementScreen = ({
|
|
|
336
449
|
if (error.message?.includes('File not found') || error.message?.includes('404')) {
|
|
337
450
|
_sonner.toast.error('File not found. It may have already been deleted.');
|
|
338
451
|
// Still reload files to refresh the list
|
|
339
|
-
setTimeout(
|
|
340
|
-
await loadFiles();
|
|
341
|
-
}, 500);
|
|
452
|
+
setTimeout(() => loadFiles('silent'), 800);
|
|
342
453
|
} else if (error.message?.includes('permission') || error.message?.includes('403')) {
|
|
343
454
|
_sonner.toast.error('You do not have permission to delete this file.');
|
|
344
455
|
} else {
|
|
345
456
|
_sonner.toast.error(error.message || 'Failed to delete file');
|
|
346
457
|
}
|
|
347
458
|
} finally {
|
|
348
|
-
|
|
459
|
+
storeSetDeleting(null);
|
|
349
460
|
}
|
|
350
461
|
};
|
|
351
462
|
|
|
@@ -356,24 +467,68 @@ const FileManagementScreen = ({
|
|
|
356
467
|
setIsDragging(true);
|
|
357
468
|
}
|
|
358
469
|
};
|
|
470
|
+
const handleDragEnter = e => {
|
|
471
|
+
if (_reactNative.Platform.OS === 'web' && user?.id === targetUserId) {
|
|
472
|
+
e.preventDefault();
|
|
473
|
+
setIsDragging(true);
|
|
474
|
+
}
|
|
475
|
+
};
|
|
359
476
|
const handleDragLeave = e => {
|
|
360
477
|
if (_reactNative.Platform.OS === 'web') {
|
|
361
478
|
e.preventDefault();
|
|
362
479
|
setIsDragging(false);
|
|
363
480
|
}
|
|
364
481
|
};
|
|
482
|
+
|
|
483
|
+
// Global drag listeners (web) to catch drags outside component bounds
|
|
484
|
+
(0, _react.useEffect)(() => {
|
|
485
|
+
if (_reactNative.Platform.OS !== 'web' || user?.id !== targetUserId) return;
|
|
486
|
+
const onDocDragEnter = e => {
|
|
487
|
+
if (e?.dataTransfer?.types?.includes('Files')) setIsDragging(true);
|
|
488
|
+
};
|
|
489
|
+
const onDocDragOver = e => {
|
|
490
|
+
if (e?.dataTransfer?.types?.includes('Files')) {
|
|
491
|
+
e.preventDefault();
|
|
492
|
+
setIsDragging(true);
|
|
493
|
+
}
|
|
494
|
+
};
|
|
495
|
+
const onDocDrop = e => {
|
|
496
|
+
if (e?.dataTransfer?.files?.length) {
|
|
497
|
+
e.preventDefault();
|
|
498
|
+
setIsDragging(false);
|
|
499
|
+
}
|
|
500
|
+
};
|
|
501
|
+
const onDocDragLeave = e => {
|
|
502
|
+
if (!e.relatedTarget && e.screenX === 0 && e.screenY === 0) setIsDragging(false);
|
|
503
|
+
};
|
|
504
|
+
document.addEventListener('dragenter', onDocDragEnter);
|
|
505
|
+
document.addEventListener('dragover', onDocDragOver);
|
|
506
|
+
document.addEventListener('drop', onDocDrop);
|
|
507
|
+
document.addEventListener('dragleave', onDocDragLeave);
|
|
508
|
+
return () => {
|
|
509
|
+
document.removeEventListener('dragenter', onDocDragEnter);
|
|
510
|
+
document.removeEventListener('dragover', onDocDragOver);
|
|
511
|
+
document.removeEventListener('drop', onDocDrop);
|
|
512
|
+
document.removeEventListener('dragleave', onDocDragLeave);
|
|
513
|
+
};
|
|
514
|
+
}, [user?.id, targetUserId]);
|
|
365
515
|
const handleDrop = async e => {
|
|
366
516
|
if (_reactNative.Platform.OS === 'web' && user?.id === targetUserId) {
|
|
367
517
|
e.preventDefault();
|
|
368
518
|
setIsDragging(false);
|
|
369
|
-
|
|
519
|
+
uploadStartRef.current = Date.now();
|
|
520
|
+
storeSetUploading(true);
|
|
370
521
|
try {
|
|
371
522
|
const files = Array.from(e.dataTransfer.files);
|
|
523
|
+
if (files.length > 0) storeSetUploadProgress({
|
|
524
|
+
current: 0,
|
|
525
|
+
total: files.length
|
|
526
|
+
});
|
|
372
527
|
await processFileUploads(files);
|
|
373
528
|
} catch (error) {
|
|
374
529
|
_sonner.toast.error(error.message || 'Failed to upload files');
|
|
375
530
|
} finally {
|
|
376
|
-
|
|
531
|
+
endUpload();
|
|
377
532
|
}
|
|
378
533
|
}
|
|
379
534
|
};
|
|
@@ -428,7 +583,7 @@ const FileManagementScreen = ({
|
|
|
428
583
|
const k = 1024;
|
|
429
584
|
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
430
585
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
431
|
-
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
586
|
+
return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
432
587
|
};
|
|
433
588
|
const getFileIcon = contentType => {
|
|
434
589
|
if (contentType.startsWith('image/')) return 'image';
|
|
@@ -488,7 +643,7 @@ const FileManagementScreen = ({
|
|
|
488
643
|
setShowFileDetails(true);
|
|
489
644
|
};
|
|
490
645
|
const renderSimplePhotoItem = (0, _react.useCallback)((photo, index) => {
|
|
491
|
-
const downloadUrl =
|
|
646
|
+
const downloadUrl = getSafeDownloadUrl(photo, 'thumb');
|
|
492
647
|
|
|
493
648
|
// Calculate photo item width based on actual container size from bottom sheet
|
|
494
649
|
let itemsPerRow = 3; // Default for mobile
|
|
@@ -510,41 +665,24 @@ const FileManagementScreen = ({
|
|
|
510
665
|
activeOpacity: 0.8,
|
|
511
666
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
512
667
|
style: styles.simplePhotoContainer,
|
|
513
|
-
children:
|
|
514
|
-
src: downloadUrl,
|
|
515
|
-
alt: photo.filename,
|
|
516
|
-
style: {
|
|
517
|
-
width: '100%',
|
|
518
|
-
height: '100%',
|
|
519
|
-
objectFit: 'cover',
|
|
520
|
-
borderRadius: 8,
|
|
521
|
-
transition: 'transform 0.2s ease'
|
|
522
|
-
},
|
|
523
|
-
loading: "lazy",
|
|
524
|
-
onError: e => {
|
|
525
|
-
console.error('Photo failed to load:', e);
|
|
526
|
-
},
|
|
527
|
-
onMouseEnter: e => {
|
|
528
|
-
e.currentTarget.style.transform = 'scale(1.05)';
|
|
529
|
-
},
|
|
530
|
-
onMouseLeave: e => {
|
|
531
|
-
e.currentTarget.style.transform = 'scale(1)';
|
|
532
|
-
}
|
|
533
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
|
|
668
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_expoImage.Image, {
|
|
534
669
|
source: {
|
|
535
670
|
uri: downloadUrl
|
|
536
671
|
},
|
|
537
672
|
style: styles.simplePhotoImage,
|
|
538
|
-
|
|
673
|
+
contentFit: "cover",
|
|
674
|
+
transition: 120,
|
|
675
|
+
cachePolicy: "memory-disk",
|
|
539
676
|
onError: e => {
|
|
540
|
-
console.error('Photo failed to load:', e);
|
|
541
|
-
}
|
|
677
|
+
console.error('Photo failed to load:', e?.nativeEvent ?? e);
|
|
678
|
+
},
|
|
679
|
+
accessibilityLabel: photo.filename
|
|
542
680
|
})
|
|
543
681
|
})
|
|
544
682
|
}, photo.id);
|
|
545
683
|
}, [oxyServices, containerWidth]);
|
|
546
684
|
const renderJustifiedPhotoItem = (0, _react.useCallback)((photo, width, height, isLast) => {
|
|
547
|
-
const downloadUrl =
|
|
685
|
+
const downloadUrl = getSafeDownloadUrl(photo, 'thumb');
|
|
548
686
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
549
687
|
style: [styles.justifiedPhotoItem, {
|
|
550
688
|
width,
|
|
@@ -554,46 +692,33 @@ const FileManagementScreen = ({
|
|
|
554
692
|
activeOpacity: 0.8,
|
|
555
693
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
556
694
|
style: styles.justifiedPhotoContainer,
|
|
557
|
-
children:
|
|
558
|
-
src: downloadUrl,
|
|
559
|
-
alt: photo.filename,
|
|
560
|
-
style: {
|
|
561
|
-
width: '100%',
|
|
562
|
-
height: '100%',
|
|
563
|
-
objectFit: 'cover',
|
|
564
|
-
borderRadius: 6,
|
|
565
|
-
transition: 'transform 0.2s ease, box-shadow 0.2s ease'
|
|
566
|
-
},
|
|
567
|
-
loading: "lazy",
|
|
568
|
-
onError: e => {
|
|
569
|
-
console.error('Photo failed to load:', e);
|
|
570
|
-
},
|
|
571
|
-
onMouseEnter: e => {
|
|
572
|
-
e.currentTarget.style.transform = 'scale(1.02)';
|
|
573
|
-
e.currentTarget.style.boxShadow = '0 8px 25px rgba(0,0,0,0.15)';
|
|
574
|
-
e.currentTarget.style.zIndex = '10';
|
|
575
|
-
},
|
|
576
|
-
onMouseLeave: e => {
|
|
577
|
-
e.currentTarget.style.transform = 'scale(1)';
|
|
578
|
-
e.currentTarget.style.boxShadow = '0 2px 8px rgba(0,0,0,0.1)';
|
|
579
|
-
e.currentTarget.style.zIndex = '1';
|
|
580
|
-
}
|
|
581
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
|
|
695
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_expoImage.Image, {
|
|
582
696
|
source: {
|
|
583
697
|
uri: downloadUrl
|
|
584
698
|
},
|
|
585
699
|
style: styles.justifiedPhotoImage,
|
|
586
|
-
|
|
700
|
+
contentFit: "cover",
|
|
701
|
+
transition: 120,
|
|
702
|
+
cachePolicy: "memory-disk",
|
|
587
703
|
onError: e => {
|
|
588
|
-
console.error('Photo failed to load:', e);
|
|
589
|
-
}
|
|
704
|
+
console.error('Photo failed to load:', e?.nativeEvent ?? e);
|
|
705
|
+
},
|
|
706
|
+
accessibilityLabel: photo.filename
|
|
590
707
|
})
|
|
591
708
|
})
|
|
592
709
|
}, photo.id);
|
|
593
710
|
}, [oxyServices]);
|
|
711
|
+
|
|
712
|
+
// Run initial load once per targetUserId change to avoid accidental loops
|
|
713
|
+
const lastLoadedFor = (0, _react.useRef)(undefined);
|
|
594
714
|
(0, _react.useEffect)(() => {
|
|
595
|
-
|
|
596
|
-
|
|
715
|
+
const key = targetUserId || 'anonymous';
|
|
716
|
+
if (lastLoadedFor.current !== key) {
|
|
717
|
+
lastLoadedFor.current = key;
|
|
718
|
+
loadFiles('initial');
|
|
719
|
+
}
|
|
720
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
721
|
+
}, [targetUserId]);
|
|
597
722
|
const renderFileItem = file => {
|
|
598
723
|
const isImage = file.contentType.startsWith('image/');
|
|
599
724
|
const isPDF = file.contentType.includes('pdf');
|
|
@@ -617,35 +742,19 @@ const FileManagementScreen = ({
|
|
|
617
742
|
onMouseEnter: () => setHoveredPreview(file.id),
|
|
618
743
|
onMouseLeave: () => setHoveredPreview(null)
|
|
619
744
|
}),
|
|
620
|
-
children: [isImage &&
|
|
621
|
-
src: oxyServices.getFileDownloadUrl(file.id),
|
|
622
|
-
style: {
|
|
623
|
-
width: '100%',
|
|
624
|
-
height: '100%',
|
|
625
|
-
objectFit: 'cover',
|
|
626
|
-
borderRadius: 8,
|
|
627
|
-
transition: 'transform 0.2s ease',
|
|
628
|
-
transform: hoveredPreview === file.id ? 'scale(1.05)' : 'scale(1)'
|
|
629
|
-
},
|
|
630
|
-
onError: e => {
|
|
631
|
-
// Show fallback icon if image fails to load
|
|
632
|
-
e.currentTarget.style.display = 'none';
|
|
633
|
-
const fallbackElement = e.currentTarget.parentElement?.querySelector('[data-fallback="true"]');
|
|
634
|
-
if (fallbackElement) {
|
|
635
|
-
fallbackElement.style.display = 'flex';
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
|
|
745
|
+
children: [isImage && /*#__PURE__*/(0, _jsxRuntime.jsx)(_expoImage.Image, {
|
|
639
746
|
source: {
|
|
640
|
-
uri:
|
|
747
|
+
uri: getSafeDownloadUrl(file, 'thumb')
|
|
641
748
|
},
|
|
642
749
|
style: styles.previewImage,
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
750
|
+
contentFit: "cover",
|
|
751
|
+
transition: 120,
|
|
752
|
+
cachePolicy: "memory-disk",
|
|
753
|
+
onError: _ => {
|
|
754
|
+
console.warn('Failed to load image preview.');
|
|
755
|
+
},
|
|
756
|
+
accessibilityLabel: file.filename
|
|
757
|
+
}), isPDF && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
649
758
|
style: styles.pdfPreview,
|
|
650
759
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
|
|
651
760
|
name: "document",
|
|
@@ -658,16 +767,26 @@ const FileManagementScreen = ({
|
|
|
658
767
|
children: "PDF"
|
|
659
768
|
})]
|
|
660
769
|
}), isVideo && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
661
|
-
style: styles.
|
|
662
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
770
|
+
style: styles.videoPreviewWrapper,
|
|
771
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_expoImage.Image, {
|
|
772
|
+
source: {
|
|
773
|
+
uri: getSafeDownloadUrl(file, 'thumb')
|
|
774
|
+
},
|
|
775
|
+
style: styles.videoPosterImage,
|
|
776
|
+
contentFit: "cover",
|
|
777
|
+
transition: 120,
|
|
778
|
+
cachePolicy: "memory-disk",
|
|
779
|
+
onError: _ => {
|
|
780
|
+
// If thumbnail not available, we still show icon overlay
|
|
781
|
+
},
|
|
782
|
+
accessibilityLabel: file.filename + ' video thumbnail'
|
|
783
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
784
|
+
style: styles.videoOverlay,
|
|
785
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
|
|
786
|
+
name: "play",
|
|
787
|
+
size: 24,
|
|
788
|
+
color: "#FFFFFF"
|
|
789
|
+
})
|
|
671
790
|
})]
|
|
672
791
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
673
792
|
style: [styles.fallbackIcon, {
|
|
@@ -760,8 +879,78 @@ const FileManagementScreen = ({
|
|
|
760
879
|
})]
|
|
761
880
|
}, file.id);
|
|
762
881
|
};
|
|
882
|
+
|
|
883
|
+
// GroupedSection-based file items (for 'all' view) replacing legacy flat list look
|
|
884
|
+
const groupedFileItems = (0, _react.useMemo)(() => {
|
|
885
|
+
return filteredFiles.filter(f => true) // placeholder for future filtering
|
|
886
|
+
.sort((a, b) => new Date(b.uploadDate).getTime() - new Date(a.uploadDate).getTime()).map(file => {
|
|
887
|
+
const isImage = file.contentType.startsWith('image/');
|
|
888
|
+
const isVideo = file.contentType.startsWith('video/');
|
|
889
|
+
const hasPreview = isImage || isVideo;
|
|
890
|
+
const previewUrl = hasPreview ? isVideo ? getSafeDownloadUrl(file, 'poster') : getSafeDownloadUrl(file, 'thumb') : undefined;
|
|
891
|
+
return {
|
|
892
|
+
id: file.id,
|
|
893
|
+
image: previewUrl,
|
|
894
|
+
imageSize: 44,
|
|
895
|
+
icon: !previewUrl ? getFileIcon(file.contentType) : undefined,
|
|
896
|
+
iconColor: themeStyles.primaryColor,
|
|
897
|
+
title: file.filename,
|
|
898
|
+
subtitle: `${formatFileSize(file.length)} • ${new Date(file.uploadDate).toLocaleDateString()}`,
|
|
899
|
+
theme: theme,
|
|
900
|
+
onPress: () => handleFileOpen(file),
|
|
901
|
+
showChevron: false,
|
|
902
|
+
dense: true,
|
|
903
|
+
multiRow: !!file.metadata?.description,
|
|
904
|
+
customContent: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
905
|
+
style: styles.groupedActions,
|
|
906
|
+
children: [(isImage || isVideo || file.contentType.includes('pdf')) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
907
|
+
style: [styles.groupedActionBtn, {
|
|
908
|
+
backgroundColor: themeStyles.isDarkTheme ? '#333333' : '#F0F0F0'
|
|
909
|
+
}],
|
|
910
|
+
onPress: () => handleFileOpen(file),
|
|
911
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
|
|
912
|
+
name: "eye",
|
|
913
|
+
size: 18,
|
|
914
|
+
color: themeStyles.primaryColor
|
|
915
|
+
})
|
|
916
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
917
|
+
style: [styles.groupedActionBtn, {
|
|
918
|
+
backgroundColor: themeStyles.isDarkTheme ? '#333333' : '#F0F0F0'
|
|
919
|
+
}],
|
|
920
|
+
onPress: () => handleFileDownload(file.id, file.filename),
|
|
921
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
|
|
922
|
+
name: "download",
|
|
923
|
+
size: 18,
|
|
924
|
+
color: themeStyles.primaryColor
|
|
925
|
+
})
|
|
926
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
927
|
+
style: [styles.groupedActionBtn, {
|
|
928
|
+
backgroundColor: themeStyles.isDarkTheme ? '#400000' : '#FFEBEE'
|
|
929
|
+
}],
|
|
930
|
+
onPress: () => handleFileDelete(file.id, file.filename),
|
|
931
|
+
disabled: deleting === file.id,
|
|
932
|
+
children: deleting === file.id ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
|
|
933
|
+
size: "small",
|
|
934
|
+
color: themeStyles.dangerColor
|
|
935
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
|
|
936
|
+
name: "trash",
|
|
937
|
+
size: 18,
|
|
938
|
+
color: themeStyles.dangerColor
|
|
939
|
+
})
|
|
940
|
+
})]
|
|
941
|
+
}),
|
|
942
|
+
customContentBelow: file.metadata?.description ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
943
|
+
style: [styles.groupedDescription, {
|
|
944
|
+
color: themeStyles.isDarkTheme ? '#AAAAAA' : '#666666'
|
|
945
|
+
}],
|
|
946
|
+
numberOfLines: 2,
|
|
947
|
+
children: file.metadata.description
|
|
948
|
+
}) : undefined
|
|
949
|
+
}; // GroupedSectionItem shape
|
|
950
|
+
});
|
|
951
|
+
}, [filteredFiles, theme, themeStyles, deleting, handleFileDownload, handleFileDelete, handleFileOpen, getSafeDownloadUrl]);
|
|
763
952
|
const renderPhotoItem = (photo, index) => {
|
|
764
|
-
const downloadUrl =
|
|
953
|
+
const downloadUrl = getSafeDownloadUrl(photo, 'thumb');
|
|
765
954
|
|
|
766
955
|
// Calculate photo item width based on actual container size from bottom sheet
|
|
767
956
|
let itemsPerRow = 3; // Default for mobile
|
|
@@ -782,36 +971,18 @@ const FileManagementScreen = ({
|
|
|
782
971
|
activeOpacity: 0.8,
|
|
783
972
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
784
973
|
style: styles.photoContainer,
|
|
785
|
-
children:
|
|
786
|
-
src: downloadUrl,
|
|
787
|
-
alt: photo.filename,
|
|
788
|
-
style: {
|
|
789
|
-
width: '100%',
|
|
790
|
-
height: '100%',
|
|
791
|
-
objectFit: 'cover',
|
|
792
|
-
borderRadius: 8,
|
|
793
|
-
transition: 'transform 0.2s ease'
|
|
794
|
-
},
|
|
795
|
-
loading: "lazy",
|
|
796
|
-
onError: e => {
|
|
797
|
-
console.error('Photo failed to load:', e);
|
|
798
|
-
// Could replace with placeholder image
|
|
799
|
-
},
|
|
800
|
-
onMouseEnter: e => {
|
|
801
|
-
e.currentTarget.style.transform = 'scale(1.02)';
|
|
802
|
-
},
|
|
803
|
-
onMouseLeave: e => {
|
|
804
|
-
e.currentTarget.style.transform = 'scale(1)';
|
|
805
|
-
}
|
|
806
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
|
|
974
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_expoImage.Image, {
|
|
807
975
|
source: {
|
|
808
976
|
uri: downloadUrl
|
|
809
977
|
},
|
|
810
978
|
style: styles.photoImage,
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
979
|
+
contentFit: "cover",
|
|
980
|
+
transition: 120,
|
|
981
|
+
cachePolicy: "memory-disk",
|
|
982
|
+
onError: _ => {
|
|
983
|
+
console.warn('Failed to load image preview for photo:', photo.id);
|
|
984
|
+
},
|
|
985
|
+
accessibilityLabel: photo.filename
|
|
815
986
|
})
|
|
816
987
|
})
|
|
817
988
|
}, photo.id);
|
|
@@ -830,11 +1001,11 @@ const FileManagementScreen = ({
|
|
|
830
1001
|
color: themeStyles.textColor
|
|
831
1002
|
}],
|
|
832
1003
|
children: "No Photos Yet"
|
|
833
|
-
}), /*#__PURE__*/(0, _jsxRuntime.
|
|
1004
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
834
1005
|
style: [styles.emptyStateDescription, {
|
|
835
1006
|
color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'
|
|
836
1007
|
}],
|
|
837
|
-
children: user?.id === targetUserId ? `Upload photos to get started. You can select multiple photos at once${_reactNative.Platform.OS === 'web' ? ' or drag & drop them here.' : '.'}` : "This user hasn't uploaded any photos yet"
|
|
1008
|
+
children: [" ", user?.id === targetUserId ? `Upload photos to get started. You can select multiple photos at once${_reactNative.Platform.OS === 'web' ? ' or drag & drop them here.' : '.'}` : "This user hasn't uploaded any photos yet", " "]
|
|
838
1009
|
}), user?.id === targetUserId && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
839
1010
|
style: [styles.emptyStateButton, {
|
|
840
1011
|
backgroundColor: themeStyles.primaryColor
|
|
@@ -862,7 +1033,7 @@ const FileManagementScreen = ({
|
|
|
862
1033
|
contentContainerStyle: styles.photoScrollContainer,
|
|
863
1034
|
refreshControl: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.RefreshControl, {
|
|
864
1035
|
refreshing: refreshing,
|
|
865
|
-
onRefresh: () => loadFiles(
|
|
1036
|
+
onRefresh: () => loadFiles('refresh'),
|
|
866
1037
|
tintColor: themeStyles.primaryColor
|
|
867
1038
|
}),
|
|
868
1039
|
showsVerticalScrollIndicator: false,
|
|
@@ -904,7 +1075,9 @@ const FileManagementScreen = ({
|
|
|
904
1075
|
// Load dimensions for new photos
|
|
905
1076
|
_react.default.useEffect(() => {
|
|
906
1077
|
loadPhotoDimensions(photos);
|
|
907
|
-
|
|
1078
|
+
// Depend only on photo IDs to avoid re-running from dimension state changes
|
|
1079
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1080
|
+
}, [photos.map(p => p.id).join(',')]);
|
|
908
1081
|
|
|
909
1082
|
// Group photos by date
|
|
910
1083
|
const photosByDate = _react.default.useMemo(() => {
|
|
@@ -1343,31 +1516,22 @@ const FileManagementScreen = ({
|
|
|
1343
1516
|
})]
|
|
1344
1517
|
}) : isImage && fileContent ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1345
1518
|
style: styles.imageContainer,
|
|
1346
|
-
children:
|
|
1347
|
-
src: fileContent,
|
|
1348
|
-
alt: openedFile.filename,
|
|
1349
|
-
style: {
|
|
1350
|
-
maxWidth: '100%',
|
|
1351
|
-
maxHeight: '80vh',
|
|
1352
|
-
objectFit: 'contain',
|
|
1353
|
-
borderRadius: 8
|
|
1354
|
-
},
|
|
1355
|
-
onError: e => {
|
|
1356
|
-
console.error('Image failed to load:', e);
|
|
1357
|
-
}
|
|
1358
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Image, {
|
|
1519
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_expoImage.Image, {
|
|
1359
1520
|
source: {
|
|
1360
1521
|
uri: fileContent
|
|
1361
1522
|
},
|
|
1362
1523
|
style: {
|
|
1363
1524
|
width: '100%',
|
|
1364
1525
|
height: 400,
|
|
1365
|
-
resizeMode: 'contain',
|
|
1366
1526
|
borderRadius: 8
|
|
1367
1527
|
},
|
|
1528
|
+
contentFit: "contain",
|
|
1529
|
+
transition: 120,
|
|
1530
|
+
cachePolicy: "memory-disk",
|
|
1368
1531
|
onError: e => {
|
|
1369
|
-
console.error('Image failed to load:', e);
|
|
1370
|
-
}
|
|
1532
|
+
console.error('Image failed to load:', e?.nativeEvent ?? e);
|
|
1533
|
+
},
|
|
1534
|
+
accessibilityLabel: openedFile.filename
|
|
1371
1535
|
})
|
|
1372
1536
|
}) : isText && fileContent ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1373
1537
|
style: [styles.textContainer, {
|
|
@@ -1530,157 +1694,76 @@ const FileManagementScreen = ({
|
|
|
1530
1694
|
});
|
|
1531
1695
|
}
|
|
1532
1696
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1533
|
-
style: [styles.container,
|
|
1534
|
-
backgroundColor
|
|
1535
|
-
}, isDragging && _reactNative.Platform.OS === 'web' && styles.dragOverlay],
|
|
1697
|
+
style: [styles.container, isDragging && _reactNative.Platform.OS === 'web' && styles.dragOverlay],
|
|
1536
1698
|
...(_reactNative.Platform.OS === 'web' && user?.id === targetUserId ? {
|
|
1537
1699
|
onDragOver: handleDragOver,
|
|
1700
|
+
onDragEnter: handleDragEnter,
|
|
1538
1701
|
onDragLeave: handleDragLeave,
|
|
1539
1702
|
onDrop: handleDrop
|
|
1540
1703
|
} : {}),
|
|
1541
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
default: {}
|
|
1558
|
-
})
|
|
1559
|
-
}],
|
|
1560
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
1561
|
-
style: [styles.backButton, {
|
|
1562
|
-
backgroundColor: themeStyles.isDarkTheme ? '#2A2A2A' : '#F8F9FA',
|
|
1563
|
-
borderRadius: 12
|
|
1704
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Header.default, {
|
|
1705
|
+
title: viewMode === 'photos' ? 'Photos' : 'File Management',
|
|
1706
|
+
subtitle: `${filteredFiles.length} ${filteredFiles.length === 1 ? 'item' : 'items'}`,
|
|
1707
|
+
onBack: onClose || goBack,
|
|
1708
|
+
theme: theme,
|
|
1709
|
+
showBackButton: true,
|
|
1710
|
+
variant: "minimal",
|
|
1711
|
+
elevation: "none",
|
|
1712
|
+
titleAlignment: "left"
|
|
1713
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1714
|
+
style: styles.controlsBar,
|
|
1715
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1716
|
+
style: [styles.viewModeToggle, {
|
|
1717
|
+
backgroundColor: themeStyles.isDarkTheme ? '#181818' : '#FFFFFF',
|
|
1718
|
+
borderWidth: 1,
|
|
1719
|
+
borderColor: themeStyles.isDarkTheme ? '#2A2A2A' : '#E8E9EA'
|
|
1564
1720
|
}],
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
size: 22,
|
|
1569
|
-
color: themeStyles.textColor
|
|
1570
|
-
})
|
|
1571
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1572
|
-
style: styles.headerTitleContainer,
|
|
1573
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1574
|
-
style: [styles.headerTitle, {
|
|
1575
|
-
color: themeStyles.textColor
|
|
1576
|
-
}],
|
|
1577
|
-
children: viewMode === 'photos' ? 'Photos' : 'File Management'
|
|
1578
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
1579
|
-
style: [styles.headerSubtitle, {
|
|
1580
|
-
color: themeStyles.isDarkTheme ? '#AAAAAA' : '#666666'
|
|
1581
|
-
}],
|
|
1582
|
-
children: [filteredFiles.length, " ", filteredFiles.length === 1 ? 'item' : 'items']
|
|
1583
|
-
})]
|
|
1584
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1585
|
-
style: styles.headerActions,
|
|
1586
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1587
|
-
style: [styles.viewModeToggle, {
|
|
1588
|
-
backgroundColor: themeStyles.isDarkTheme ? '#2A2A2A' : '#F8F9FA',
|
|
1589
|
-
borderWidth: 1,
|
|
1590
|
-
borderColor: themeStyles.isDarkTheme ? '#3A3A3A' : '#E8E9EA',
|
|
1591
|
-
shadowColor: '#000000',
|
|
1592
|
-
shadowOffset: {
|
|
1593
|
-
width: 0,
|
|
1594
|
-
height: 1
|
|
1595
|
-
},
|
|
1596
|
-
shadowOpacity: themeStyles.isDarkTheme ? 0.3 : 0.05,
|
|
1597
|
-
shadowRadius: 4,
|
|
1598
|
-
elevation: 2
|
|
1721
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
1722
|
+
style: [styles.viewModeButton, viewMode === 'all' && {
|
|
1723
|
+
backgroundColor: themeStyles.primaryColor
|
|
1599
1724
|
}],
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
shadowRadius: 4,
|
|
1610
|
-
elevation: 3
|
|
1611
|
-
}],
|
|
1612
|
-
onPress: () => setViewMode('all'),
|
|
1613
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
|
|
1614
|
-
name: "folder",
|
|
1615
|
-
size: 18,
|
|
1616
|
-
color: viewMode === 'all' ? '#FFFFFF' : themeStyles.textColor
|
|
1617
|
-
})
|
|
1618
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
1619
|
-
style: [styles.viewModeButton, viewMode === 'photos' && {
|
|
1620
|
-
backgroundColor: themeStyles.primaryColor,
|
|
1621
|
-
shadowColor: themeStyles.primaryColor,
|
|
1622
|
-
shadowOffset: {
|
|
1623
|
-
width: 0,
|
|
1624
|
-
height: 2
|
|
1625
|
-
},
|
|
1626
|
-
shadowOpacity: 0.3,
|
|
1627
|
-
shadowRadius: 4,
|
|
1628
|
-
elevation: 3
|
|
1629
|
-
}],
|
|
1630
|
-
onPress: () => setViewMode('photos'),
|
|
1631
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
|
|
1632
|
-
name: "images",
|
|
1633
|
-
size: 18,
|
|
1634
|
-
color: viewMode === 'photos' ? '#FFFFFF' : themeStyles.textColor
|
|
1635
|
-
})
|
|
1636
|
-
})]
|
|
1637
|
-
}), user?.id === targetUserId && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
1638
|
-
style: [styles.uploadButton, {
|
|
1639
|
-
backgroundColor: themeStyles.primaryColor,
|
|
1640
|
-
shadowColor: themeStyles.primaryColor,
|
|
1641
|
-
shadowOffset: {
|
|
1642
|
-
width: 0,
|
|
1643
|
-
height: 3
|
|
1644
|
-
},
|
|
1645
|
-
shadowOpacity: 0.4,
|
|
1646
|
-
shadowRadius: 6,
|
|
1647
|
-
elevation: 5,
|
|
1648
|
-
transform: uploading ? [{
|
|
1649
|
-
scale: 0.95
|
|
1650
|
-
}] : [{
|
|
1651
|
-
scale: 1
|
|
1652
|
-
}]
|
|
1725
|
+
onPress: () => setViewMode('all'),
|
|
1726
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
|
|
1727
|
+
name: "folder",
|
|
1728
|
+
size: 18,
|
|
1729
|
+
color: viewMode === 'all' ? '#FFFFFF' : themeStyles.textColor
|
|
1730
|
+
})
|
|
1731
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
1732
|
+
style: [styles.viewModeButton, viewMode === 'photos' && {
|
|
1733
|
+
backgroundColor: themeStyles.primaryColor
|
|
1653
1734
|
}],
|
|
1654
|
-
onPress:
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
size: "small",
|
|
1660
|
-
color: "#FFFFFF"
|
|
1661
|
-
}), uploadProgress && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
1662
|
-
style: styles.uploadProgressText,
|
|
1663
|
-
children: [uploadProgress.current, "/", uploadProgress.total]
|
|
1664
|
-
})]
|
|
1665
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
|
|
1666
|
-
name: "add",
|
|
1667
|
-
size: 26,
|
|
1668
|
-
color: "#FFFFFF"
|
|
1735
|
+
onPress: () => setViewMode('photos'),
|
|
1736
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
|
|
1737
|
+
name: "images",
|
|
1738
|
+
size: 18,
|
|
1739
|
+
color: viewMode === 'photos' ? '#FFFFFF' : themeStyles.textColor
|
|
1669
1740
|
})
|
|
1670
1741
|
})]
|
|
1742
|
+
}), user?.id === targetUserId && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
1743
|
+
style: [styles.uploadButton, {
|
|
1744
|
+
backgroundColor: themeStyles.primaryColor
|
|
1745
|
+
}],
|
|
1746
|
+
onPress: handleFileUpload,
|
|
1747
|
+
disabled: uploading,
|
|
1748
|
+
children: uploading ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1749
|
+
style: styles.uploadProgress,
|
|
1750
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
|
|
1751
|
+
size: "small",
|
|
1752
|
+
color: "#FFFFFF"
|
|
1753
|
+
}), uploadProgress && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
1754
|
+
style: styles.uploadProgressText,
|
|
1755
|
+
children: [uploadProgress.current, "/", uploadProgress.total]
|
|
1756
|
+
})]
|
|
1757
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
|
|
1758
|
+
name: "add",
|
|
1759
|
+
size: 22,
|
|
1760
|
+
color: "#FFFFFF"
|
|
1761
|
+
})
|
|
1671
1762
|
})]
|
|
1672
1763
|
}), files.length > 0 && (viewMode === 'all' || files.some(f => f.contentType.startsWith('image/'))) && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1673
1764
|
style: [styles.searchContainer, {
|
|
1674
1765
|
backgroundColor: themeStyles.isDarkTheme ? '#1A1A1A' : '#FFFFFF',
|
|
1675
|
-
borderColor: themeStyles.isDarkTheme ? '#3A3A3A' : '#E8E9EA'
|
|
1676
|
-
shadowColor: '#000000',
|
|
1677
|
-
shadowOffset: {
|
|
1678
|
-
width: 0,
|
|
1679
|
-
height: 1
|
|
1680
|
-
},
|
|
1681
|
-
shadowOpacity: themeStyles.isDarkTheme ? 0.2 : 0.05,
|
|
1682
|
-
shadowRadius: 4,
|
|
1683
|
-
elevation: 2
|
|
1766
|
+
borderColor: themeStyles.isDarkTheme ? '#3A3A3A' : '#E8E9EA'
|
|
1684
1767
|
}],
|
|
1685
1768
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
|
|
1686
1769
|
name: "search",
|
|
@@ -1706,15 +1789,7 @@ const FileManagementScreen = ({
|
|
|
1706
1789
|
}), files.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1707
1790
|
style: [styles.statsContainer, {
|
|
1708
1791
|
backgroundColor: themeStyles.isDarkTheme ? '#1A1A1A' : '#FFFFFF',
|
|
1709
|
-
borderColor: themeStyles.isDarkTheme ? '#3A3A3A' : '#E8E9EA'
|
|
1710
|
-
shadowColor: '#000000',
|
|
1711
|
-
shadowOffset: {
|
|
1712
|
-
width: 0,
|
|
1713
|
-
height: 1
|
|
1714
|
-
},
|
|
1715
|
-
shadowOpacity: themeStyles.isDarkTheme ? 0.2 : 0.05,
|
|
1716
|
-
shadowRadius: 4,
|
|
1717
|
-
elevation: 2
|
|
1792
|
+
borderColor: themeStyles.isDarkTheme ? '#3A3A3A' : '#E8E9EA'
|
|
1718
1793
|
}],
|
|
1719
1794
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1720
1795
|
style: styles.statItem,
|
|
@@ -1761,7 +1836,7 @@ const FileManagementScreen = ({
|
|
|
1761
1836
|
contentContainerStyle: styles.scrollContainer,
|
|
1762
1837
|
refreshControl: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.RefreshControl, {
|
|
1763
1838
|
refreshing: refreshing,
|
|
1764
|
-
onRefresh: () => loadFiles(
|
|
1839
|
+
onRefresh: () => loadFiles('refresh'),
|
|
1765
1840
|
tintColor: themeStyles.primaryColor
|
|
1766
1841
|
}),
|
|
1767
1842
|
children: filteredFiles.length === 0 && searchQuery.length > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
@@ -1794,10 +1869,37 @@ const FileManagementScreen = ({
|
|
|
1794
1869
|
children: "Clear Search"
|
|
1795
1870
|
})]
|
|
1796
1871
|
})]
|
|
1797
|
-
}) : filteredFiles.length === 0 ? renderEmptyState() : /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
1798
|
-
|
|
1872
|
+
}) : filteredFiles.length === 0 ? renderEmptyState() : /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.GroupedSection, {
|
|
1873
|
+
items: groupedFileItems,
|
|
1874
|
+
theme: theme
|
|
1875
|
+
})
|
|
1876
|
+
}), renderFileDetailsModal(), uploading && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1877
|
+
pointerEvents: "none",
|
|
1878
|
+
style: styles.uploadBannerContainer,
|
|
1879
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1880
|
+
style: [styles.uploadBanner, {
|
|
1881
|
+
backgroundColor: themeStyles.isDarkTheme ? '#222831EE' : '#FFFFFFEE',
|
|
1882
|
+
borderColor: themeStyles.borderColor
|
|
1883
|
+
}],
|
|
1884
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
|
|
1885
|
+
name: "cloud-upload",
|
|
1886
|
+
size: 18,
|
|
1887
|
+
color: themeStyles.primaryColor
|
|
1888
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
1889
|
+
style: [styles.uploadBannerText, {
|
|
1890
|
+
color: themeStyles.textColor
|
|
1891
|
+
}],
|
|
1892
|
+
children: ["Uploading", uploadProgress ? ` ${uploadProgress.current}/${uploadProgress.total}` : '...']
|
|
1893
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1894
|
+
style: styles.uploadBannerDots,
|
|
1895
|
+
children: [0, 1, 2].map(i => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1896
|
+
style: [styles.dot, {
|
|
1897
|
+
opacity: (Date.now() / 400 + i) % 3 < 1 ? 1 : 0.25
|
|
1898
|
+
}]
|
|
1899
|
+
}, i))
|
|
1900
|
+
})]
|
|
1799
1901
|
})
|
|
1800
|
-
}),
|
|
1902
|
+
}), isDragging && _reactNative.Platform.OS === 'web' && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1801
1903
|
style: styles.dragDropOverlay,
|
|
1802
1904
|
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1803
1905
|
style: styles.dragDropContent,
|
|
@@ -1825,9 +1927,9 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
1825
1927
|
flex: 1
|
|
1826
1928
|
},
|
|
1827
1929
|
dragOverlay: {
|
|
1828
|
-
backgroundColor: 'rgba(0, 122, 255, 0.
|
|
1829
|
-
borderWidth:
|
|
1830
|
-
borderColor: '#
|
|
1930
|
+
backgroundColor: 'rgba(0, 122, 255, 0.06)',
|
|
1931
|
+
borderWidth: 1,
|
|
1932
|
+
borderColor: '#66AFFF',
|
|
1831
1933
|
borderStyle: 'dashed'
|
|
1832
1934
|
},
|
|
1833
1935
|
centerContent: {
|
|
@@ -1838,8 +1940,8 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
1838
1940
|
flexDirection: 'row',
|
|
1839
1941
|
alignItems: 'center',
|
|
1840
1942
|
justifyContent: 'space-between',
|
|
1841
|
-
paddingHorizontal:
|
|
1842
|
-
paddingVertical:
|
|
1943
|
+
paddingHorizontal: 16,
|
|
1944
|
+
paddingVertical: 12,
|
|
1843
1945
|
borderBottomWidth: 1,
|
|
1844
1946
|
position: 'relative'
|
|
1845
1947
|
},
|
|
@@ -1888,16 +1990,57 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
1888
1990
|
fontWeight: '600',
|
|
1889
1991
|
marginTop: 2
|
|
1890
1992
|
},
|
|
1993
|
+
uploadBannerContainer: {
|
|
1994
|
+
position: 'absolute',
|
|
1995
|
+
top: 72,
|
|
1996
|
+
// below header
|
|
1997
|
+
left: 0,
|
|
1998
|
+
right: 0,
|
|
1999
|
+
alignItems: 'center',
|
|
2000
|
+
zIndex: 50
|
|
2001
|
+
},
|
|
2002
|
+
uploadBanner: {
|
|
2003
|
+
flexDirection: 'row',
|
|
2004
|
+
alignItems: 'center',
|
|
2005
|
+
paddingHorizontal: 14,
|
|
2006
|
+
paddingVertical: 8,
|
|
2007
|
+
borderRadius: 24,
|
|
2008
|
+
gap: 8,
|
|
2009
|
+
borderWidth: 1,
|
|
2010
|
+
shadowColor: '#000',
|
|
2011
|
+
shadowOpacity: 0.1,
|
|
2012
|
+
shadowRadius: 6,
|
|
2013
|
+
shadowOffset: {
|
|
2014
|
+
width: 0,
|
|
2015
|
+
height: 2
|
|
2016
|
+
},
|
|
2017
|
+
elevation: 2
|
|
2018
|
+
},
|
|
2019
|
+
uploadBannerText: {
|
|
2020
|
+
fontSize: 13,
|
|
2021
|
+
fontWeight: '500'
|
|
2022
|
+
},
|
|
2023
|
+
uploadBannerDots: {
|
|
2024
|
+
flexDirection: 'row',
|
|
2025
|
+
gap: 4,
|
|
2026
|
+
marginLeft: 2
|
|
2027
|
+
},
|
|
2028
|
+
dot: {
|
|
2029
|
+
width: 6,
|
|
2030
|
+
height: 6,
|
|
2031
|
+
borderRadius: 3,
|
|
2032
|
+
backgroundColor: '#007AFF'
|
|
2033
|
+
},
|
|
1891
2034
|
searchContainer: {
|
|
1892
2035
|
flexDirection: 'row',
|
|
1893
2036
|
alignItems: 'center',
|
|
1894
|
-
paddingHorizontal:
|
|
1895
|
-
paddingVertical:
|
|
1896
|
-
marginHorizontal:
|
|
1897
|
-
marginTop:
|
|
1898
|
-
borderRadius:
|
|
2037
|
+
paddingHorizontal: 14,
|
|
2038
|
+
paddingVertical: 10,
|
|
2039
|
+
marginHorizontal: 16,
|
|
2040
|
+
marginTop: 12,
|
|
2041
|
+
borderRadius: 10,
|
|
1899
2042
|
borderWidth: 1,
|
|
1900
|
-
gap:
|
|
2043
|
+
gap: 10
|
|
1901
2044
|
},
|
|
1902
2045
|
searchInput: {
|
|
1903
2046
|
flex: 1,
|
|
@@ -1916,11 +2059,11 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
1916
2059
|
},
|
|
1917
2060
|
statsContainer: {
|
|
1918
2061
|
flexDirection: 'row',
|
|
1919
|
-
paddingHorizontal:
|
|
1920
|
-
paddingVertical:
|
|
1921
|
-
marginHorizontal:
|
|
1922
|
-
marginTop:
|
|
1923
|
-
borderRadius:
|
|
2062
|
+
paddingHorizontal: 14,
|
|
2063
|
+
paddingVertical: 10,
|
|
2064
|
+
marginHorizontal: 16,
|
|
2065
|
+
marginTop: 12,
|
|
2066
|
+
borderRadius: 10,
|
|
1924
2067
|
borderWidth: 1
|
|
1925
2068
|
},
|
|
1926
2069
|
statItem: {
|
|
@@ -1929,31 +2072,31 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
1929
2072
|
paddingVertical: 4
|
|
1930
2073
|
},
|
|
1931
2074
|
statValue: {
|
|
1932
|
-
fontSize:
|
|
2075
|
+
fontSize: 20,
|
|
1933
2076
|
fontWeight: '800',
|
|
1934
2077
|
fontFamily: _fonts.fontFamilies.phuduBold,
|
|
1935
2078
|
letterSpacing: -0.5,
|
|
1936
|
-
lineHeight:
|
|
2079
|
+
lineHeight: 24
|
|
1937
2080
|
},
|
|
1938
2081
|
statLabel: {
|
|
1939
|
-
fontSize:
|
|
2082
|
+
fontSize: 12,
|
|
1940
2083
|
fontWeight: '500',
|
|
1941
2084
|
fontFamily: _fonts.fontFamilies.phuduMedium,
|
|
1942
|
-
marginTop:
|
|
1943
|
-
letterSpacing: 0.
|
|
2085
|
+
marginTop: 2,
|
|
2086
|
+
letterSpacing: 0.2
|
|
1944
2087
|
},
|
|
1945
2088
|
scrollView: {
|
|
1946
2089
|
flex: 1
|
|
1947
2090
|
},
|
|
1948
2091
|
scrollContainer: {
|
|
1949
|
-
padding:
|
|
2092
|
+
padding: 12
|
|
1950
2093
|
},
|
|
1951
2094
|
fileItem: {
|
|
1952
2095
|
flexDirection: 'row',
|
|
1953
2096
|
alignItems: 'center',
|
|
1954
|
-
padding:
|
|
1955
|
-
marginBottom:
|
|
1956
|
-
borderRadius:
|
|
2097
|
+
padding: 10,
|
|
2098
|
+
marginBottom: 8,
|
|
2099
|
+
borderRadius: 10,
|
|
1957
2100
|
borderWidth: 1
|
|
1958
2101
|
},
|
|
1959
2102
|
fileContent: {
|
|
@@ -1969,15 +2112,15 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
1969
2112
|
marginRight: 12
|
|
1970
2113
|
},
|
|
1971
2114
|
filePreviewContainer: {
|
|
1972
|
-
width:
|
|
1973
|
-
height:
|
|
1974
|
-
marginRight:
|
|
2115
|
+
width: 52,
|
|
2116
|
+
height: 52,
|
|
2117
|
+
marginRight: 10
|
|
1975
2118
|
},
|
|
1976
2119
|
filePreview: {
|
|
1977
2120
|
width: '100%',
|
|
1978
2121
|
height: '100%',
|
|
1979
2122
|
borderRadius: 8,
|
|
1980
|
-
backgroundColor: '
|
|
2123
|
+
backgroundColor: 'transparent',
|
|
1981
2124
|
alignItems: 'center',
|
|
1982
2125
|
justifyContent: 'center',
|
|
1983
2126
|
overflow: 'hidden',
|
|
@@ -2020,7 +2163,7 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
2020
2163
|
bottom: 0,
|
|
2021
2164
|
alignItems: 'center',
|
|
2022
2165
|
justifyContent: 'center',
|
|
2023
|
-
backgroundColor: '
|
|
2166
|
+
backgroundColor: 'transparent',
|
|
2024
2167
|
borderRadius: 8
|
|
2025
2168
|
},
|
|
2026
2169
|
previewOverlay: {
|
|
@@ -2029,11 +2172,57 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
2029
2172
|
left: 0,
|
|
2030
2173
|
right: 0,
|
|
2031
2174
|
bottom: 0,
|
|
2032
|
-
backgroundColor: 'rgba(0, 0, 0, 0.
|
|
2175
|
+
backgroundColor: 'rgba(0, 0, 0, 0.25)',
|
|
2033
2176
|
alignItems: 'center',
|
|
2034
2177
|
justifyContent: 'center',
|
|
2035
2178
|
borderRadius: 8
|
|
2036
2179
|
},
|
|
2180
|
+
groupedActions: {
|
|
2181
|
+
flexDirection: 'row',
|
|
2182
|
+
alignItems: 'center',
|
|
2183
|
+
gap: 6,
|
|
2184
|
+
marginLeft: 12
|
|
2185
|
+
},
|
|
2186
|
+
groupedActionBtn: {
|
|
2187
|
+
width: 34,
|
|
2188
|
+
height: 34,
|
|
2189
|
+
borderRadius: 8,
|
|
2190
|
+
alignItems: 'center',
|
|
2191
|
+
justifyContent: 'center'
|
|
2192
|
+
},
|
|
2193
|
+
groupedDescription: {
|
|
2194
|
+
fontSize: 12,
|
|
2195
|
+
lineHeight: 16,
|
|
2196
|
+
marginTop: 6
|
|
2197
|
+
},
|
|
2198
|
+
videoPreviewWrapper: {
|
|
2199
|
+
width: '100%',
|
|
2200
|
+
height: '100%',
|
|
2201
|
+
borderRadius: 8,
|
|
2202
|
+
overflow: 'hidden',
|
|
2203
|
+
backgroundColor: '#000000',
|
|
2204
|
+
alignItems: 'center',
|
|
2205
|
+
justifyContent: 'center'
|
|
2206
|
+
},
|
|
2207
|
+
videoPosterImage: {
|
|
2208
|
+
position: 'absolute',
|
|
2209
|
+
top: 0,
|
|
2210
|
+
left: 0,
|
|
2211
|
+
right: 0,
|
|
2212
|
+
bottom: 0,
|
|
2213
|
+
width: '100%',
|
|
2214
|
+
height: '100%'
|
|
2215
|
+
},
|
|
2216
|
+
videoOverlay: {
|
|
2217
|
+
position: 'absolute',
|
|
2218
|
+
top: 0,
|
|
2219
|
+
left: 0,
|
|
2220
|
+
right: 0,
|
|
2221
|
+
bottom: 0,
|
|
2222
|
+
alignItems: 'center',
|
|
2223
|
+
justifyContent: 'center',
|
|
2224
|
+
backgroundColor: 'rgba(0,0,0,0.25)'
|
|
2225
|
+
},
|
|
2037
2226
|
fileInfo: {
|
|
2038
2227
|
flex: 1
|
|
2039
2228
|
},
|
|
@@ -2055,16 +2244,19 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
2055
2244
|
gap: 8
|
|
2056
2245
|
},
|
|
2057
2246
|
actionButton: {
|
|
2058
|
-
width:
|
|
2059
|
-
height:
|
|
2060
|
-
borderRadius:
|
|
2247
|
+
width: 36,
|
|
2248
|
+
height: 36,
|
|
2249
|
+
borderRadius: 18,
|
|
2061
2250
|
alignItems: 'center',
|
|
2062
|
-
justifyContent: 'center'
|
|
2251
|
+
justifyContent: 'center',
|
|
2252
|
+
borderWidth: 1,
|
|
2253
|
+
borderColor: '#E0E0E0',
|
|
2254
|
+
backgroundColor: 'transparent'
|
|
2063
2255
|
},
|
|
2064
2256
|
emptyState: {
|
|
2065
2257
|
alignItems: 'center',
|
|
2066
|
-
paddingVertical:
|
|
2067
|
-
paddingHorizontal:
|
|
2258
|
+
paddingVertical: 40,
|
|
2259
|
+
paddingHorizontal: 24
|
|
2068
2260
|
},
|
|
2069
2261
|
emptyStateTitle: {
|
|
2070
2262
|
fontSize: 24,
|
|
@@ -2104,8 +2296,8 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
2104
2296
|
flexDirection: 'row',
|
|
2105
2297
|
alignItems: 'center',
|
|
2106
2298
|
justifyContent: 'space-between',
|
|
2107
|
-
paddingHorizontal:
|
|
2108
|
-
paddingVertical:
|
|
2299
|
+
paddingHorizontal: 16,
|
|
2300
|
+
paddingVertical: 12,
|
|
2109
2301
|
borderBottomWidth: 1
|
|
2110
2302
|
},
|
|
2111
2303
|
modalCloseButton: {
|
|
@@ -2121,11 +2313,11 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
2121
2313
|
},
|
|
2122
2314
|
modalContent: {
|
|
2123
2315
|
flex: 1,
|
|
2124
|
-
padding:
|
|
2316
|
+
padding: 16
|
|
2125
2317
|
},
|
|
2126
2318
|
fileDetailCard: {
|
|
2127
|
-
padding:
|
|
2128
|
-
borderRadius:
|
|
2319
|
+
padding: 18,
|
|
2320
|
+
borderRadius: 14,
|
|
2129
2321
|
borderWidth: 1,
|
|
2130
2322
|
alignItems: 'center'
|
|
2131
2323
|
},
|
|
@@ -2187,25 +2379,25 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
2187
2379
|
left: 0,
|
|
2188
2380
|
right: 0,
|
|
2189
2381
|
bottom: 0,
|
|
2190
|
-
backgroundColor: 'rgba(0, 0, 0, 0.
|
|
2382
|
+
backgroundColor: 'rgba(0, 0, 0, 0.5)',
|
|
2191
2383
|
justifyContent: 'center',
|
|
2192
2384
|
alignItems: 'center',
|
|
2193
2385
|
zIndex: 1000
|
|
2194
2386
|
},
|
|
2195
2387
|
dragDropContent: {
|
|
2196
2388
|
alignItems: 'center',
|
|
2197
|
-
backgroundColor: 'rgba(255, 255, 255, 0.
|
|
2198
|
-
padding:
|
|
2199
|
-
borderRadius:
|
|
2200
|
-
borderWidth:
|
|
2201
|
-
borderColor: '#
|
|
2389
|
+
backgroundColor: 'rgba(255, 255, 255, 0.95)',
|
|
2390
|
+
padding: 20,
|
|
2391
|
+
borderRadius: 14,
|
|
2392
|
+
borderWidth: 1,
|
|
2393
|
+
borderColor: '#66AFFF',
|
|
2202
2394
|
borderStyle: 'dashed'
|
|
2203
2395
|
},
|
|
2204
2396
|
dragDropTitle: {
|
|
2205
|
-
fontSize:
|
|
2397
|
+
fontSize: 20,
|
|
2206
2398
|
fontWeight: 'bold',
|
|
2207
|
-
marginTop:
|
|
2208
|
-
marginBottom:
|
|
2399
|
+
marginTop: 12,
|
|
2400
|
+
marginBottom: 6
|
|
2209
2401
|
},
|
|
2210
2402
|
dragDropSubtitle: {
|
|
2211
2403
|
fontSize: 16,
|
|
@@ -2218,8 +2410,8 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
2218
2410
|
fileViewerHeader: {
|
|
2219
2411
|
flexDirection: 'row',
|
|
2220
2412
|
alignItems: 'center',
|
|
2221
|
-
paddingHorizontal:
|
|
2222
|
-
paddingVertical:
|
|
2413
|
+
paddingHorizontal: 16,
|
|
2414
|
+
paddingVertical: 12,
|
|
2223
2415
|
borderBottomWidth: 1
|
|
2224
2416
|
},
|
|
2225
2417
|
fileViewerTitleContainer: {
|
|
@@ -2247,7 +2439,7 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
2247
2439
|
},
|
|
2248
2440
|
fileViewerContentContainer: {
|
|
2249
2441
|
flexGrow: 1,
|
|
2250
|
-
padding:
|
|
2442
|
+
padding: 14
|
|
2251
2443
|
},
|
|
2252
2444
|
fileViewerLoading: {
|
|
2253
2445
|
flex: 1,
|
|
@@ -2265,10 +2457,10 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
2265
2457
|
},
|
|
2266
2458
|
textContainer: {
|
|
2267
2459
|
flex: 1,
|
|
2268
|
-
borderRadius:
|
|
2460
|
+
borderRadius: 10,
|
|
2269
2461
|
borderWidth: 1,
|
|
2270
|
-
padding:
|
|
2271
|
-
minHeight:
|
|
2462
|
+
padding: 12,
|
|
2463
|
+
minHeight: 180,
|
|
2272
2464
|
maxHeight: '80%'
|
|
2273
2465
|
},
|
|
2274
2466
|
textContent: {
|
|
@@ -2280,8 +2472,8 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
2280
2472
|
flex: 1,
|
|
2281
2473
|
justifyContent: 'center',
|
|
2282
2474
|
alignItems: 'center',
|
|
2283
|
-
paddingVertical:
|
|
2284
|
-
paddingHorizontal:
|
|
2475
|
+
paddingVertical: 40,
|
|
2476
|
+
paddingHorizontal: 24
|
|
2285
2477
|
},
|
|
2286
2478
|
unsupportedFileTitle: {
|
|
2287
2479
|
fontSize: 24,
|
|
@@ -2300,9 +2492,9 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
2300
2492
|
downloadButtonLarge: {
|
|
2301
2493
|
flexDirection: 'row',
|
|
2302
2494
|
alignItems: 'center',
|
|
2303
|
-
paddingHorizontal:
|
|
2304
|
-
paddingVertical:
|
|
2305
|
-
borderRadius:
|
|
2495
|
+
paddingHorizontal: 18,
|
|
2496
|
+
paddingVertical: 12,
|
|
2497
|
+
borderRadius: 20,
|
|
2306
2498
|
gap: 8
|
|
2307
2499
|
},
|
|
2308
2500
|
downloadButtonText: {
|
|
@@ -2328,10 +2520,10 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
2328
2520
|
},
|
|
2329
2521
|
// File Details in Viewer styles
|
|
2330
2522
|
fileDetailsSection: {
|
|
2331
|
-
margin:
|
|
2523
|
+
margin: 12,
|
|
2332
2524
|
marginTop: 0,
|
|
2333
|
-
padding:
|
|
2334
|
-
borderRadius:
|
|
2525
|
+
padding: 14,
|
|
2526
|
+
borderRadius: 10,
|
|
2335
2527
|
borderWidth: 1
|
|
2336
2528
|
},
|
|
2337
2529
|
fileDetailsSectionTitle: {
|
|
@@ -2374,6 +2566,15 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
2374
2566
|
alignItems: 'center',
|
|
2375
2567
|
gap: 16
|
|
2376
2568
|
},
|
|
2569
|
+
controlsBar: {
|
|
2570
|
+
flexDirection: 'row',
|
|
2571
|
+
alignItems: 'center',
|
|
2572
|
+
justifyContent: 'space-between',
|
|
2573
|
+
paddingHorizontal: 16,
|
|
2574
|
+
paddingTop: 8,
|
|
2575
|
+
paddingBottom: 4,
|
|
2576
|
+
gap: 12
|
|
2577
|
+
},
|
|
2377
2578
|
viewModeToggle: {
|
|
2378
2579
|
flexDirection: 'row',
|
|
2379
2580
|
borderRadius: 24,
|
|
@@ -2391,17 +2592,17 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
2391
2592
|
},
|
|
2392
2593
|
// Photo Grid styles
|
|
2393
2594
|
photoScrollContainer: {
|
|
2394
|
-
padding:
|
|
2595
|
+
padding: 10
|
|
2395
2596
|
},
|
|
2396
2597
|
photoDateSection: {
|
|
2397
|
-
marginBottom:
|
|
2598
|
+
marginBottom: 16
|
|
2398
2599
|
},
|
|
2399
2600
|
photoDateHeader: {
|
|
2400
|
-
fontSize:
|
|
2601
|
+
fontSize: 16,
|
|
2401
2602
|
fontWeight: '600',
|
|
2402
2603
|
fontFamily: _fonts.fontFamilies.phuduSemiBold,
|
|
2403
|
-
marginBottom:
|
|
2404
|
-
paddingHorizontal:
|
|
2604
|
+
marginBottom: 8,
|
|
2605
|
+
paddingHorizontal: 2
|
|
2405
2606
|
},
|
|
2406
2607
|
photoGrid: {
|
|
2407
2608
|
flexDirection: 'row',
|
|
@@ -2453,7 +2654,7 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
2453
2654
|
position: 'relative',
|
|
2454
2655
|
borderRadius: 6,
|
|
2455
2656
|
overflow: 'hidden',
|
|
2456
|
-
backgroundColor: '
|
|
2657
|
+
backgroundColor: 'transparent'
|
|
2457
2658
|
},
|
|
2458
2659
|
justifiedPhotoImage: {
|
|
2459
2660
|
width: '100%',
|
|
@@ -2464,7 +2665,7 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
2464
2665
|
simplePhotoItem: {
|
|
2465
2666
|
borderRadius: 8,
|
|
2466
2667
|
overflow: 'hidden',
|
|
2467
|
-
backgroundColor: '
|
|
2668
|
+
backgroundColor: 'transparent'
|
|
2468
2669
|
},
|
|
2469
2670
|
simplePhotoContainer: {
|
|
2470
2671
|
width: '100%',
|