diff --git a/mobile/app/sync-detail.tsx b/mobile/app/sync-detail.tsx index 163a766..f3ce79e 100644 --- a/mobile/app/sync-detail.tsx +++ b/mobile/app/sync-detail.tsx @@ -34,7 +34,7 @@ function uploadStatusIcon(task: UploadTask) { export function SyncDetailScreen() { const insets = useSafeAreaInsets(); const { pendingCount, isSyncing, refresh } = useSyncQueue(); - const { triggerSync } = useAutoSync(); + const { syncManually } = useAutoSync(); const { push } = useSyncPush(); const { tasks: uploadTasks, retry, retryAll } = useUploadQueue(); @@ -56,7 +56,7 @@ export function SyncDetailScreen() { for (const f of fileStore.getErrorFiles()) { fileStore.resetSyncError(f.id); } - await triggerSync(); + await syncManually(); try { const { getStoredDeviceServerId } = await import('../hooks/useDeviceRegistration'); const serverId = await getStoredDeviceServerId(); @@ -66,7 +66,7 @@ export function SyncDetailScreen() { } catch { } refresh(); bumpList(); - }, [triggerSync, push, refresh, bumpList]); + }, [syncManually, push, refresh, bumpList]); const handleSyncButtonPress = useCallback(async () => { if (uploadErrors.length > 0) { @@ -85,7 +85,7 @@ export function SyncDetailScreen() { text: 'Réessayer', onPress: () => { fileStore.resetSyncError(file.id); - triggerSync().finally(() => { + syncManually().finally(() => { refresh(); bumpList(); }); @@ -93,7 +93,7 @@ export function SyncDetailScreen() { }, ], ); - }, [triggerSync, refresh, bumpList]); + }, [syncManually, refresh, bumpList]); const handleTaskPress = useCallback((task: UploadTask) => { if (task.status !== 'error') return; diff --git a/mobile/hooks/useAutoSync.ts b/mobile/hooks/useAutoSync.ts index 6df814b..df2205d 100644 --- a/mobile/hooks/useAutoSync.ts +++ b/mobile/hooks/useAutoSync.ts @@ -3,7 +3,7 @@ import { createMMKV } from 'react-native-mmkv'; import { useQueryClient } from '@tanstack/react-query'; import { File, UploadType } from 'expo-file-system'; import NetInfo, { NetInfoState } from '@react-native-community/netinfo'; -import { safDirectory, StoredFolder } from '../services/safDirectory'; +import { safDirectory } from '../services/safDirectory'; import { fileStore } from '../services/fileStore'; import { activeUploadUris } from '../services/uploadQueue'; import { apiClient } from '../api/client'; @@ -77,40 +77,23 @@ export function useAutoSync() { const queryClient = useQueryClient(); const isRunning = useRef(false); - const checkAndSync = useCallback(async () => { + const getPendingFiles = useCallback((): Array[number]> => { + return fileStore.getAllLocal().filter( + (entry) => !entry.backendId && entry.syncStatus === 'local' && entry.localUri + ); + }, []); + + const runPendingSync = useCallback(async (pendingFiles: Array[number]>) => { if (isRunning.current) return; - const globalMode = safDirectory.getGlobalSyncMode(); - if (globalMode === 'off') return; + const globalCellular = safDirectory.getGlobalSyncCellular(); + const netInfo = await NetInfo.fetch(); + + if (!canSyncBasedOnNetwork(netInfo, globalCellular)) return; isRunning.current = true; try { - const globalCellular = safDirectory.getGlobalSyncCellular(); - const netInfo = await NetInfo.fetch(); - - if (!canSyncBasedOnNetwork(netInfo, globalCellular)) return; - - const registry = fileStore.getAllLocal(); - let pendingFiles = registry.filter( - (entry) => !entry.backendId && entry.syncStatus === 'local' && entry.localUri - ); - - if (globalMode === 'auto') { - // Mode auto global : tous les fichiers locaux sans backendId - } else { - // Mode manuel : uniquement les fichiers des dossiers en mode auto - const allFolders = safDirectory.getAll(); - const autoFolderIds = new Set( - allFolders.filter((f) => f.syncMode === 'auto').map((f) => f.id) - ); - pendingFiles = pendingFiles.filter( - (entry) => entry.parentResourceId && autoFolderIds.has(entry.parentResourceId) - ); - } - - if (pendingFiles.length === 0) return; - setIsSyncing(true); for (const entry of pendingFiles) { @@ -150,6 +133,33 @@ export function useAutoSync() { } }, [queryClient]); + const checkAndSync = useCallback(async () => { + const globalMode = safDirectory.getGlobalSyncMode(); + if (globalMode === 'off') return; + + let pendingFiles = getPendingFiles(); + + if (globalMode === 'manual') { + const allFolders = safDirectory.getAll(); + const autoFolderIds = new Set( + allFolders.filter((f) => f.syncMode === 'auto').map((f) => f.id) + ); + pendingFiles = pendingFiles.filter( + (entry) => entry.parentResourceId && autoFolderIds.has(entry.parentResourceId) + ); + } + + if (pendingFiles.length === 0) return; + + await runPendingSync(pendingFiles); + }, [getPendingFiles, runPendingSync]); + + const syncManually = useCallback(async () => { + const pendingFiles = getPendingFiles(); + if (pendingFiles.length === 0) return; + await runPendingSync(pendingFiles); + }, [getPendingFiles, runPendingSync]); + useEffect(() => { const timeout = setTimeout(() => { checkAndSync(); @@ -158,5 +168,5 @@ export function useAutoSync() { return () => { clearTimeout(timeout); clearInterval(interval); }; }, [checkAndSync]); - return { triggerSync: checkAndSync }; + return { triggerSync: checkAndSync, syncManually }; } diff --git a/mobile/hooks/useSyncQueue.ts b/mobile/hooks/useSyncQueue.ts index 4b229ae..61f5f0b 100644 --- a/mobile/hooks/useSyncQueue.ts +++ b/mobile/hooks/useSyncQueue.ts @@ -1,8 +1,6 @@ import { useState, useEffect, useCallback } from 'react'; import { createMMKV } from 'react-native-mmkv'; import { fileStore } from '../services/fileStore'; -import { safDirectory } from '../services/safDirectory'; -import { useDeviceFiles } from './useDeviceFiles'; const syncStateStorage = createMMKV({ id: 'vaultdrop-sync-state' }); @@ -17,35 +15,15 @@ export function setIsSyncing(value: boolean) { export function useSyncQueue() { const [pendingCount, setPendingCount] = useState(0); const [isSyncing, setIsSyncingState] = useState(() => getIsSyncing()); - const { folders } = useDeviceFiles(); const refresh = useCallback(() => { - const globalMode = safDirectory.getGlobalSyncMode(); - - if (globalMode === 'off') { - setPendingCount(0); - setIsSyncingState(getIsSyncing()); - return; - } - - const allFolders = safDirectory.getAll(); - const autoFolderIds = new Set( - allFolders.filter((f) => f.syncMode === 'auto').map((f) => f.id) - ); - const registry = fileStore.getAllLocal(); let count = 0; for (const entry of registry) { if (entry.backendId || !entry.localUri) continue; if (entry.syncStatus !== 'local' && entry.syncStatus !== 'error') continue; - if (globalMode === 'auto') { - count++; - } else { - // mode manuel : uniquement les fichiers des dossiers en mode auto - if (!entry.parentResourceId || !autoFolderIds.has(entry.parentResourceId)) continue; - count++; - } + count++; } setPendingCount(count);