mirror of
https://github.com/mudabbir-ahmad/Media-Aggregation-and-Sorting-System.git
synced 2026-10-08 03:40:20 +00:00
refactored code into components (major cleanup for reused code) added email for local acccount creation and changes to how nas and google photo connections work and added themes
This commit is contained in:
1 parent
c1d7139055
commit
6f4ec66e2e
17 files changed
+1761
-1018
No files matched your search
@@ -0,0 +1,83 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
View, Text, FlatList, TouchableOpacity, Image, Dimensions, StyleSheet,
|
||||
} from 'react-native';
|
||||
import { useTheme } from '../services/ThemeContext';
|
||||
|
||||
const { width } = Dimensions.get('window');
|
||||
const GRID_GAP = 2;
|
||||
|
||||
const PhotoGrid = ({
|
||||
data,
|
||||
onItemPress,
|
||||
columns = 3,
|
||||
refreshControl,
|
||||
ListHeaderComponent,
|
||||
ListEmptyComponent,
|
||||
}) => {
|
||||
const { theme } = useTheme();
|
||||
const itemSize = (width - GRID_GAP * (columns + 1)) / columns;
|
||||
|
||||
const getServiceIcon = (type) =>
|
||||
({ GOOGLE_PHOTOS: '📷', ICLOUD_PHOTOS: '🍎', NAS: '💾' }[type] || '📱');
|
||||
|
||||
const renderItem = ({ item }) => (
|
||||
<TouchableOpacity
|
||||
style={[styles.gridItem, { width: itemSize, height: itemSize, backgroundColor: theme.chipBg }]}
|
||||
onPress={() => onItemPress?.(item)}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
{item.local_path ? (
|
||||
<Image source={{ uri: item.local_path }} style={styles.gridImage} resizeMode="cover" />
|
||||
) : (
|
||||
<View style={[styles.placeholder, { backgroundColor: theme.borderLight }]}>
|
||||
<Text style={{ fontSize: 28 }}>📷</Text>
|
||||
</View>
|
||||
)}
|
||||
{item.media_type === 'video' && (
|
||||
<View style={styles.videoOverlay}>
|
||||
<Text style={{ color: '#fff', fontSize: 20 }}>▶</Text>
|
||||
</View>
|
||||
)}
|
||||
<View style={styles.sourceBadge}>
|
||||
<Text style={{ fontSize: 10 }}>{getServiceIcon(item.source_service)}</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
||||
return (
|
||||
<FlatList
|
||||
data={data}
|
||||
renderItem={renderItem}
|
||||
keyExtractor={(item, i) => item.id?.toString() || item.source_id || i.toString()}
|
||||
numColumns={columns}
|
||||
contentContainerStyle={styles.gridContent}
|
||||
refreshControl={refreshControl}
|
||||
ListHeaderComponent={ListHeaderComponent}
|
||||
ListEmptyComponent={ListEmptyComponent}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
gridContent: { paddingBottom: 20 },
|
||||
gridItem: {
|
||||
margin: GRID_GAP / 2,
|
||||
position: 'relative',
|
||||
},
|
||||
gridImage: { width: '100%', height: '100%' },
|
||||
placeholder: {
|
||||
width: '100%', height: '100%', justifyContent: 'center', alignItems: 'center',
|
||||
},
|
||||
videoOverlay: {
|
||||
position: 'absolute', top: 0, left: 0, right: 0, bottom: 0,
|
||||
backgroundColor: 'rgba(0,0,0,0.25)', justifyContent: 'center', alignItems: 'center',
|
||||
},
|
||||
sourceBadge: {
|
||||
position: 'absolute', bottom: 4, right: 4, backgroundColor: 'rgba(0,0,0,0.5)',
|
||||
borderRadius: 8, paddingHorizontal: 4, paddingVertical: 2,
|
||||
},
|
||||
});
|
||||
|
||||
export default PhotoGrid;
|
||||
|
||||
Reference in new issue
Block a user