From 57d8e70d7fbba57f810db223dee7b63b372b6ff3 Mon Sep 17 00:00:00 2001 From: m Date: Fri, 28 Aug 2026 22:34:00 +0200 Subject: [PATCH] add network status --- mobile/app/index.tsx | 20 +++++++++++++++++--- mobile/hooks/useFiles.ts | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/mobile/app/index.tsx b/mobile/app/index.tsx index 75a55e8..b5e4641 100644 --- a/mobile/app/index.tsx +++ b/mobile/app/index.tsx @@ -187,16 +187,30 @@ export function HomeScreen() { const files = data?.data ?? []; const filteredFiles = useMemo( - () => debouncedSearch.trim() ? files.filter((f) => matchesQuery(f, debouncedSearch, filters)) : files, + () => { + + const search = debouncedSearch.trim(); + + if ( search ) { + return files.filter((f) => matchesQuery(f, debouncedSearch, filters)); + } + + return files; + + }, [files, debouncedSearch, filters] ); const mediaFilteredFiles = useMemo(() => { if (mediaFilter === 'all') return filteredFiles; + + const PHOTOS_VIDEOS = ['image/','video/']; + const DOCUMENTS = ['application/','text/']; + return filteredFiles.filter((f) => { const mt = (f.mimeType ?? '').toLowerCase(); - if (mediaFilter === 'documents') return mt.startsWith('application/') || mt.startsWith('text/'); - if (mediaFilter === 'photos-videos') return mt.startsWith('image/') || mt.startsWith('video/'); + if (mediaFilter === 'documents') return DOCUMENTS.some(docType => mt.startsWith(docType)) || PHOTOS_VIDEOS.every(docType => !mt.startsWith(docType)); + if (mediaFilter === 'photos-videos') return PHOTOS_VIDEOS.some(docType => mt.startsWith(docType)); return true; }); }, [filteredFiles, mediaFilter]); diff --git a/mobile/hooks/useFiles.ts b/mobile/hooks/useFiles.ts index 76bdb1d..7bdc6e8 100644 --- a/mobile/hooks/useFiles.ts +++ b/mobile/hooks/useFiles.ts @@ -4,6 +4,7 @@ import { ENDPOINTS } from '../constants/api'; import type { UnifiedFileItem, PaginatedResponse, FileItem, Tag } from '../types'; import { fileStore } from '../services/fileStore'; import { actionQueue } from '../services/actionQueue'; +import { useNetworkStatus } from './useNetworkStatus'; function recordToUnifiedItem(record: ReturnType): UnifiedFileItem | null { if (!record) return null; @@ -33,9 +34,43 @@ export function useFiles(parentId?: string | null, page: number = 1, limit: numb ? ['resources', parentId, page, limit] : ['resources', 'root', page, limit]; + const { isOnline } = useNetworkStatus(); + return useQuery({ queryKey, queryFn: async () => { + + if ( !isOnline ) { + + if ( parentId ) { + + const children = fileStore.getChildrenByParent(parentId); + + return { + data: children.map((r) => recordToUnifiedItem(r)!).filter(Boolean), + meta: { page, total: children.length }, + }; + + } + + const cached = fileStore.getRootFiles(); + const localDeviceFiles = fileStore.getLocalDeviceFiles(); + const validFiles = cached.files.filter( + (f) => !f.backendId || returnedIds.has(f.backendId) || f.source === 'local', + ); + const validIds = new Set(validFiles.map((f) => f.id)); + const extraLocal = localDeviceFiles.filter((f) => !validIds.has(f.id)); + const mergedFiles = [...validFiles, ...extraLocal]; + + return { + data: mergedFiles.map((r) => recordToUnifiedItem(r)!).filter(Boolean), + meta: { page, total: ( cached.total) + extraLocal.length }, + + }; + + } + + if (parentId) { const backendRes = await apiClient.get>( `${ENDPOINTS.RESOURCES}/folders/${parentId}/resources?page=${page}&limit=${limit}&thumbnail=thumbnail_small`, @@ -103,6 +138,7 @@ export function useFiles(parentId?: string | null, page: number = 1, limit: numb if (!parentId) { const cached = fileStore.getRootFiles(); const localDeviceFiles = fileStore.getLocalDeviceFiles(); + const validIds = new Set(cached.files.map((f) => f.id)); const extraLocal = localDeviceFiles.filter((f) => !validIds.has(f.id)); const allFiles = [...cached.files, ...extraLocal];