diff --git a/app/lib/entity/file/data_source.dart b/app/lib/entity/file/data_source.dart index ad800240..a7e7c2be 100644 --- a/app/lib/entity/file/data_source.dart +++ b/app/lib/entity/file/data_source.dart @@ -568,6 +568,22 @@ class FileSqliteDbDataSource implements FileDataSource { static final _log = Logger("entity.file.data_source.FileSqliteDbDataSource"); } +class IntermediateSyncState { + const IntermediateSyncState({ + required this.account, + required this.dir, + required this.remoteTouchEtag, + required this.files, + required this.shouldCache, + }); + + final Account account; + final File dir; + final String? remoteTouchEtag; + final List<File> files; + final bool shouldCache; +} + class FileCachedDataSource implements FileDataSource { FileCachedDataSource( this._c, { @@ -598,21 +614,29 @@ class FileCachedDataSource implements FileDataSource { Account account, File dir, { required String? remoteTouchEtag, + }) async { + final state = await beginSync( + account, + dir, + remoteTouchEtag: remoteTouchEtag, + ); + return concludeSync(state); + } + + Future<IntermediateSyncState> beginSync( + Account account, + File dir, { + required String? remoteTouchEtag, }) async { try { final remote = await _remoteSrc.list(account, dir); - await FileSqliteCacheUpdater(_c)(account, dir, remote: remote); - if (shouldCheckCache) { - // update our local touch token to match the remote one - try { - _log.info("[list] Update outdated local etag: ${dir.path}"); - await _c.touchManager.setLocalEtag(account, dir, remoteTouchEtag); - } catch (e, stacktrace) { - _log.shout("[list] Failed while setLocalToken", e, stacktrace); - // ignore error - } - } - return remote; + return IntermediateSyncState( + account: account, + dir: dir, + remoteTouchEtag: remoteTouchEtag, + files: remote, + shouldCache: true, + ); } on ApiException catch (e) { if (e.response.statusCode == 404) { _log.info("[list] File removed: $dir"); @@ -622,7 +646,13 @@ class FileCachedDataSource implements FileDataSource { _log.warning( "[list] Failed while remove from db, file not cached?", e); } - return []; + return IntermediateSyncState( + account: account, + dir: dir, + remoteTouchEtag: remoteTouchEtag, + files: [], + shouldCache: false, + ); } else if (e.response.statusCode == 403) { _log.info("[list] E2E encrypted dir: $dir"); try { @@ -633,13 +663,40 @@ class FileCachedDataSource implements FileDataSource { _log.warning( "[list] Failed while emptying from db, file not cached?", e); } - return []; + return IntermediateSyncState( + account: account, + dir: dir, + remoteTouchEtag: remoteTouchEtag, + files: [], + shouldCache: false, + ); } else { rethrow; } } } + Future<List<File>> concludeSync(IntermediateSyncState state) async { + if (!state.shouldCache) { + return state.files; + } + + await FileSqliteCacheUpdater(_c)(state.account, state.dir, + remote: state.files); + if (shouldCheckCache) { + // update our local touch token to match the remote one + try { + _log.info("[list] Update outdated local etag: ${state.dir.path}"); + await _c.touchManager + .setLocalEtag(state.account, state.dir, state.remoteTouchEtag); + } catch (e, stacktrace) { + _log.shout("[list] Failed while setLocalToken", e, stacktrace); + // ignore error + } + } + return state.files; + } + @override listSingle(Account account, File f) async { final remote = await _remoteSrc.listSingle(account, f); diff --git a/app/lib/use_case/sync_dir.dart b/app/lib/use_case/sync_dir.dart index 55ff7e48..d96b3fcd 100644 --- a/app/lib/use_case/sync_dir.dart +++ b/app/lib/use_case/sync_dir.dart @@ -56,9 +56,12 @@ class SyncDir { } _log.info("[_syncDir] Dir changed: ${remoteDir.path}"); - final children = await FileCachedDataSource(_c, shouldCheckCache: true) - .sync(account, remoteDir, remoteTouchEtag: status.item2); + final dataSrc = FileCachedDataSource(_c, shouldCheckCache: true); + final syncState = await dataSrc.beginSync(account, remoteDir, + remoteTouchEtag: status.item2); + final children = syncState.files; if (!isRecursive) { + await dataSrc.concludeSync(syncState); return true; } final subDirs = children @@ -88,6 +91,7 @@ class SyncDir { } progress.next(); } + await dataSrc.concludeSync(syncState); return true; }