Consolidate shared assets deletion logic

This commit is contained in:
Neeraj Gupta
2025-07-31 10:29:00 +05:30
parent 1848f1a94b
commit 02ef29fd8f
4 changed files with 46 additions and 22 deletions

View File

@@ -7,7 +7,6 @@ import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import "package:photos/db/common/base.dart";
import "package:photos/extensions/stop_watch.dart";
import 'package:photos/models/backup_status.dart';
import 'package:photos/models/file/file.dart';
import 'package:photos/models/file/file_type.dart';
import 'package:photos/models/file_load_result.dart';

View File

@@ -53,4 +53,17 @@ extension SharedAssetsTable on LocalDB {
[assetID],
);
}
Future<void> deleteSharedAssets(Set<String> assetIDs) async {
if (assetIDs.isEmpty) return;
await Future.forEach(
assetIDs.slices(LocalDB.batchInsertMaxCount),
(slice) async {
await sqliteDB.executeBatch(
'DELETE FROM shared_assets WHERE id = ?',
slice.map((id) => [id]).toList(),
);
},
);
}
}

View File

@@ -103,27 +103,39 @@ class SharedAssetService {
return (width, height);
}
static Future<List<String>> tryDelete(List<String> localIDs) {
static Future<List<String>> tryDelete(List<String> localIDs,
{int batchSize = 10}) async {
final List<String> actuallyDeletedIDs = [];
try {
return Future.forEach<String>(localIDs, (id) async {
final String localPath = getPath(id);
try {
// verify the file exists as the OS may have already deleted it from cache
if (File(localPath).existsSync()) {
await File(localPath).delete();
}
actuallyDeletedIDs.add(id);
} catch (e, s) {
_logger.severe("Could not delete file ", e, s);
}
}).then((ignore) {
return actuallyDeletedIDs;
});
for (int i = 0; i < localIDs.length; i += batchSize) {
final batch = localIDs.skip(i).take(batchSize).toList();
final batchResults = await Future.wait(
batch.map((id) async {
final String localPath = getPath(id);
try {
if (File(localPath).existsSync()) {
await File(localPath).delete();
}
return id;
} catch (e, s) {
_logger.severe("Could not delete file $id", e, s);
return null;
}
}),
eagerError: false, // Continue even if some deletions fail
);
// Add successful deletions
actuallyDeletedIDs.addAll(batchResults.whereType<String>());
}
} catch (e, s) {
_logger.severe("Unexpected error while deleting share media files", e, s);
return Future.value(actuallyDeletedIDs);
}
if (actuallyDeletedIDs.isNotEmpty) {
await localDB.deleteSharedAssets(actuallyDeletedIDs.toSet());
}
return actuallyDeletedIDs;
}
static Future<File> moveToSharedDir(File ioFile, String id) async {

View File

@@ -72,7 +72,7 @@ Future<void> deleteFilesFromEverywhere(
} catch (e, s) {
_logger.severe("Could not delete file", e, s);
}
deletedIDs.addAll(await SharedAssetService.tryDelete(sharedAssetIDs));
await SharedAssetService.tryDelete(sharedAssetIDs);
final updatedCollectionIDs = <int>{};
final List<TrashRequest> uploadedFilesToBeTrashed = [];
final List<EnteFile> deletedFiles = [];
@@ -228,7 +228,7 @@ Future<void> deleteFilesOnDeviceOnly(
} catch (e, s) {
_logger.severe("Could not delete file", e, s);
}
deletedIDs.addAll(await SharedAssetService.tryDelete(localSharedMediaIDs));
await SharedAssetService.tryDelete(localSharedMediaIDs);
final List<EnteFile> deletedFiles = [];
for (final file in files) {
// Remove only those files that have been removed from disk
@@ -347,7 +347,7 @@ Future<bool> deleteLocalFiles(
localAssetIDs.add(id);
}
}
delLocalIDs.addAll(await SharedAssetService.tryDelete(localSharedMediaIDs));
await SharedAssetService.tryDelete(localSharedMediaIDs);
final bool shouldDeleteInBatches =
await isAndroidSDKVersionLowerThan(android11SDKINT) || tooManyAssets;
@@ -435,7 +435,7 @@ Future<bool> deleteLocalFilesAfterRemovingAlreadyDeletedIDs(
}
}
deletedIDs.addAll(alreadyDeletedIDs);
deletedIDs.addAll(await SharedAssetService.tryDelete(localSharedMediaIDs));
await SharedAssetService.tryDelete(localSharedMediaIDs);
await dialog.hide();
@@ -520,7 +520,7 @@ Future<bool> retryFreeUpSpaceAfterRemovingAssetsNonExistingInDisk(
localAssetIDs.add(localID);
}
}
deletedIDs.addAll(await SharedAssetService.tryDelete(localSharedMediaIDs));
await SharedAssetService.tryDelete(localSharedMediaIDs);
await dialog.hide();