fix files details

This commit is contained in:
m
2026-07-29 18:14:35 +02:00
parent 7cc425d28b
commit e8a5c02620
2 changed files with 42 additions and 21 deletions
+38 -19
View File
@@ -1,4 +1,4 @@
import React, { useRef, useState, useCallback } from 'react'; import React, { useRef, useState, useCallback, useEffect } from 'react';
import { import {
View, View,
Text, Text,
@@ -44,19 +44,31 @@ type FileDetailRouteProp = RouteProp<RootStackParamList, 'FileDetail'>;
function DetailItem({ fileId, deviceFile, onSelectImage }: { fileId: string; deviceFile?: DeviceFileParam; onSelectImage?: (state: ModalState) => void }) { function DetailItem({ fileId, deviceFile, onSelectImage }: { fileId: string; deviceFile?: DeviceFileParam; onSelectImage?: (state: ModalState) => void }) {
const isDevice = !!deviceFile; const isDevice = !!deviceFile;
const { data: fileData } = useFile(isDevice ? '' : fileId);
const localEntry = fileStore.getById(fileId);
const apiId = isDevice ? '' : (localEntry?.backendId ?? fileId);
const { data: fileData } = useFile(apiId);
const downloadFile = useDownloadFile(); const downloadFile = useDownloadFile();
const [downloading, setDownloading] = useState(false); const [downloading, setDownloading] = useState(false);
const file = fileData as any; const file = fileData as any;
const uri = isDevice ? deviceFile.localUri : file?.url; const uri = isDevice ? deviceFile.localUri : (localEntry?.localUri ?? file?.url);
const [imageSize, setImageSize] = useState<{ width: number; height: number } | null>(null);
useEffect(() => {
if (!uri) { setImageSize(null); return; }
Image.getSize(
uri,
(w, h) => setImageSize({ width: w, height: h }),
() => setImageSize(null),
);
}, [uri]);
const localEntry = fileStore.getByBackendId(fileId);
const syncStatus: SyncStatus = isDevice const syncStatus: SyncStatus = isDevice
? 'local' ? 'local'
: localEntry : localEntry
? (localEntry.syncStatus === 'cloud' ? 'cloud' : 'synced') ? (localEntry.syncStatus as SyncStatus)
: (uri ? 'synced' : 'cloud'); : 'cloud';
const fullVariants: Variant[] = (file?.variants ?? []) const fullVariants: Variant[] = (file?.variants ?? [])
.filter((v: Variant) => v.variantType === 'thumbnail_full') .filter((v: Variant) => v.variantType === 'thumbnail_full')
@@ -67,15 +79,16 @@ function DetailItem({ fileId, deviceFile, onSelectImage }: { fileId: string; dev
const handleDownload = useCallback(async () => { const handleDownload = useCallback(async () => {
if (!file) return; if (!file) return;
const bid = localEntry?.backendId ?? fileId;
setDownloading(true); setDownloading(true);
try { try {
await downloadFile.mutateAsync({ await downloadFile.mutateAsync({
id: fileId, id: bid,
backendResourceId: fileId, backendResourceId: bid,
name: file?.name ?? fileId, name: file?.name ?? localEntry?.name ?? fileId,
mimeType: file?.mimeType ?? 'application/octet-stream', mimeType: file?.mimeType ?? localEntry?.mimeType ?? 'application/octet-stream',
size: file?.size ?? 0, size: file?.size ?? localEntry?.size ?? 0,
createdAt: file?.createdAt ?? new Date().toISOString(), createdAt: file?.createdAt ?? localEntry?.createdAt ?? new Date().toISOString(),
source: 'cloud', source: 'cloud',
syncStatus: 'cloud', syncStatus: 'cloud',
tags: file?.tags ?? [], tags: file?.tags ?? [],
@@ -84,7 +97,7 @@ function DetailItem({ fileId, deviceFile, onSelectImage }: { fileId: string; dev
} catch {} finally { } catch {} finally {
setDownloading(false); setDownloading(false);
} }
}, [file, fileId, downloadFile]); }, [file, fileId, localEntry, downloadFile]);
return ( return (
<ScrollView style={styles.page} contentContainerStyle={styles.pageContent}> <ScrollView style={styles.page} contentContainerStyle={styles.pageContent}>
@@ -113,9 +126,19 @@ function DetailItem({ fileId, deviceFile, onSelectImage }: { fileId: string; dev
<View style={styles.imageContainer}> <View style={styles.imageContainer}>
{uri ? ( {uri ? (
<Pressable <Pressable
onPress={() => onSelectImage?.({ images: [{ uri, width: SCREEN_WIDTH, height: SCREEN_WIDTH }], index: 0 })} onPress={() => onSelectImage?.({
images: [{ uri, width: SCREEN_WIDTH, height: imageSize ? imageSize.height * SCREEN_WIDTH / imageSize.width : SCREEN_WIDTH }],
index: 0,
})}
> >
<Image source={{ uri }} style={styles.image} resizeMode="contain" /> <Image
source={{ uri }}
style={[
styles.image,
imageSize && { height: imageSize.height * SCREEN_WIDTH / imageSize.width },
]}
resizeMode="contain"
/>
</Pressable> </Pressable>
) : file ? ( ) : file ? (
<View style={styles.cloudOnlyContainer}> <View style={styles.cloudOnlyContainer}>
@@ -289,14 +312,10 @@ const styles = StyleSheet.create({
flexGrow: 1, flexGrow: 1,
}, },
imageContainer: { imageContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#000', backgroundColor: '#000',
}, },
image: { image: {
width: SCREEN_WIDTH, width: SCREEN_WIDTH,
height: SCREEN_WIDTH,
}, },
pageImageContainer: { pageImageContainer: {
alignItems: 'center', alignItems: 'center',
+4 -2
View File
@@ -407,13 +407,15 @@ export const fileStore = {
for (const bf of backendFiles) { for (const bf of backendFiles) {
const existing = d.select().from(files).where(eq(files.backendId, bf.id)).get() as FileRow | undefined; const existing = d.select().from(files).where(eq(files.backendId, bf.id)).get() as FileRow | undefined;
const recordId = existing?.id ?? bf.id;
const source = existing && existing.localUri ? 'synced' : 'cloud'; const source = existing && existing.localUri ? 'synced' : 'cloud';
const syncStatus = existing && existing.localUri const syncStatus = existing && existing.localUri
? (existing.syncStatus === 'cloud' ? 'synced' : existing.syncStatus) ? (existing.syncStatus === 'cloud' ? 'synced' : existing.syncStatus)
: 'cloud'; : 'cloud';
upsertRow({ upsertRow({
id: bf.id, id: recordId,
backendId: bf.id, backendId: bf.id,
name: bf.name, name: bf.name,
mimeType: bf.mimeType, mimeType: bf.mimeType,
@@ -431,7 +433,7 @@ export const fileStore = {
lastSyncedAt: now, lastSyncedAt: now,
}); });
if (bf.tags && bf.tags.length > 0) setTagsForFile(bf.id, bf.tags); if (bf.tags && bf.tags.length > 0) setTagsForFile(recordId, bf.tags);
} }
}); });
}, },