From e8a5c0262063b278be3b2ba18e644e4b5393a4a6 Mon Sep 17 00:00:00 2001 From: m Date: Wed, 29 Jul 2026 18:14:35 +0200 Subject: [PATCH] fix files details --- mobile/app/file-detail.tsx | 57 ++++++++++++++++++++---------- mobile/services/fileStore/index.ts | 6 ++-- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/mobile/app/file-detail.tsx b/mobile/app/file-detail.tsx index 93c6e53..05e4f00 100644 --- a/mobile/app/file-detail.tsx +++ b/mobile/app/file-detail.tsx @@ -1,4 +1,4 @@ -import React, { useRef, useState, useCallback } from 'react'; +import React, { useRef, useState, useCallback, useEffect } from 'react'; import { View, Text, @@ -44,19 +44,31 @@ type FileDetailRouteProp = RouteProp; function DetailItem({ fileId, deviceFile, onSelectImage }: { fileId: string; deviceFile?: DeviceFileParam; onSelectImage?: (state: ModalState) => void }) { 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 [downloading, setDownloading] = useState(false); 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 ? 'local' : localEntry - ? (localEntry.syncStatus === 'cloud' ? 'cloud' : 'synced') - : (uri ? 'synced' : 'cloud'); + ? (localEntry.syncStatus as SyncStatus) + : 'cloud'; const fullVariants: Variant[] = (file?.variants ?? []) .filter((v: Variant) => v.variantType === 'thumbnail_full') @@ -67,15 +79,16 @@ function DetailItem({ fileId, deviceFile, onSelectImage }: { fileId: string; dev const handleDownload = useCallback(async () => { if (!file) return; + const bid = localEntry?.backendId ?? fileId; setDownloading(true); try { await downloadFile.mutateAsync({ - id: fileId, - backendResourceId: fileId, - name: file?.name ?? fileId, - mimeType: file?.mimeType ?? 'application/octet-stream', - size: file?.size ?? 0, - createdAt: file?.createdAt ?? new Date().toISOString(), + id: bid, + backendResourceId: bid, + name: file?.name ?? localEntry?.name ?? fileId, + mimeType: file?.mimeType ?? localEntry?.mimeType ?? 'application/octet-stream', + size: file?.size ?? localEntry?.size ?? 0, + createdAt: file?.createdAt ?? localEntry?.createdAt ?? new Date().toISOString(), source: 'cloud', syncStatus: 'cloud', tags: file?.tags ?? [], @@ -84,7 +97,7 @@ function DetailItem({ fileId, deviceFile, onSelectImage }: { fileId: string; dev } catch {} finally { setDownloading(false); } - }, [file, fileId, downloadFile]); + }, [file, fileId, localEntry, downloadFile]); return ( @@ -113,9 +126,19 @@ function DetailItem({ fileId, deviceFile, onSelectImage }: { fileId: string; dev {uri ? ( 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, + })} > - + ) : file ? ( @@ -289,14 +312,10 @@ const styles = StyleSheet.create({ flexGrow: 1, }, imageContainer: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', backgroundColor: '#000', }, image: { width: SCREEN_WIDTH, - height: SCREEN_WIDTH, }, pageImageContainer: { alignItems: 'center', diff --git a/mobile/services/fileStore/index.ts b/mobile/services/fileStore/index.ts index e51a578..37e36f1 100644 --- a/mobile/services/fileStore/index.ts +++ b/mobile/services/fileStore/index.ts @@ -407,13 +407,15 @@ export const fileStore = { for (const bf of backendFiles) { 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 syncStatus = existing && existing.localUri ? (existing.syncStatus === 'cloud' ? 'synced' : existing.syncStatus) : 'cloud'; upsertRow({ - id: bf.id, + id: recordId, backendId: bf.id, name: bf.name, mimeType: bf.mimeType, @@ -431,7 +433,7 @@ export const fileStore = { 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); } }); },