load local files

This commit is contained in:
m
2026-07-27 15:52:51 +02:00
parent 8efa1e18c2
commit 0cc261105a
13 changed files with 737 additions and 45 deletions
+11 -2
View File
@@ -2,6 +2,8 @@ import React from 'react';
import { View, Text, Image, ActivityIndicator, StyleSheet } from 'react-native';
import { MaterialIcons } from '@expo/vector-icons';
import type { ComponentProps } from 'react';
import { SyncStatusBadge } from './SyncStatusBadge';
import type { SyncStatus } from '../types';
type IconName = ComponentProps<typeof MaterialIcons>['name'];
@@ -35,9 +37,10 @@ interface FileThumbnailProps {
fileName: string;
size: number;
isLoading?: boolean;
syncStatus?: SyncStatus;
}
export function FileThumbnail({ uri, thumbnailUrl, mimeType, fileName, size, isLoading }: FileThumbnailProps) {
export function FileThumbnail({ uri, thumbnailUrl, mimeType, fileName, size, isLoading, syncStatus }: FileThumbnailProps) {
const info = getFileInfo(mimeType, fileName);
const ext = getExtension(fileName);
@@ -52,7 +55,12 @@ export function FileThumbnail({ uri, thumbnailUrl, mimeType, fileName, size, isL
const imageUri = thumbnailUrl || (uri && mimeType.startsWith('image/') ? uri : undefined);
if (imageUri) {
return <Image source={{ uri: imageUri }} style={[styles.image, { width: size, height: size }]} />;
return (
<View style={{ width: size, height: size }}>
<Image source={{ uri: imageUri }} style={[styles.image, { width: size, height: size }]} />
{syncStatus && <SyncStatusBadge status={syncStatus} />}
</View>
);
}
return (
@@ -61,6 +69,7 @@ export function FileThumbnail({ uri, thumbnailUrl, mimeType, fileName, size, isL
{ext.length <= 4 && (
<Text style={[styles.ext, { color: info.color }]}>{ext}</Text>
)}
{syncStatus && <SyncStatusBadge status={syncStatus} />}
</View>
);
}
+38
View File
@@ -0,0 +1,38 @@
import React from 'react';
import { View, StyleSheet } from 'react-native';
import { MaterialIcons } from '@expo/vector-icons';
import { SyncStatus } from '../types';
interface SyncStatusBadgeProps {
status: SyncStatus;
size?: number;
}
const STATUS_CONFIG: Record<SyncStatus, { icon: string; color: string; bg: string }> = {
local: { icon: 'phone-android', color: '#757575', bg: 'rgba(245,245,245,0.9)' },
synced: { icon: 'sync', color: '#4CAF50', bg: 'rgba(232,245,233,0.9)' },
cloud: { icon: 'cloud', color: '#1976D2', bg: 'rgba(227,242,253,0.9)' },
};
export function SyncStatusBadge({ status, size = 16 }: SyncStatusBadgeProps) {
const config = STATUS_CONFIG[status];
const iconSize = Math.round(size * 0.7);
return (
<View style={[styles.badge, { width: size, height: size, borderRadius: size / 2, backgroundColor: config.bg }]}>
<MaterialIcons name={config.icon as any} size={iconSize} color={config.color} />
</View>
);
}
const styles = StyleSheet.create({
badge: {
position: 'absolute',
top: 2,
right: 2,
justifyContent: 'center',
alignItems: 'center',
borderWidth: 0.5,
borderColor: 'rgba(0,0,0,0.1)',
},
});