From d5c9eea40f12ea70476cc4b9b2225f30b045d63e Mon Sep 17 00:00:00 2001 From: ashilkn Date: Wed, 5 Mar 2025 17:05:32 +0530 Subject: [PATCH] [mob][photos] Try checking for and handling already deleted local IDs during free up space only if freeing up space without it fails This is to make free up space faster in most cases --- mobile/lib/ui/tools/free_space_page.dart | 8 +++ mobile/lib/utils/delete_file_util.dart | 67 +++++++++++++++++++++++- 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/mobile/lib/ui/tools/free_space_page.dart b/mobile/lib/ui/tools/free_space_page.dart index a8d6a42742..cae35185e6 100644 --- a/mobile/lib/ui/tools/free_space_page.dart +++ b/mobile/lib/ui/tools/free_space_page.dart @@ -167,6 +167,14 @@ class _FreeSpacePageState extends State { Future _freeStorage(BackupStatus status) async { bool result = await deleteLocalFiles(context, status.localIDs); + + if (result == false) { + result = await deleteLocalFilesAfterRemovingAlreadyDeletedIDs( + context, + status.localIDs, + ); + } + if (result == false && Platform.isAndroid) { result = await retryFreeUpSpaceAfterRemovingNonExistingAssets(context); } diff --git a/mobile/lib/utils/delete_file_util.dart b/mobile/lib/utils/delete_file_util.dart index 0147441f7b..6e5c65a4da 100644 --- a/mobile/lib/utils/delete_file_util.dart +++ b/mobile/lib/utils/delete_file_util.dart @@ -19,6 +19,7 @@ import 'package:photos/models/file/file.dart'; import "package:photos/models/files_split.dart"; import 'package:photos/models/selected_files.dart'; import "package:photos/service_locator.dart"; +import "package:photos/services/files_service.dart"; import "package:photos/services/sync/local_sync_service.dart"; import 'package:photos/services/sync/remote_sync_service.dart'; import 'package:photos/services/sync/sync_service.dart'; @@ -326,6 +327,69 @@ Future emptyTrash(BuildContext context) async { Future deleteLocalFiles( BuildContext context, List localIDs, +) async { + final List deletedIDs = []; + final List localAssetIDs = []; + final List localSharedMediaIDs = []; + try { + for (String id in localIDs) { + if (id.startsWith(oldSharedMediaIdentifier) || + id.startsWith(sharedMediaIdentifier)) { + localSharedMediaIDs.add(id); + } else { + localAssetIDs.add(id); + } + } + deletedIDs.addAll(await _tryDeleteSharedMediaFiles(localSharedMediaIDs)); + + final bool shouldDeleteInBatches = + await isAndroidSDKVersionLowerThan(android11SDKINT); + if (shouldDeleteInBatches) { + _logger.info("Deleting in batches"); + deletedIDs + .addAll(await deleteLocalFilesInBatches(context, localAssetIDs)); + } else { + _logger.info("Deleting in one shot"); + deletedIDs + .addAll(await _deleteLocalFilesInOneShot(context, localAssetIDs)); + } + // In IOS, the library returns no error and fail to delete any file is + // there's any shared file. As a stop-gap solution, we initiate deletion in + // batches. Similar in Android, for large number of files, we have observed + // that the library fails to delete any file. So, we initiate deletion in + // batches. + if (deletedIDs.isEmpty && Platform.isIOS) { + deletedIDs.addAll( + await _iosDeleteLocalFilesInBatchesFallback(context, localAssetIDs), + ); + } + + if (deletedIDs.isNotEmpty) { + final deletedFiles = await FilesDB.instance.getLocalFiles(deletedIDs); + await FilesDB.instance.deleteLocalFiles(deletedIDs); + _logger.info(deletedFiles.length.toString() + " files deleted locally"); + Bus.instance.fire( + LocalPhotosUpdatedEvent(deletedFiles, source: "deleteLocal"), + ); + return true; + } else { + //On android 10, even if files were deleted, deletedIDs is empty. + //This is a workaround so that users are not shown an error message on + //android 10 + if (!await isAndroidSDKVersionLowerThan(android11SDKINT)) { + return false; + } + return true; + } + } catch (e, s) { + _logger.severe("Could not delete local files", e, s); + return false; + } +} + +Future deleteLocalFilesAfterRemovingAlreadyDeletedIDs( + BuildContext context, + List localIDs, ) async { final files = await FilesDB.instance.getLocalFiles(localIDs, dedupeByLocalID: true); @@ -388,7 +452,6 @@ Future deleteLocalFiles( //This is a workaround so that users are not shown an error message on //android 10 if (!await isAndroidSDKVersionLowerThan(android11SDKINT)) { - showToast(context, S.of(context).couldNotFreeUpSpace); return false; } return true; @@ -423,7 +486,7 @@ Future retryFreeUpSpaceAfterRemovingNonExistingAssets( final List deletedIDs = []; final List localAssetIDs = []; final List localSharedMediaIDs = []; - status = await SyncService.instance.getBackupStatus(); + status = await FilesService.instance.getBackupStatus(); for (String localID in status.localIDs) { if (localID.startsWith(oldSharedMediaIdentifier) ||