@oxyhq/services 5.4.1 → 5.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/assets/icons/OxyServices.js +1 -1
- package/lib/commonjs/core/index.js +84 -2
- package/lib/commonjs/core/index.js.map +1 -1
- package/lib/commonjs/index.js +22 -22
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/node/index.js +6 -6
- package/lib/commonjs/node/index.js.map +1 -1
- package/lib/commonjs/ui/components/Avatar.js +3 -3
- package/lib/commonjs/ui/components/Avatar.js.map +1 -1
- package/lib/commonjs/ui/components/FollowButton.js +3 -3
- package/lib/commonjs/ui/components/GroupedSection.js +1 -1
- package/lib/commonjs/ui/components/OxyLogo.js +1 -1
- package/lib/commonjs/ui/components/OxyProvider.js +13 -13
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/OxySignInButton.js +2 -2
- package/lib/commonjs/ui/components/ProfileCard.js +2 -2
- package/lib/commonjs/ui/components/Section.js +1 -1
- package/lib/commonjs/ui/components/SectionTitle.js +1 -1
- package/lib/commonjs/ui/components/icon/index.js +1 -1
- package/lib/commonjs/ui/components/index.js +12 -12
- package/lib/commonjs/ui/context/OxyContext.js +20 -4
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/index.js +11 -11
- package/lib/commonjs/ui/index.js.map +1 -1
- package/lib/commonjs/ui/navigation/OxyRouter.js +18 -18
- package/lib/commonjs/ui/screens/AccountCenterScreen.js +18 -18
- package/lib/commonjs/ui/screens/AccountCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountManagementDemo.js +3 -3
- package/lib/commonjs/ui/screens/AccountManagementDemo.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js +45 -27
- package/lib/commonjs/ui/screens/AccountOverviewScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +29 -22
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSwitcherScreen.js +3 -3
- package/lib/commonjs/ui/screens/AppInfoScreen.js +6 -6
- package/lib/commonjs/ui/screens/BillingManagementScreen.js +3 -3
- package/lib/commonjs/ui/screens/FileManagementScreen.js +324 -306
- package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +3 -3
- package/lib/commonjs/ui/screens/ProfileScreen.js +2 -2
- package/lib/commonjs/ui/screens/SessionManagementScreen.js +2 -2
- package/lib/commonjs/ui/screens/SignInScreen.js +358 -310
- package/lib/commonjs/ui/screens/SignInScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/SignUpScreen.js +483 -308
- package/lib/commonjs/ui/screens/SignUpScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaCenterScreen.js +3 -3
- package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js +51 -26
- package/lib/commonjs/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/karma/KarmaLeaderboardScreen.js +2 -2
- package/lib/commonjs/ui/screens/karma/KarmaRulesScreen.js +1 -1
- package/lib/commonjs/ui/styles/index.js +2 -2
- package/lib/commonjs/ui/styles/theme.js +1 -1
- package/lib/commonjs/utils/index.js +1 -1
- package/lib/module/assets/icons/OxyServices.js +1 -1
- package/lib/module/assets/icons/OxyServices.js.map +1 -1
- package/lib/module/core/index.js +84 -2
- package/lib/module/core/index.js.map +1 -1
- package/lib/module/index.js +10 -10
- package/lib/module/index.js.map +1 -1
- package/lib/module/node/index.js +4 -4
- package/lib/module/node/index.js.map +1 -1
- package/lib/module/ui/components/Avatar.js +2 -2
- package/lib/module/ui/components/Avatar.js.map +1 -1
- package/lib/module/ui/components/FollowButton.js +3 -3
- package/lib/module/ui/components/FollowButton.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/OxyLogo.js +1 -1
- package/lib/module/ui/components/OxyLogo.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +10 -10
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/OxySignInButton.js +2 -2
- package/lib/module/ui/components/OxySignInButton.js.map +1 -1
- package/lib/module/ui/components/ProfileCard.js +2 -2
- package/lib/module/ui/components/ProfileCard.js.map +1 -1
- package/lib/module/ui/components/Section.js +1 -1
- package/lib/module/ui/components/Section.js.map +1 -1
- package/lib/module/ui/components/SectionTitle.js +1 -1
- package/lib/module/ui/components/SectionTitle.js.map +1 -1
- package/lib/module/ui/components/icon/index.js +1 -1
- package/lib/module/ui/components/icon/index.js.map +1 -1
- package/lib/module/ui/components/index.js +12 -12
- package/lib/module/ui/components/index.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +20 -4
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/index.js +10 -10
- package/lib/module/ui/index.js.map +1 -1
- package/lib/module/ui/navigation/OxyRouter.js +18 -18
- package/lib/module/ui/navigation/OxyRouter.js.map +1 -1
- package/lib/module/ui/screens/AccountCenterScreen.js +5 -5
- package/lib/module/ui/screens/AccountCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountManagementDemo.js +2 -2
- package/lib/module/ui/screens/AccountManagementDemo.js.map +1 -1
- package/lib/module/ui/screens/AccountOverviewScreen.js +46 -28
- package/lib/module/ui/screens/AccountOverviewScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js +30 -23
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/AccountSwitcherScreen.js +3 -3
- package/lib/module/ui/screens/AccountSwitcherScreen.js.map +1 -1
- package/lib/module/ui/screens/AppInfoScreen.js +6 -6
- package/lib/module/ui/screens/AppInfoScreen.js.map +1 -1
- package/lib/module/ui/screens/BillingManagementScreen.js +3 -3
- package/lib/module/ui/screens/BillingManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/FileManagementScreen.js +325 -307
- package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js +3 -3
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/module/ui/screens/ProfileScreen.js +2 -2
- package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/SessionManagementScreen.js +2 -2
- package/lib/module/ui/screens/SessionManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/SignInScreen.js +358 -310
- package/lib/module/ui/screens/SignInScreen.js.map +1 -1
- package/lib/module/ui/screens/SignUpScreen.js +486 -309
- package/lib/module/ui/screens/SignUpScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaCenterScreen.js +3 -3
- package/lib/module/ui/screens/karma/KarmaCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaFAQScreen.js +52 -27
- package/lib/module/ui/screens/karma/KarmaFAQScreen.js.map +1 -1
- package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.js +2 -2
- package/lib/module/ui/screens/karma/KarmaLeaderboardScreen.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/styles/index.js +2 -2
- package/lib/module/ui/styles/index.js.map +1 -1
- package/lib/module/ui/styles/theme.js +1 -1
- package/lib/module/ui/styles/theme.js.map +1 -1
- package/lib/module/utils/index.js +1 -1
- package/lib/module/utils/index.js.map +1 -1
- package/lib/typescript/core/index.d.ts +24 -0
- package/lib/typescript/core/index.d.ts.map +1 -1
- package/lib/typescript/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/AccountOverviewScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/AccountSettingsScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/FileManagementScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SignInScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/SignUpScreen.d.ts.map +1 -1
- package/lib/typescript/ui/screens/karma/KarmaFAQScreen.d.ts +2 -2
- package/lib/typescript/ui/screens/karma/KarmaFAQScreen.d.ts.map +1 -1
- package/package.json +21 -5
- package/src/core/index.ts +68 -0
- package/src/ui/components/OxyProvider.tsx +5 -5
- package/src/ui/context/OxyContext.tsx +61 -41
- package/src/ui/screens/AccountOverviewScreen.tsx +44 -26
- package/src/ui/screens/AccountSettingsScreen.tsx +24 -18
- package/src/ui/screens/FileManagementScreen.tsx +246 -211
- package/src/ui/screens/SignInScreen.tsx +382 -326
- package/src/ui/screens/SignUpScreen.tsx +443 -273
- package/src/ui/screens/karma/KarmaFAQScreen.tsx +50 -29
- package/lib/commonjs/package.json +0 -1
- package/lib/module/package.json +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState, useEffect, useCallback } from 'react';
|
|
1
|
+
import React, { useState, useEffect, useCallback, useMemo } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
View,
|
|
4
4
|
Text,
|
|
@@ -65,14 +65,24 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
65
65
|
const [loadingDimensions, setLoadingDimensions] = useState(false);
|
|
66
66
|
const [hoveredPreview, setHoveredPreview] = useState<string | null>(null);
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
68
|
+
// Memoize theme-related calculations to prevent unnecessary recalculations
|
|
69
|
+
const themeStyles = useMemo(() => {
|
|
70
|
+
const isDarkTheme = theme === 'dark';
|
|
71
|
+
return {
|
|
72
|
+
isDarkTheme,
|
|
73
|
+
textColor: isDarkTheme ? '#FFFFFF' : '#000000',
|
|
74
|
+
backgroundColor: isDarkTheme ? '#121212' : '#f2f2f2',
|
|
75
|
+
secondaryBackgroundColor: isDarkTheme ? '#222222' : '#FFFFFF',
|
|
76
|
+
borderColor: isDarkTheme ? '#444444' : '#E0E0E0',
|
|
77
|
+
primaryColor: '#007AFF',
|
|
78
|
+
dangerColor: '#FF3B30',
|
|
79
|
+
successColor: '#34C759',
|
|
80
|
+
};
|
|
81
|
+
}, [theme]);
|
|
82
|
+
|
|
83
|
+
// Extract commonly used theme variables
|
|
84
|
+
const backgroundColor = themeStyles.backgroundColor;
|
|
85
|
+
const borderColor = themeStyles.borderColor;
|
|
76
86
|
|
|
77
87
|
const targetUserId = userId || user?.id;
|
|
78
88
|
|
|
@@ -199,7 +209,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
199
209
|
}, [oxyServices, photoDimensions]);
|
|
200
210
|
|
|
201
211
|
// Create justified rows from photos with responsive algorithm
|
|
202
|
-
const createJustifiedRows = useCallback((photos: FileMetadata[]) => {
|
|
212
|
+
const createJustifiedRows = useCallback((photos: FileMetadata[], containerWidth: number) => {
|
|
203
213
|
if (photos.length === 0) return [];
|
|
204
214
|
|
|
205
215
|
const rows: FileMetadata[][] = [];
|
|
@@ -689,11 +699,12 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
689
699
|
const isVideo = file.contentType.startsWith('video/');
|
|
690
700
|
const isAudio = file.contentType.startsWith('audio/');
|
|
691
701
|
const hasPreview = isImage || isPDF || isVideo;
|
|
702
|
+
const borderColor = themeStyles.borderColor;
|
|
692
703
|
|
|
693
704
|
return (
|
|
694
705
|
<View
|
|
695
706
|
key={file.id}
|
|
696
|
-
style={[styles.fileItem, { backgroundColor: secondaryBackgroundColor, borderColor }]}
|
|
707
|
+
style={[styles.fileItem, { backgroundColor: themeStyles.secondaryBackgroundColor, borderColor }]}
|
|
697
708
|
>
|
|
698
709
|
<TouchableOpacity
|
|
699
710
|
style={styles.fileContent}
|
|
@@ -744,14 +755,14 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
744
755
|
)}
|
|
745
756
|
{isPDF && (
|
|
746
757
|
<View style={styles.pdfPreview}>
|
|
747
|
-
<Ionicons name="document" size={32} color={primaryColor} />
|
|
748
|
-
<Text style={[styles.pdfLabel, { color: primaryColor }]}>PDF</Text>
|
|
758
|
+
<Ionicons name="document" size={32} color={themeStyles.primaryColor} />
|
|
759
|
+
<Text style={[styles.pdfLabel, { color: themeStyles.primaryColor }]}>PDF</Text>
|
|
749
760
|
</View>
|
|
750
761
|
)}
|
|
751
762
|
{isVideo && (
|
|
752
763
|
<View style={styles.videoPreview}>
|
|
753
|
-
<Ionicons name="play-circle" size={32} color={primaryColor} />
|
|
754
|
-
<Text style={[styles.videoLabel, { color: primaryColor }]}>VIDEO</Text>
|
|
764
|
+
<Ionicons name="play-circle" size={32} color={themeStyles.primaryColor} />
|
|
765
|
+
<Text style={[styles.videoLabel, { color: themeStyles.primaryColor }]}>VIDEO</Text>
|
|
755
766
|
</View>
|
|
756
767
|
)}
|
|
757
768
|
{/* Fallback icon (hidden by default for images) */}
|
|
@@ -762,7 +773,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
762
773
|
<Ionicons
|
|
763
774
|
name={getFileIcon(file.contentType) as any}
|
|
764
775
|
size={32}
|
|
765
|
-
color={primaryColor}
|
|
776
|
+
color={themeStyles.primaryColor}
|
|
766
777
|
/>
|
|
767
778
|
</View>
|
|
768
779
|
|
|
@@ -778,22 +789,22 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
778
789
|
<Ionicons
|
|
779
790
|
name={getFileIcon(file.contentType) as any}
|
|
780
791
|
size={32}
|
|
781
|
-
color={primaryColor}
|
|
792
|
+
color={themeStyles.primaryColor}
|
|
782
793
|
/>
|
|
783
794
|
</View>
|
|
784
795
|
)}
|
|
785
796
|
</View>
|
|
786
797
|
|
|
787
798
|
<View style={styles.fileInfo}>
|
|
788
|
-
<Text style={[styles.fileName, { color: textColor }]} numberOfLines={1}>
|
|
799
|
+
<Text style={[styles.fileName, { color: themeStyles.textColor }]} numberOfLines={1}>
|
|
789
800
|
{file.filename}
|
|
790
801
|
</Text>
|
|
791
|
-
<Text style={[styles.fileDetails, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
802
|
+
<Text style={[styles.fileDetails, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
792
803
|
{formatFileSize(file.length)} • {new Date(file.uploadDate).toLocaleDateString()}
|
|
793
804
|
</Text>
|
|
794
805
|
{file.metadata?.description && (
|
|
795
806
|
<Text
|
|
796
|
-
style={[styles.fileDescription, { color: isDarkTheme ? '#AAAAAA' : '#888888' }]}
|
|
807
|
+
style={[styles.fileDescription, { color: themeStyles.isDarkTheme ? '#AAAAAA' : '#888888' }]}
|
|
797
808
|
numberOfLines={2}
|
|
798
809
|
>
|
|
799
810
|
{file.metadata.description}
|
|
@@ -806,32 +817,32 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
806
817
|
{/* Preview button for supported files */}
|
|
807
818
|
{hasPreview && (
|
|
808
819
|
<TouchableOpacity
|
|
809
|
-
style={[styles.actionButton, { backgroundColor: isDarkTheme ? '#333333' : '#F0F0F0' }]}
|
|
820
|
+
style={[styles.actionButton, { backgroundColor: themeStyles.isDarkTheme ? '#333333' : '#F0F0F0' }]}
|
|
810
821
|
onPress={() => handleFileOpen(file)}
|
|
811
822
|
>
|
|
812
|
-
<Ionicons name="eye" size={20} color={primaryColor} />
|
|
823
|
+
<Ionicons name="eye" size={20} color={themeStyles.primaryColor} />
|
|
813
824
|
</TouchableOpacity>
|
|
814
825
|
)}
|
|
815
826
|
|
|
816
827
|
<TouchableOpacity
|
|
817
|
-
style={[styles.actionButton, { backgroundColor: isDarkTheme ? '#333333' : '#F0F0F0' }]}
|
|
828
|
+
style={[styles.actionButton, { backgroundColor: themeStyles.isDarkTheme ? '#333333' : '#F0F0F0' }]}
|
|
818
829
|
onPress={() => handleFileDownload(file.id, file.filename)}
|
|
819
830
|
>
|
|
820
|
-
<Ionicons name="download" size={20} color={primaryColor} />
|
|
831
|
+
<Ionicons name="download" size={20} color={themeStyles.primaryColor} />
|
|
821
832
|
</TouchableOpacity>
|
|
822
833
|
|
|
823
834
|
{/* Always show delete button for debugging */}
|
|
824
835
|
<TouchableOpacity
|
|
825
|
-
style={[styles.actionButton, { backgroundColor: isDarkTheme ? '#400000' : '#FFEBEE' }]}
|
|
836
|
+
style={[styles.actionButton, { backgroundColor: themeStyles.isDarkTheme ? '#400000' : '#FFEBEE' }]}
|
|
826
837
|
onPress={() => {
|
|
827
838
|
handleFileDelete(file.id, file.filename);
|
|
828
839
|
}}
|
|
829
840
|
disabled={deleting === file.id}
|
|
830
841
|
>
|
|
831
842
|
{deleting === file.id ? (
|
|
832
|
-
<ActivityIndicator size="small" color={dangerColor} />
|
|
843
|
+
<ActivityIndicator size="small" color={themeStyles.dangerColor} />
|
|
833
844
|
) : (
|
|
834
|
-
<Ionicons name="trash" size={20} color={dangerColor} />
|
|
845
|
+
<Ionicons name="trash" size={20} color={themeStyles.dangerColor} />
|
|
835
846
|
)}
|
|
836
847
|
</TouchableOpacity>
|
|
837
848
|
</View>
|
|
@@ -839,15 +850,81 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
839
850
|
);
|
|
840
851
|
};
|
|
841
852
|
|
|
853
|
+
const renderPhotoItem = (photo: FileMetadata, index: number) => {
|
|
854
|
+
const downloadUrl = oxyServices.getFileDownloadUrl(photo.id);
|
|
855
|
+
|
|
856
|
+
// Calculate photo item width based on actual container size from bottom sheet
|
|
857
|
+
let itemsPerRow = 3; // Default for mobile
|
|
858
|
+
if (containerWidth > 768) itemsPerRow = 6; // Tablet/Desktop
|
|
859
|
+
else if (containerWidth > 480) itemsPerRow = 4; // Large mobile
|
|
860
|
+
|
|
861
|
+
// Account for the photoScrollContainer padding (16px on each side = 32px total)
|
|
862
|
+
const scrollContainerPadding = 32; // Total horizontal padding from photoScrollContainer
|
|
863
|
+
const gaps = (itemsPerRow - 1) * 4; // Gap between items
|
|
864
|
+
const availableWidth = containerWidth - scrollContainerPadding;
|
|
865
|
+
const itemWidth = (availableWidth - gaps) / itemsPerRow;
|
|
866
|
+
|
|
867
|
+
return (
|
|
868
|
+
<TouchableOpacity
|
|
869
|
+
key={photo.id}
|
|
870
|
+
style={[
|
|
871
|
+
styles.photoItem,
|
|
872
|
+
{
|
|
873
|
+
width: itemWidth,
|
|
874
|
+
height: itemWidth,
|
|
875
|
+
}
|
|
876
|
+
]}
|
|
877
|
+
onPress={() => handleFileOpen(photo)}
|
|
878
|
+
activeOpacity={0.8}
|
|
879
|
+
>
|
|
880
|
+
<View style={styles.photoContainer}>
|
|
881
|
+
{Platform.OS === 'web' ? (
|
|
882
|
+
<img
|
|
883
|
+
src={downloadUrl}
|
|
884
|
+
alt={photo.filename}
|
|
885
|
+
style={{
|
|
886
|
+
width: '100%',
|
|
887
|
+
height: '100%',
|
|
888
|
+
objectFit: 'cover',
|
|
889
|
+
borderRadius: 8,
|
|
890
|
+
transition: 'transform 0.2s ease',
|
|
891
|
+
}}
|
|
892
|
+
loading="lazy"
|
|
893
|
+
onError={(e) => {
|
|
894
|
+
console.error('Photo failed to load:', e);
|
|
895
|
+
// Could replace with placeholder image
|
|
896
|
+
}}
|
|
897
|
+
onMouseEnter={(e) => {
|
|
898
|
+
e.currentTarget.style.transform = 'scale(1.02)';
|
|
899
|
+
}}
|
|
900
|
+
onMouseLeave={(e) => {
|
|
901
|
+
e.currentTarget.style.transform = 'scale(1)';
|
|
902
|
+
}}
|
|
903
|
+
/>
|
|
904
|
+
) : (
|
|
905
|
+
<Image
|
|
906
|
+
source={{ uri: downloadUrl }}
|
|
907
|
+
style={styles.photoImage}
|
|
908
|
+
resizeMode="cover"
|
|
909
|
+
onError={(e) => {
|
|
910
|
+
console.error('Photo failed to load:', e);
|
|
911
|
+
}}
|
|
912
|
+
/>
|
|
913
|
+
)}
|
|
914
|
+
</View>
|
|
915
|
+
</TouchableOpacity>
|
|
916
|
+
);
|
|
917
|
+
};
|
|
918
|
+
|
|
842
919
|
const renderPhotoGrid = useCallback(() => {
|
|
843
920
|
const photos = filteredFiles.filter(file => file.contentType.startsWith('image/'));
|
|
844
921
|
|
|
845
922
|
if (photos.length === 0) {
|
|
846
923
|
return (
|
|
847
924
|
<View style={styles.emptyState}>
|
|
848
|
-
<Ionicons name="images-outline" size={64} color={isDarkTheme ? '#666666' : '#CCCCCC'} />
|
|
849
|
-
<Text style={[styles.emptyStateTitle, { color: textColor }]}>No Photos Yet</Text>
|
|
850
|
-
<Text style={[styles.emptyStateDescription, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
925
|
+
<Ionicons name="images-outline" size={64} color={themeStyles.isDarkTheme ? '#666666' : '#CCCCCC'} />
|
|
926
|
+
<Text style={[styles.emptyStateTitle, { color: themeStyles.textColor }]}>No Photos Yet</Text>
|
|
927
|
+
<Text style={[styles.emptyStateDescription, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
851
928
|
{user?.id === targetUserId
|
|
852
929
|
? `Upload photos to get started. You can select multiple photos at once${Platform.OS === 'web' ? ' or drag & drop them here.' : '.'}`
|
|
853
930
|
: "This user hasn't uploaded any photos yet"
|
|
@@ -855,7 +932,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
855
932
|
</Text>
|
|
856
933
|
{user?.id === targetUserId && (
|
|
857
934
|
<TouchableOpacity
|
|
858
|
-
style={[styles.emptyStateButton, { backgroundColor: primaryColor }]}
|
|
935
|
+
style={[styles.emptyStateButton, { backgroundColor: themeStyles.primaryColor }]}
|
|
859
936
|
onPress={handleFileUpload}
|
|
860
937
|
disabled={uploading}
|
|
861
938
|
>
|
|
@@ -881,15 +958,15 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
881
958
|
<RefreshControl
|
|
882
959
|
refreshing={refreshing}
|
|
883
960
|
onRefresh={() => loadFiles(true)}
|
|
884
|
-
tintColor={primaryColor}
|
|
961
|
+
tintColor={themeStyles.primaryColor}
|
|
885
962
|
/>
|
|
886
963
|
}
|
|
887
964
|
showsVerticalScrollIndicator={false}
|
|
888
965
|
>
|
|
889
966
|
{loadingDimensions && (
|
|
890
967
|
<View style={styles.dimensionsLoadingIndicator}>
|
|
891
|
-
<ActivityIndicator size="small" color={primaryColor} />
|
|
892
|
-
<Text style={[styles.dimensionsLoadingText, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
968
|
+
<ActivityIndicator size="small" color={themeStyles.primaryColor} />
|
|
969
|
+
<Text style={[styles.dimensionsLoadingText, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
893
970
|
Loading photo layout...
|
|
894
971
|
</Text>
|
|
895
972
|
</View>
|
|
@@ -902,12 +979,28 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
902
979
|
createJustifiedRows={createJustifiedRows}
|
|
903
980
|
renderJustifiedPhotoItem={renderJustifiedPhotoItem}
|
|
904
981
|
renderSimplePhotoItem={renderPhotoItem}
|
|
905
|
-
textColor={textColor}
|
|
982
|
+
textColor={themeStyles.textColor}
|
|
906
983
|
containerWidth={containerWidth}
|
|
907
984
|
/>
|
|
908
985
|
</ScrollView>
|
|
909
986
|
);
|
|
910
|
-
}, [
|
|
987
|
+
}, [
|
|
988
|
+
filteredFiles,
|
|
989
|
+
themeStyles,
|
|
990
|
+
user?.id,
|
|
991
|
+
targetUserId,
|
|
992
|
+
uploading,
|
|
993
|
+
handleFileUpload,
|
|
994
|
+
refreshing,
|
|
995
|
+
loadFiles,
|
|
996
|
+
loadingDimensions,
|
|
997
|
+
photoDimensions,
|
|
998
|
+
loadPhotoDimensions,
|
|
999
|
+
createJustifiedRows,
|
|
1000
|
+
renderJustifiedPhotoItem,
|
|
1001
|
+
renderPhotoItem,
|
|
1002
|
+
containerWidth
|
|
1003
|
+
]);
|
|
911
1004
|
|
|
912
1005
|
// Separate component for the photo grid to optimize rendering
|
|
913
1006
|
const JustifiedPhotoGrid = React.memo(({
|
|
@@ -960,7 +1053,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
960
1053
|
|
|
961
1054
|
return (
|
|
962
1055
|
<View key={date} style={styles.photoDateSection}>
|
|
963
|
-
<Text style={[styles.photoDateHeader, { color: textColor }]}>
|
|
1056
|
+
<Text style={[styles.photoDateHeader, { color: themeStyles.textColor }]}>
|
|
964
1057
|
{new Date(date).toLocaleDateString('en-US', {
|
|
965
1058
|
weekday: 'long',
|
|
966
1059
|
year: 'numeric',
|
|
@@ -1031,140 +1124,78 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1031
1124
|
);
|
|
1032
1125
|
});
|
|
1033
1126
|
|
|
1034
|
-
const
|
|
1035
|
-
const
|
|
1036
|
-
|
|
1037
|
-
// Calculate photo item width based on actual container size from bottom sheet
|
|
1038
|
-
let itemsPerRow = 3; // Default for mobile
|
|
1039
|
-
if (containerWidth > 768) itemsPerRow = 6; // Tablet/Desktop
|
|
1040
|
-
else if (containerWidth > 480) itemsPerRow = 4; // Large mobile
|
|
1041
|
-
|
|
1042
|
-
// Account for the photoScrollContainer padding (16px on each side = 32px total)
|
|
1043
|
-
const scrollContainerPadding = 32; // Total horizontal padding from photoScrollContainer
|
|
1044
|
-
const gaps = (itemsPerRow - 1) * 4; // Gap between items
|
|
1045
|
-
const availableWidth = containerWidth - scrollContainerPadding;
|
|
1046
|
-
const itemWidth = (availableWidth - gaps) / itemsPerRow;
|
|
1127
|
+
const renderFileDetailsModal = () => {
|
|
1128
|
+
const backgroundColor = themeStyles.backgroundColor;
|
|
1129
|
+
const borderColor = themeStyles.borderColor;
|
|
1047
1130
|
|
|
1048
1131
|
return (
|
|
1049
|
-
<
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
width: itemWidth,
|
|
1055
|
-
height: itemWidth,
|
|
1056
|
-
}
|
|
1057
|
-
]}
|
|
1058
|
-
onPress={() => handleFileOpen(photo)}
|
|
1059
|
-
activeOpacity={0.8}
|
|
1132
|
+
<Modal
|
|
1133
|
+
visible={showFileDetails}
|
|
1134
|
+
animationType="slide"
|
|
1135
|
+
presentationStyle="pageSheet"
|
|
1136
|
+
onRequestClose={() => setShowFileDetails(false)}
|
|
1060
1137
|
>
|
|
1061
|
-
<View style={styles.
|
|
1062
|
-
{
|
|
1063
|
-
<
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
height: '100%',
|
|
1069
|
-
objectFit: 'cover',
|
|
1070
|
-
borderRadius: 8,
|
|
1071
|
-
transition: 'transform 0.2s ease',
|
|
1072
|
-
}}
|
|
1073
|
-
loading="lazy"
|
|
1074
|
-
onError={(e) => {
|
|
1075
|
-
console.error('Photo failed to load:', e);
|
|
1076
|
-
// Could replace with placeholder image
|
|
1077
|
-
}}
|
|
1078
|
-
onMouseEnter={(e) => {
|
|
1079
|
-
e.currentTarget.style.transform = 'scale(1.02)';
|
|
1080
|
-
}}
|
|
1081
|
-
onMouseLeave={(e) => {
|
|
1082
|
-
e.currentTarget.style.transform = 'scale(1)';
|
|
1083
|
-
}}
|
|
1084
|
-
/>
|
|
1085
|
-
) : (
|
|
1086
|
-
<Image
|
|
1087
|
-
source={{ uri: downloadUrl }}
|
|
1088
|
-
style={styles.photoImage}
|
|
1089
|
-
resizeMode="cover"
|
|
1090
|
-
onError={(e) => {
|
|
1091
|
-
console.error('Photo failed to load:', e);
|
|
1092
|
-
}}
|
|
1093
|
-
/>
|
|
1094
|
-
)}
|
|
1095
|
-
</View>
|
|
1096
|
-
</TouchableOpacity>
|
|
1097
|
-
);
|
|
1098
|
-
};
|
|
1099
|
-
|
|
1100
|
-
const renderFileDetailsModal = () => (
|
|
1101
|
-
<Modal
|
|
1102
|
-
visible={showFileDetails}
|
|
1103
|
-
animationType="slide"
|
|
1104
|
-
presentationStyle="pageSheet"
|
|
1105
|
-
onRequestClose={() => setShowFileDetails(false)}
|
|
1106
|
-
>
|
|
1107
|
-
<View style={[styles.modalContainer, { backgroundColor }]}>
|
|
1108
|
-
<View style={[styles.modalHeader, { borderBottomColor: borderColor }]}>
|
|
1109
|
-
<TouchableOpacity
|
|
1110
|
-
style={styles.modalCloseButton}
|
|
1111
|
-
onPress={() => setShowFileDetails(false)}
|
|
1112
|
-
>
|
|
1113
|
-
<Ionicons name="close" size={24} color={textColor} />
|
|
1138
|
+
<View style={[styles.modalContainer, { backgroundColor }]}>
|
|
1139
|
+
<View style={[styles.modalHeader, { borderBottomColor: borderColor }]}>
|
|
1140
|
+
<TouchableOpacity
|
|
1141
|
+
style={styles.modalCloseButton}
|
|
1142
|
+
onPress={() => setShowFileDetails(false)}
|
|
1143
|
+
>
|
|
1144
|
+
<Ionicons name="close" size={24} color={themeStyles.textColor} />
|
|
1114
1145
|
</TouchableOpacity>
|
|
1115
|
-
<Text style={[styles.modalTitle, { color: textColor }]}>File Details</Text>
|
|
1146
|
+
<Text style={[styles.modalTitle, { color: themeStyles.textColor }]}>File Details</Text>
|
|
1116
1147
|
<View style={styles.modalPlaceholder} />
|
|
1117
1148
|
</View>
|
|
1118
1149
|
|
|
1119
1150
|
{selectedFile && (
|
|
1120
1151
|
<ScrollView style={styles.modalContent}>
|
|
1121
|
-
<View style={[styles.fileDetailCard, { backgroundColor: secondaryBackgroundColor, borderColor }]}>
|
|
1152
|
+
<View style={[styles.fileDetailCard, { backgroundColor: themeStyles.secondaryBackgroundColor, borderColor }]}>
|
|
1122
1153
|
<View style={styles.fileDetailIcon}>
|
|
1123
1154
|
<Ionicons
|
|
1124
1155
|
name={getFileIcon(selectedFile.contentType) as any}
|
|
1125
1156
|
size={64}
|
|
1126
|
-
color={primaryColor}
|
|
1157
|
+
color={themeStyles.primaryColor}
|
|
1127
1158
|
/>
|
|
1128
1159
|
</View>
|
|
1129
1160
|
|
|
1130
|
-
<Text style={[styles.fileDetailName, { color: textColor }]}>
|
|
1161
|
+
<Text style={[styles.fileDetailName, { color: themeStyles.textColor }]}>
|
|
1131
1162
|
{selectedFile.filename}
|
|
1132
1163
|
</Text>
|
|
1133
1164
|
|
|
1134
1165
|
<View style={styles.fileDetailInfo}>
|
|
1135
1166
|
<View style={styles.detailRow}>
|
|
1136
|
-
<Text style={[styles.detailLabel, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1167
|
+
<Text style={[styles.detailLabel, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1137
1168
|
Size:
|
|
1138
1169
|
</Text>
|
|
1139
|
-
<Text style={[styles.detailValue, { color: textColor }]}>
|
|
1170
|
+
<Text style={[styles.detailValue, { color: themeStyles.textColor }]}>
|
|
1140
1171
|
{formatFileSize(selectedFile.length)}
|
|
1141
1172
|
</Text>
|
|
1142
1173
|
</View>
|
|
1143
1174
|
|
|
1144
1175
|
<View style={styles.detailRow}>
|
|
1145
|
-
<Text style={[styles.detailLabel, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1176
|
+
<Text style={[styles.detailLabel, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1146
1177
|
Type:
|
|
1147
1178
|
</Text>
|
|
1148
|
-
<Text style={[styles.detailValue, { color: textColor }]}>
|
|
1179
|
+
<Text style={[styles.detailValue, { color: themeStyles.textColor }]}>
|
|
1149
1180
|
{selectedFile.contentType}
|
|
1150
1181
|
</Text>
|
|
1151
1182
|
</View>
|
|
1152
1183
|
|
|
1153
1184
|
<View style={styles.detailRow}>
|
|
1154
|
-
<Text style={[styles.detailLabel, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1185
|
+
<Text style={[styles.detailLabel, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1155
1186
|
Uploaded:
|
|
1156
1187
|
</Text>
|
|
1157
|
-
<Text style={[styles.detailValue, { color: textColor }]}>
|
|
1188
|
+
<Text style={[styles.detailValue, { color: themeStyles.textColor }]}>
|
|
1158
1189
|
{new Date(selectedFile.uploadDate).toLocaleString()}
|
|
1159
1190
|
</Text>
|
|
1160
1191
|
</View>
|
|
1161
1192
|
|
|
1162
1193
|
{selectedFile.metadata?.description && (
|
|
1163
1194
|
<View style={styles.detailRow}>
|
|
1164
|
-
<Text style={[styles.detailLabel, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1195
|
+
<Text style={[styles.detailLabel, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1165
1196
|
Description:
|
|
1166
1197
|
</Text>
|
|
1167
|
-
<Text style={[styles.detailValue, { color: textColor }]}>
|
|
1198
|
+
<Text style={[styles.detailValue, { color: themeStyles.textColor }]}>
|
|
1168
1199
|
{selectedFile.metadata.description}
|
|
1169
1200
|
</Text>
|
|
1170
1201
|
</View>
|
|
@@ -1173,7 +1204,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1173
1204
|
|
|
1174
1205
|
<View style={styles.modalActions}>
|
|
1175
1206
|
<TouchableOpacity
|
|
1176
|
-
style={[styles.modalActionButton, { backgroundColor: primaryColor }]}
|
|
1207
|
+
style={[styles.modalActionButton, { backgroundColor: themeStyles.primaryColor }]}
|
|
1177
1208
|
onPress={() => {
|
|
1178
1209
|
handleFileDownload(selectedFile.id, selectedFile.filename);
|
|
1179
1210
|
setShowFileDetails(false);
|
|
@@ -1185,7 +1216,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1185
1216
|
|
|
1186
1217
|
{(user?.id === targetUserId) && (
|
|
1187
1218
|
<TouchableOpacity
|
|
1188
|
-
style={[styles.modalActionButton, { backgroundColor: dangerColor }]}
|
|
1219
|
+
style={[styles.modalActionButton, { backgroundColor: themeStyles.dangerColor }]}
|
|
1189
1220
|
onPress={() => {
|
|
1190
1221
|
setShowFileDetails(false);
|
|
1191
1222
|
handleFileDelete(selectedFile.id, selectedFile.filename);
|
|
@@ -1201,11 +1232,15 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1201
1232
|
)}
|
|
1202
1233
|
</View>
|
|
1203
1234
|
</Modal>
|
|
1204
|
-
|
|
1235
|
+
);
|
|
1236
|
+
};
|
|
1205
1237
|
|
|
1206
1238
|
const renderFileViewer = () => {
|
|
1207
1239
|
if (!openedFile) return null;
|
|
1208
1240
|
|
|
1241
|
+
const backgroundColor = themeStyles.backgroundColor;
|
|
1242
|
+
const borderColor = themeStyles.borderColor;
|
|
1243
|
+
|
|
1209
1244
|
const isImage = openedFile.contentType.startsWith('image/');
|
|
1210
1245
|
const isText = openedFile.contentType.startsWith('text/') ||
|
|
1211
1246
|
openedFile.contentType.includes('json') ||
|
|
@@ -1224,30 +1259,30 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1224
1259
|
style={styles.backButton}
|
|
1225
1260
|
onPress={handleCloseFile}
|
|
1226
1261
|
>
|
|
1227
|
-
<Ionicons name="arrow-back" size={24} color={textColor} />
|
|
1262
|
+
<Ionicons name="arrow-back" size={24} color={themeStyles.textColor} />
|
|
1228
1263
|
</TouchableOpacity>
|
|
1229
1264
|
<View style={styles.fileViewerTitleContainer}>
|
|
1230
|
-
<Text style={[styles.fileViewerTitle, { color: textColor }]} numberOfLines={1}>
|
|
1265
|
+
<Text style={[styles.fileViewerTitle, { color: themeStyles.textColor }]} numberOfLines={1}>
|
|
1231
1266
|
{openedFile.filename}
|
|
1232
1267
|
</Text>
|
|
1233
|
-
<Text style={[styles.fileViewerSubtitle, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1268
|
+
<Text style={[styles.fileViewerSubtitle, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1234
1269
|
{formatFileSize(openedFile.length)} • {openedFile.contentType}
|
|
1235
1270
|
</Text>
|
|
1236
1271
|
</View>
|
|
1237
1272
|
<View style={styles.fileViewerActions}>
|
|
1238
1273
|
<TouchableOpacity
|
|
1239
|
-
style={[styles.actionButton, { backgroundColor: isDarkTheme ? '#333333' : '#F0F0F0' }]}
|
|
1274
|
+
style={[styles.actionButton, { backgroundColor: themeStyles.isDarkTheme ? '#333333' : '#F0F0F0' }]}
|
|
1240
1275
|
onPress={() => handleFileDownload(openedFile.id, openedFile.filename)}
|
|
1241
1276
|
>
|
|
1242
|
-
<Ionicons name="download" size={20} color={primaryColor} />
|
|
1277
|
+
<Ionicons name="download" size={20} color={themeStyles.primaryColor} />
|
|
1243
1278
|
</TouchableOpacity>
|
|
1244
1279
|
<TouchableOpacity
|
|
1245
1280
|
style={[
|
|
1246
1281
|
styles.actionButton,
|
|
1247
1282
|
{
|
|
1248
1283
|
backgroundColor: showFileDetailsInViewer
|
|
1249
|
-
? primaryColor
|
|
1250
|
-
: (isDarkTheme ? '#333333' : '#F0F0F0')
|
|
1284
|
+
? themeStyles.primaryColor
|
|
1285
|
+
: (themeStyles.isDarkTheme ? '#333333' : '#F0F0F0')
|
|
1251
1286
|
}
|
|
1252
1287
|
]}
|
|
1253
1288
|
onPress={() => setShowFileDetailsInViewer(!showFileDetailsInViewer)}
|
|
@@ -1255,7 +1290,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1255
1290
|
<Ionicons
|
|
1256
1291
|
name={showFileDetailsInViewer ? "chevron-up" : "information-circle"}
|
|
1257
1292
|
size={20}
|
|
1258
|
-
color={showFileDetailsInViewer ? "#FFFFFF" : primaryColor}
|
|
1293
|
+
color={showFileDetailsInViewer ? "#FFFFFF" : themeStyles.primaryColor}
|
|
1259
1294
|
/>
|
|
1260
1295
|
</TouchableOpacity>
|
|
1261
1296
|
</View>
|
|
@@ -1263,72 +1298,72 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1263
1298
|
|
|
1264
1299
|
{/* File Details Section */}
|
|
1265
1300
|
{showFileDetailsInViewer && (
|
|
1266
|
-
<View style={[styles.fileDetailsSection, { backgroundColor: secondaryBackgroundColor, borderColor }]}>
|
|
1301
|
+
<View style={[styles.fileDetailsSection, { backgroundColor: themeStyles.secondaryBackgroundColor, borderColor }]}>
|
|
1267
1302
|
<View style={styles.fileDetailsSectionHeader}>
|
|
1268
|
-
<Text style={[styles.fileDetailsSectionTitle, { color: textColor }]}>
|
|
1303
|
+
<Text style={[styles.fileDetailsSectionTitle, { color: themeStyles.textColor }]}>
|
|
1269
1304
|
File Details
|
|
1270
1305
|
</Text>
|
|
1271
1306
|
<TouchableOpacity
|
|
1272
1307
|
style={styles.fileDetailsSectionToggle}
|
|
1273
1308
|
onPress={() => setShowFileDetailsInViewer(false)}
|
|
1274
1309
|
>
|
|
1275
|
-
<Ionicons name="chevron-up" size={20} color={isDarkTheme ? '#BBBBBB' : '#666666'} />
|
|
1310
|
+
<Ionicons name="chevron-up" size={20} color={themeStyles.isDarkTheme ? '#BBBBBB' : '#666666'} />
|
|
1276
1311
|
</TouchableOpacity>
|
|
1277
1312
|
</View>
|
|
1278
1313
|
|
|
1279
1314
|
<View style={styles.fileDetailInfo}>
|
|
1280
1315
|
<View style={styles.detailRow}>
|
|
1281
|
-
<Text style={[styles.detailLabel, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1316
|
+
<Text style={[styles.detailLabel, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1282
1317
|
File Name:
|
|
1283
1318
|
</Text>
|
|
1284
|
-
<Text style={[styles.detailValue, { color: textColor }]}>
|
|
1319
|
+
<Text style={[styles.detailValue, { color: themeStyles.textColor }]}>
|
|
1285
1320
|
{openedFile.filename}
|
|
1286
1321
|
</Text>
|
|
1287
1322
|
</View>
|
|
1288
1323
|
|
|
1289
1324
|
<View style={styles.detailRow}>
|
|
1290
|
-
<Text style={[styles.detailLabel, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1325
|
+
<Text style={[styles.detailLabel, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1291
1326
|
Size:
|
|
1292
1327
|
</Text>
|
|
1293
|
-
<Text style={[styles.detailValue, { color: textColor }]}>
|
|
1328
|
+
<Text style={[styles.detailValue, { color: themeStyles.textColor }]}>
|
|
1294
1329
|
{formatFileSize(openedFile.length)}
|
|
1295
1330
|
</Text>
|
|
1296
1331
|
</View>
|
|
1297
1332
|
|
|
1298
1333
|
<View style={styles.detailRow}>
|
|
1299
|
-
<Text style={[styles.detailLabel, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1334
|
+
<Text style={[styles.detailLabel, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1300
1335
|
Type:
|
|
1301
1336
|
</Text>
|
|
1302
|
-
<Text style={[styles.detailValue, { color: textColor }]}>
|
|
1337
|
+
<Text style={[styles.detailValue, { color: themeStyles.textColor }]}>
|
|
1303
1338
|
{openedFile.contentType}
|
|
1304
1339
|
</Text>
|
|
1305
1340
|
</View>
|
|
1306
1341
|
|
|
1307
1342
|
<View style={styles.detailRow}>
|
|
1308
|
-
<Text style={[styles.detailLabel, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1343
|
+
<Text style={[styles.detailLabel, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1309
1344
|
Uploaded:
|
|
1310
1345
|
</Text>
|
|
1311
|
-
<Text style={[styles.detailValue, { color: textColor }]}>
|
|
1346
|
+
<Text style={[styles.detailValue, { color: themeStyles.textColor }]}>
|
|
1312
1347
|
{new Date(openedFile.uploadDate).toLocaleString()}
|
|
1313
1348
|
</Text>
|
|
1314
1349
|
</View>
|
|
1315
1350
|
|
|
1316
1351
|
{openedFile.metadata?.description && (
|
|
1317
1352
|
<View style={styles.detailRow}>
|
|
1318
|
-
<Text style={[styles.detailLabel, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1353
|
+
<Text style={[styles.detailLabel, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1319
1354
|
Description:
|
|
1320
1355
|
</Text>
|
|
1321
|
-
<Text style={[styles.detailValue, { color: textColor }]}>
|
|
1356
|
+
<Text style={[styles.detailValue, { color: themeStyles.textColor }]}>
|
|
1322
1357
|
{openedFile.metadata.description}
|
|
1323
1358
|
</Text>
|
|
1324
1359
|
</View>
|
|
1325
1360
|
)}
|
|
1326
1361
|
|
|
1327
1362
|
<View style={styles.detailRow}>
|
|
1328
|
-
<Text style={[styles.detailLabel, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1363
|
+
<Text style={[styles.detailLabel, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1329
1364
|
File ID:
|
|
1330
1365
|
</Text>
|
|
1331
|
-
<Text style={[styles.detailValue, { color: textColor, fontSize: 12, fontFamily: Platform.OS === 'web' ? 'monospace' : 'Courier' }]}>
|
|
1366
|
+
<Text style={[styles.detailValue, { color: themeStyles.textColor, fontSize: 12, fontFamily: Platform.OS === 'web' ? 'monospace' : 'Courier' }]}>
|
|
1332
1367
|
{openedFile.id}
|
|
1333
1368
|
</Text>
|
|
1334
1369
|
</View>
|
|
@@ -1336,7 +1371,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1336
1371
|
|
|
1337
1372
|
<View style={styles.fileDetailsActions}>
|
|
1338
1373
|
<TouchableOpacity
|
|
1339
|
-
style={[styles.fileDetailsActionButton, { backgroundColor: primaryColor }]}
|
|
1374
|
+
style={[styles.fileDetailsActionButton, { backgroundColor: themeStyles.primaryColor }]}
|
|
1340
1375
|
onPress={() => handleFileDownload(openedFile.id, openedFile.filename)}
|
|
1341
1376
|
>
|
|
1342
1377
|
<Ionicons name="download" size={16} color="#FFFFFF" />
|
|
@@ -1345,7 +1380,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1345
1380
|
|
|
1346
1381
|
{(user?.id === targetUserId) && (
|
|
1347
1382
|
<TouchableOpacity
|
|
1348
|
-
style={[styles.fileDetailsActionButton, { backgroundColor: dangerColor }]}
|
|
1383
|
+
style={[styles.fileDetailsActionButton, { backgroundColor: themeStyles.dangerColor }]}
|
|
1349
1384
|
onPress={() => {
|
|
1350
1385
|
handleCloseFile();
|
|
1351
1386
|
handleFileDelete(openedFile.id, openedFile.filename);
|
|
@@ -1369,8 +1404,8 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1369
1404
|
>
|
|
1370
1405
|
{loadingFileContent ? (
|
|
1371
1406
|
<View style={styles.fileViewerLoading}>
|
|
1372
|
-
<ActivityIndicator size="large" color={primaryColor} />
|
|
1373
|
-
<Text style={[styles.fileViewerLoadingText, { color: textColor }]}>
|
|
1407
|
+
<ActivityIndicator size="large" color={themeStyles.primaryColor} />
|
|
1408
|
+
<Text style={[styles.fileViewerLoadingText, { color: themeStyles.textColor }]}>
|
|
1374
1409
|
Loading file content...
|
|
1375
1410
|
</Text>
|
|
1376
1411
|
</View>
|
|
@@ -1406,9 +1441,9 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1406
1441
|
)}
|
|
1407
1442
|
</View>
|
|
1408
1443
|
) : isText && fileContent ? (
|
|
1409
|
-
<View style={[styles.textContainer, { backgroundColor: secondaryBackgroundColor, borderColor }]}>
|
|
1444
|
+
<View style={[styles.textContainer, { backgroundColor: themeStyles.secondaryBackgroundColor, borderColor }]}>
|
|
1410
1445
|
<ScrollView style={{ flex: 1 }} nestedScrollEnabled>
|
|
1411
|
-
<Text style={[styles.textContent, { color: textColor }]}>
|
|
1446
|
+
<Text style={[styles.textContent, { color: themeStyles.textColor }]}>
|
|
1412
1447
|
{fileContent}
|
|
1413
1448
|
</Text>
|
|
1414
1449
|
</ScrollView>
|
|
@@ -1438,7 +1473,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1438
1473
|
Your browser does not support the video tag.
|
|
1439
1474
|
</video>
|
|
1440
1475
|
) : (
|
|
1441
|
-
<Text style={[styles.unsupportedText, { color: textColor }]}>
|
|
1476
|
+
<Text style={[styles.unsupportedText, { color: themeStyles.textColor }]}>
|
|
1442
1477
|
Video playback not supported on mobile
|
|
1443
1478
|
</Text>
|
|
1444
1479
|
)}
|
|
@@ -1457,7 +1492,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1457
1492
|
Your browser does not support the audio tag.
|
|
1458
1493
|
</audio>
|
|
1459
1494
|
) : (
|
|
1460
|
-
<Text style={[styles.unsupportedText, { color: textColor }]}>
|
|
1495
|
+
<Text style={[styles.unsupportedText, { color: themeStyles.textColor }]}>
|
|
1461
1496
|
Audio playback not supported on mobile
|
|
1462
1497
|
</Text>
|
|
1463
1498
|
)}
|
|
@@ -1467,17 +1502,17 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1467
1502
|
<Ionicons
|
|
1468
1503
|
name={getFileIcon(openedFile.contentType) as any}
|
|
1469
1504
|
size={64}
|
|
1470
|
-
color={isDarkTheme ? '#666666' : '#CCCCCC'}
|
|
1505
|
+
color={themeStyles.isDarkTheme ? '#666666' : '#CCCCCC'}
|
|
1471
1506
|
/>
|
|
1472
|
-
<Text style={[styles.unsupportedFileTitle, { color: textColor }]}>
|
|
1507
|
+
<Text style={[styles.unsupportedFileTitle, { color: themeStyles.textColor }]}>
|
|
1473
1508
|
Preview Not Available
|
|
1474
1509
|
</Text>
|
|
1475
|
-
<Text style={[styles.unsupportedFileDescription, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1510
|
+
<Text style={[styles.unsupportedFileDescription, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1476
1511
|
This file type cannot be previewed in the browser.{'\n'}
|
|
1477
1512
|
Download the file to view its contents.
|
|
1478
1513
|
</Text>
|
|
1479
1514
|
<TouchableOpacity
|
|
1480
|
-
style={[styles.downloadButtonLarge, { backgroundColor: primaryColor }]}
|
|
1515
|
+
style={[styles.downloadButtonLarge, { backgroundColor: themeStyles.primaryColor }]}
|
|
1481
1516
|
onPress={() => handleFileDownload(openedFile.id, openedFile.filename)}
|
|
1482
1517
|
>
|
|
1483
1518
|
<Ionicons name="download" size={20} color="#FFFFFF" />
|
|
@@ -1492,9 +1527,9 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1492
1527
|
|
|
1493
1528
|
const renderEmptyState = () => (
|
|
1494
1529
|
<View style={styles.emptyState}>
|
|
1495
|
-
<Ionicons name="folder-open-outline" size={64} color={isDarkTheme ? '#666666' : '#CCCCCC'} />
|
|
1496
|
-
<Text style={[styles.emptyStateTitle, { color: textColor }]}>No Files Yet</Text>
|
|
1497
|
-
<Text style={[styles.emptyStateDescription, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1530
|
+
<Ionicons name="folder-open-outline" size={64} color={themeStyles.isDarkTheme ? '#666666' : '#CCCCCC'} />
|
|
1531
|
+
<Text style={[styles.emptyStateTitle, { color: themeStyles.textColor }]}>No Files Yet</Text>
|
|
1532
|
+
<Text style={[styles.emptyStateDescription, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1498
1533
|
{user?.id === targetUserId
|
|
1499
1534
|
? `Upload files to get started. You can select multiple files at once${Platform.OS === 'web' ? ' or drag & drop them here.' : '.'}`
|
|
1500
1535
|
: "This user hasn't uploaded any files yet"
|
|
@@ -1502,7 +1537,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1502
1537
|
</Text>
|
|
1503
1538
|
{user?.id === targetUserId && (
|
|
1504
1539
|
<TouchableOpacity
|
|
1505
|
-
style={[styles.emptyStateButton, { backgroundColor: primaryColor }]}
|
|
1540
|
+
style={[styles.emptyStateButton, { backgroundColor: themeStyles.primaryColor }]}
|
|
1506
1541
|
onPress={handleFileUpload}
|
|
1507
1542
|
disabled={uploading}
|
|
1508
1543
|
>
|
|
@@ -1522,8 +1557,8 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1522
1557
|
if (loading) {
|
|
1523
1558
|
return (
|
|
1524
1559
|
<View style={[styles.container, styles.centerContent, { backgroundColor }]}>
|
|
1525
|
-
<ActivityIndicator size="large" color={primaryColor} />
|
|
1526
|
-
<Text style={[styles.loadingText, { color: textColor }]}>Loading files...</Text>
|
|
1560
|
+
<ActivityIndicator size="large" color={themeStyles.primaryColor} />
|
|
1561
|
+
<Text style={[styles.loadingText, { color: themeStyles.textColor }]}>Loading files...</Text>
|
|
1527
1562
|
</View>
|
|
1528
1563
|
);
|
|
1529
1564
|
}
|
|
@@ -1556,13 +1591,13 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1556
1591
|
styles.header,
|
|
1557
1592
|
{
|
|
1558
1593
|
borderBottomColor: borderColor,
|
|
1559
|
-
backgroundColor: isDarkTheme ? '#1A1A1A' : '#FFFFFF',
|
|
1594
|
+
backgroundColor: themeStyles.isDarkTheme ? '#1A1A1A' : '#FFFFFF',
|
|
1560
1595
|
shadowColor: '#000000',
|
|
1561
1596
|
shadowOffset: {
|
|
1562
1597
|
width: 0,
|
|
1563
1598
|
height: 2,
|
|
1564
1599
|
},
|
|
1565
|
-
shadowOpacity: isDarkTheme ? 0.3 : 0.1,
|
|
1600
|
+
shadowOpacity: themeStyles.isDarkTheme ? 0.3 : 0.1,
|
|
1566
1601
|
shadowRadius: 8,
|
|
1567
1602
|
elevation: 4,
|
|
1568
1603
|
}
|
|
@@ -1571,20 +1606,20 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1571
1606
|
style={[
|
|
1572
1607
|
styles.backButton,
|
|
1573
1608
|
{
|
|
1574
|
-
backgroundColor: isDarkTheme ? '#2A2A2A' : '#F8F9FA',
|
|
1609
|
+
backgroundColor: themeStyles.isDarkTheme ? '#2A2A2A' : '#F8F9FA',
|
|
1575
1610
|
borderRadius: 12,
|
|
1576
1611
|
}
|
|
1577
1612
|
]}
|
|
1578
1613
|
onPress={onClose || goBack}
|
|
1579
1614
|
>
|
|
1580
|
-
<Ionicons name="arrow-back" size={22} color={textColor} />
|
|
1615
|
+
<Ionicons name="arrow-back" size={22} color={themeStyles.textColor} />
|
|
1581
1616
|
</TouchableOpacity>
|
|
1582
1617
|
|
|
1583
1618
|
<View style={styles.headerTitleContainer}>
|
|
1584
|
-
<Text style={[styles.headerTitle, { color: textColor }]}>
|
|
1619
|
+
<Text style={[styles.headerTitle, { color: themeStyles.textColor }]}>
|
|
1585
1620
|
{viewMode === 'photos' ? 'Photos' : 'File Management'}
|
|
1586
1621
|
</Text>
|
|
1587
|
-
<Text style={[styles.headerSubtitle, { color: isDarkTheme ? '#AAAAAA' : '#666666' }]}>
|
|
1622
|
+
<Text style={[styles.headerSubtitle, { color: themeStyles.isDarkTheme ? '#AAAAAA' : '#666666' }]}>
|
|
1588
1623
|
{filteredFiles.length} {filteredFiles.length === 1 ? 'item' : 'items'}
|
|
1589
1624
|
</Text>
|
|
1590
1625
|
</View>
|
|
@@ -1594,15 +1629,15 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1594
1629
|
<View style={[
|
|
1595
1630
|
styles.viewModeToggle,
|
|
1596
1631
|
{
|
|
1597
|
-
backgroundColor: isDarkTheme ? '#2A2A2A' : '#F8F9FA',
|
|
1632
|
+
backgroundColor: themeStyles.isDarkTheme ? '#2A2A2A' : '#F8F9FA',
|
|
1598
1633
|
borderWidth: 1,
|
|
1599
|
-
borderColor: isDarkTheme ? '#3A3A3A' : '#E8E9EA',
|
|
1634
|
+
borderColor: themeStyles.isDarkTheme ? '#3A3A3A' : '#E8E9EA',
|
|
1600
1635
|
shadowColor: '#000000',
|
|
1601
1636
|
shadowOffset: {
|
|
1602
1637
|
width: 0,
|
|
1603
1638
|
height: 1,
|
|
1604
1639
|
},
|
|
1605
|
-
shadowOpacity: isDarkTheme ? 0.3 : 0.05,
|
|
1640
|
+
shadowOpacity: themeStyles.isDarkTheme ? 0.3 : 0.05,
|
|
1606
1641
|
shadowRadius: 4,
|
|
1607
1642
|
elevation: 2,
|
|
1608
1643
|
}
|
|
@@ -1611,8 +1646,8 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1611
1646
|
style={[
|
|
1612
1647
|
styles.viewModeButton,
|
|
1613
1648
|
viewMode === 'all' && {
|
|
1614
|
-
backgroundColor: primaryColor,
|
|
1615
|
-
shadowColor: primaryColor,
|
|
1649
|
+
backgroundColor: themeStyles.primaryColor,
|
|
1650
|
+
shadowColor: themeStyles.primaryColor,
|
|
1616
1651
|
shadowOffset: {
|
|
1617
1652
|
width: 0,
|
|
1618
1653
|
height: 2,
|
|
@@ -1627,15 +1662,15 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1627
1662
|
<Ionicons
|
|
1628
1663
|
name="folder"
|
|
1629
1664
|
size={18}
|
|
1630
|
-
color={viewMode === 'all' ? '#FFFFFF' : textColor}
|
|
1665
|
+
color={viewMode === 'all' ? '#FFFFFF' : themeStyles.textColor}
|
|
1631
1666
|
/>
|
|
1632
1667
|
</TouchableOpacity>
|
|
1633
1668
|
<TouchableOpacity
|
|
1634
1669
|
style={[
|
|
1635
1670
|
styles.viewModeButton,
|
|
1636
1671
|
viewMode === 'photos' && {
|
|
1637
|
-
backgroundColor: primaryColor,
|
|
1638
|
-
shadowColor: primaryColor,
|
|
1672
|
+
backgroundColor: themeStyles.primaryColor,
|
|
1673
|
+
shadowColor: themeStyles.primaryColor,
|
|
1639
1674
|
shadowOffset: {
|
|
1640
1675
|
width: 0,
|
|
1641
1676
|
height: 2,
|
|
@@ -1650,7 +1685,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1650
1685
|
<Ionicons
|
|
1651
1686
|
name="images"
|
|
1652
1687
|
size={18}
|
|
1653
|
-
color={viewMode === 'photos' ? '#FFFFFF' : textColor}
|
|
1688
|
+
color={viewMode === 'photos' ? '#FFFFFF' : themeStyles.textColor}
|
|
1654
1689
|
/>
|
|
1655
1690
|
</TouchableOpacity>
|
|
1656
1691
|
</View>
|
|
@@ -1660,8 +1695,8 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1660
1695
|
style={[
|
|
1661
1696
|
styles.uploadButton,
|
|
1662
1697
|
{
|
|
1663
|
-
backgroundColor: primaryColor,
|
|
1664
|
-
shadowColor: primaryColor,
|
|
1698
|
+
backgroundColor: themeStyles.primaryColor,
|
|
1699
|
+
shadowColor: themeStyles.primaryColor,
|
|
1665
1700
|
shadowOffset: {
|
|
1666
1701
|
width: 0,
|
|
1667
1702
|
height: 3,
|
|
@@ -1697,23 +1732,23 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1697
1732
|
<View style={[
|
|
1698
1733
|
styles.searchContainer,
|
|
1699
1734
|
{
|
|
1700
|
-
backgroundColor: isDarkTheme ? '#1A1A1A' : '#FFFFFF',
|
|
1701
|
-
borderColor: isDarkTheme ? '#3A3A3A' : '#E8E9EA',
|
|
1735
|
+
backgroundColor: themeStyles.isDarkTheme ? '#1A1A1A' : '#FFFFFF',
|
|
1736
|
+
borderColor: themeStyles.isDarkTheme ? '#3A3A3A' : '#E8E9EA',
|
|
1702
1737
|
shadowColor: '#000000',
|
|
1703
1738
|
shadowOffset: {
|
|
1704
1739
|
width: 0,
|
|
1705
1740
|
height: 1,
|
|
1706
1741
|
},
|
|
1707
|
-
shadowOpacity: isDarkTheme ? 0.2 : 0.05,
|
|
1742
|
+
shadowOpacity: themeStyles.isDarkTheme ? 0.2 : 0.05,
|
|
1708
1743
|
shadowRadius: 4,
|
|
1709
1744
|
elevation: 2,
|
|
1710
1745
|
}
|
|
1711
1746
|
]}>
|
|
1712
|
-
<Ionicons name="search" size={22} color={isDarkTheme ? '#888888' : '#666666'} />
|
|
1747
|
+
<Ionicons name="search" size={22} color={themeStyles.isDarkTheme ? '#888888' : '#666666'} />
|
|
1713
1748
|
<TextInput
|
|
1714
|
-
style={[styles.searchInput, { color: textColor }]}
|
|
1749
|
+
style={[styles.searchInput, { color: themeStyles.textColor }]}
|
|
1715
1750
|
placeholder={viewMode === 'photos' ? 'Search photos...' : 'Search files...'}
|
|
1716
|
-
placeholderTextColor={isDarkTheme ? '#888888' : '#999999'}
|
|
1751
|
+
placeholderTextColor={themeStyles.isDarkTheme ? '#888888' : '#999999'}
|
|
1717
1752
|
value={searchQuery}
|
|
1718
1753
|
onChangeText={setSearchQuery}
|
|
1719
1754
|
/>
|
|
@@ -1722,7 +1757,7 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1722
1757
|
onPress={() => setSearchQuery('')}
|
|
1723
1758
|
style={styles.searchClearButton}
|
|
1724
1759
|
>
|
|
1725
|
-
<Ionicons name="close-circle" size={22} color={isDarkTheme ? '#888888' : '#666666'} />
|
|
1760
|
+
<Ionicons name="close-circle" size={22} color={themeStyles.isDarkTheme ? '#888888' : '#666666'} />
|
|
1726
1761
|
</TouchableOpacity>
|
|
1727
1762
|
)}
|
|
1728
1763
|
</View>
|
|
@@ -1733,36 +1768,36 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1733
1768
|
<View style={[
|
|
1734
1769
|
styles.statsContainer,
|
|
1735
1770
|
{
|
|
1736
|
-
backgroundColor: isDarkTheme ? '#1A1A1A' : '#FFFFFF',
|
|
1737
|
-
borderColor: isDarkTheme ? '#3A3A3A' : '#E8E9EA',
|
|
1771
|
+
backgroundColor: themeStyles.isDarkTheme ? '#1A1A1A' : '#FFFFFF',
|
|
1772
|
+
borderColor: themeStyles.isDarkTheme ? '#3A3A3A' : '#E8E9EA',
|
|
1738
1773
|
shadowColor: '#000000',
|
|
1739
1774
|
shadowOffset: {
|
|
1740
1775
|
width: 0,
|
|
1741
1776
|
height: 1,
|
|
1742
1777
|
},
|
|
1743
|
-
shadowOpacity: isDarkTheme ? 0.2 : 0.05,
|
|
1778
|
+
shadowOpacity: themeStyles.isDarkTheme ? 0.2 : 0.05,
|
|
1744
1779
|
shadowRadius: 4,
|
|
1745
1780
|
elevation: 2,
|
|
1746
1781
|
}
|
|
1747
1782
|
]}>
|
|
1748
1783
|
<View style={styles.statItem}>
|
|
1749
|
-
<Text style={[styles.statValue, { color: textColor }]}>{filteredFiles.length}</Text>
|
|
1750
|
-
<Text style={[styles.statLabel, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1784
|
+
<Text style={[styles.statValue, { color: themeStyles.textColor }]}>{filteredFiles.length}</Text>
|
|
1785
|
+
<Text style={[styles.statLabel, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1751
1786
|
{searchQuery.length > 0 ? 'Found' : (filteredFiles.length === 1 ? (viewMode === 'photos' ? 'Photo' : 'File') : (viewMode === 'photos' ? 'Photos' : 'Files'))}
|
|
1752
1787
|
</Text>
|
|
1753
1788
|
</View>
|
|
1754
1789
|
<View style={styles.statItem}>
|
|
1755
|
-
<Text style={[styles.statValue, { color: textColor }]}>
|
|
1790
|
+
<Text style={[styles.statValue, { color: themeStyles.textColor }]}>
|
|
1756
1791
|
{formatFileSize(filteredFiles.reduce((total, file) => total + file.length, 0))}
|
|
1757
1792
|
</Text>
|
|
1758
|
-
<Text style={[styles.statLabel, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1793
|
+
<Text style={[styles.statLabel, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1759
1794
|
{searchQuery.length > 0 ? 'Size' : 'Total Size'}
|
|
1760
1795
|
</Text>
|
|
1761
1796
|
</View>
|
|
1762
1797
|
{searchQuery.length > 0 && (
|
|
1763
1798
|
<View style={styles.statItem}>
|
|
1764
|
-
<Text style={[styles.statValue, { color: textColor }]}>{files.length}</Text>
|
|
1765
|
-
<Text style={[styles.statLabel, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1799
|
+
<Text style={[styles.statValue, { color: themeStyles.textColor }]}>{files.length}</Text>
|
|
1800
|
+
<Text style={[styles.statLabel, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1766
1801
|
Total
|
|
1767
1802
|
</Text>
|
|
1768
1803
|
</View>
|
|
@@ -1781,19 +1816,19 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1781
1816
|
<RefreshControl
|
|
1782
1817
|
refreshing={refreshing}
|
|
1783
1818
|
onRefresh={() => loadFiles(true)}
|
|
1784
|
-
tintColor={primaryColor}
|
|
1819
|
+
tintColor={themeStyles.primaryColor}
|
|
1785
1820
|
/>
|
|
1786
1821
|
}
|
|
1787
1822
|
>
|
|
1788
1823
|
{filteredFiles.length === 0 && searchQuery.length > 0 ? (
|
|
1789
1824
|
<View style={styles.emptyState}>
|
|
1790
|
-
<Ionicons name="search" size={64} color={isDarkTheme ? '#666666' : '#CCCCCC'} />
|
|
1791
|
-
<Text style={[styles.emptyStateTitle, { color: textColor }]}>No Results Found</Text>
|
|
1792
|
-
<Text style={[styles.emptyStateDescription, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1825
|
+
<Ionicons name="search" size={64} color={themeStyles.isDarkTheme ? '#666666' : '#CCCCCC'} />
|
|
1826
|
+
<Text style={[styles.emptyStateTitle, { color: themeStyles.textColor }]}>No Results Found</Text>
|
|
1827
|
+
<Text style={[styles.emptyStateDescription, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1793
1828
|
No files match your search for "{searchQuery}"
|
|
1794
1829
|
</Text>
|
|
1795
1830
|
<TouchableOpacity
|
|
1796
|
-
style={[styles.emptyStateButton, { backgroundColor: primaryColor }]}
|
|
1831
|
+
style={[styles.emptyStateButton, { backgroundColor: themeStyles.primaryColor }]}
|
|
1797
1832
|
onPress={() => setSearchQuery('')}
|
|
1798
1833
|
>
|
|
1799
1834
|
<Ionicons name="refresh" size={20} color="#FFFFFF" />
|
|
@@ -1814,11 +1849,11 @@ const FileManagementScreen: React.FC<FileManagementScreenProps> = ({
|
|
|
1814
1849
|
{isDragging && Platform.OS === 'web' && (
|
|
1815
1850
|
<View style={styles.dragDropOverlay}>
|
|
1816
1851
|
<View style={styles.dragDropContent}>
|
|
1817
|
-
<Ionicons name="cloud-upload" size={64} color={primaryColor} />
|
|
1818
|
-
<Text style={[styles.dragDropTitle, { color: primaryColor }]}>
|
|
1852
|
+
<Ionicons name="cloud-upload" size={64} color={themeStyles.primaryColor} />
|
|
1853
|
+
<Text style={[styles.dragDropTitle, { color: themeStyles.primaryColor }]}>
|
|
1819
1854
|
Drop files to upload
|
|
1820
1855
|
</Text>
|
|
1821
|
-
<Text style={[styles.dragDropSubtitle, { color: isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1856
|
+
<Text style={[styles.dragDropSubtitle, { color: themeStyles.isDarkTheme ? '#BBBBBB' : '#666666' }]}>
|
|
1822
1857
|
Release to upload{uploadProgress ? ` (${uploadProgress.current}/${uploadProgress.total})` : ' multiple files'}
|
|
1823
1858
|
</Text>
|
|
1824
1859
|
</View>
|