fix files details
This commit is contained in:
+38
-19
@@ -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',
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user