From 6745b110df07331d7a9b56042f8b0d359c90cc9f Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Mon, 30 Jun 2025 12:23:01 +0530 Subject: [PATCH] Refactor shared assets --- .../services/local/shared_assert.service.dart | 46 +++++++++++++++++-- .../viewer/file/video_widget_media_kit.dart | 3 +- .../ui/viewer/file/video_widget_native.dart | 3 +- mobile/lib/utils/delete_file_util.dart | 41 ++++------------- mobile/lib/utils/file_uploader.dart | 2 +- mobile/lib/utils/file_uploader_util.dart | 4 +- mobile/lib/utils/file_util.dart | 20 +------- mobile/lib/utils/thumbnail_util.dart | 2 +- 8 files changed, 61 insertions(+), 60 deletions(-) diff --git a/mobile/lib/services/local/shared_assert.service.dart b/mobile/lib/services/local/shared_assert.service.dart index 3d71539854..364d4a6dfd 100644 --- a/mobile/lib/services/local/shared_assert.service.dart +++ b/mobile/lib/services/local/shared_assert.service.dart @@ -11,13 +11,28 @@ import "package:photos/service_locator.dart"; import "package:photos/utils/file_util.dart"; import "package:video_thumbnail/video_thumbnail.dart"; -class SharedAssertService { - static final _logger = Logger("SharedAssertService"); +class SharedAssetService { + static final _logger = Logger("SharedAssetService"); + + static Future getFile(String sharedAssetID) async { + final localFile = File(getPath(sharedAssetID)); + if (localFile.existsSync()) { + return localFile; + } + return null; + } + + static String getPath(String localID) { + return Configuration.instance.getSharedMediaDirectory() + + "/" + + localID.replaceAll(sharedMediaIdentifier, ''); + } + static Future getThumbnail( String sharedAssetID, bool isVideo, ) async { - var localFile = File(getSharedAssetPath(sharedAssetID)); + var localFile = File(getPath(sharedAssetID)); if (!localFile.existsSync()) { return null; } @@ -49,6 +64,29 @@ class SharedAssertService { return thumbnailData; } + static Future> tryDelete(List localIDs) { + final List actuallyDeletedIDs = []; + try { + return Future.forEach(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; + }); + } catch (e, s) { + _logger.severe("Unexpected error while deleting share media files", e, s); + return Future.value(actuallyDeletedIDs); + } + } + static Future cleanUpUntrackedItems() async { final sharedMediaDir = Configuration.instance.getSharedMediaDirectory() + "/"; @@ -59,7 +97,7 @@ class SharedAssertService { final Set trackedSharedFilePaths = {}; for (String localID in existingLocalFileIDs) { if (localID.contains(sharedMediaIdentifier)) { - trackedSharedFilePaths.add(getSharedAssetPath(localID)); + trackedSharedFilePaths.add(getPath(localID)); } } for (final file in sharedFiles) { diff --git a/mobile/lib/ui/viewer/file/video_widget_media_kit.dart b/mobile/lib/ui/viewer/file/video_widget_media_kit.dart index 9dfce2c013..c925a628e0 100644 --- a/mobile/lib/ui/viewer/file/video_widget_media_kit.dart +++ b/mobile/lib/ui/viewer/file/video_widget_media_kit.dart @@ -17,6 +17,7 @@ import "package:photos/models/file/file.dart"; import "package:photos/module/download/task.dart"; import "package:photos/service_locator.dart"; import "package:photos/services/files_service.dart"; +import "package:photos/services/local/shared_assert.service.dart"; import "package:photos/services/wake_lock_service.dart"; import "package:photos/theme/colors.dart"; import "package:photos/theme/ente_theme.dart"; @@ -136,7 +137,7 @@ class _VideoWidgetMediaKitState extends State _loadNetworkVideo(); _setFileSizeIfNull(); } else if (widget.file.isSharedMediaToAppSandbox) { - final localFile = File(getSharedMediaFilePath(widget.file)); + final localFile = File(SharedAssetService.getPath(widget.file.localID!)); if (localFile.existsSync()) { _setVideoController(localFile.path); } else if (widget.file.isUploaded) { diff --git a/mobile/lib/ui/viewer/file/video_widget_native.dart b/mobile/lib/ui/viewer/file/video_widget_native.dart index c54d78b7dd..9fc178e4d6 100644 --- a/mobile/lib/ui/viewer/file/video_widget_native.dart +++ b/mobile/lib/ui/viewer/file/video_widget_native.dart @@ -21,6 +21,7 @@ import "package:photos/models/preview/playlist_data.dart"; import "package:photos/module/download/task.dart"; import "package:photos/service_locator.dart"; import "package:photos/services/files_service.dart"; +import "package:photos/services/local/shared_assert.service.dart"; import "package:photos/services/wake_lock_service.dart"; import "package:photos/theme/colors.dart"; import "package:photos/theme/ente_theme.dart"; @@ -177,7 +178,7 @@ class _VideoWidgetNativeState extends State _loadNetworkVideo(update); _setFileSizeIfNull(); } else if (widget.file.isSharedMediaToAppSandbox) { - final localFile = File(getSharedMediaFilePath(widget.file)); + final localFile = File(SharedAssetService.getPath(widget.file.localID!)); if (localFile.existsSync()) { _setFilePathForNativePlayer(localFile.path, update); } else if (widget.file.isUploaded) { diff --git a/mobile/lib/utils/delete_file_util.dart b/mobile/lib/utils/delete_file_util.dart index fb2b744330..3056a9f9d0 100644 --- a/mobile/lib/utils/delete_file_util.dart +++ b/mobile/lib/utils/delete_file_util.dart @@ -22,6 +22,7 @@ import 'package:photos/models/selected_files.dart'; import "package:photos/service_locator.dart"; import "package:photos/services/files_service.dart"; import "package:photos/services/local/local_import.dart"; +import "package:photos/services/local/shared_assert.service.dart"; import 'package:photos/services/sync/remote_sync_service.dart'; import 'package:photos/services/sync/sync_service.dart'; import 'package:photos/ui/common/linear_progress_dialog.dart'; @@ -31,7 +32,6 @@ import 'package:photos/ui/components/models/button_type.dart'; import 'package:photos/ui/notification/toast.dart'; import "package:photos/utils/device_info.dart"; import 'package:photos/utils/dialog_util.dart'; -import 'package:photos/utils/file_util.dart'; final _logger = Logger("DeleteFileUtil"); @@ -72,7 +72,7 @@ Future deleteFilesFromEverywhere( } catch (e, s) { _logger.severe("Could not delete file", e, s); } - deletedIDs.addAll(await _tryDeleteSharedMediaFiles(sharedAssetIDs)); + deletedIDs.addAll(await SharedAssetService.tryDelete(sharedAssetIDs)); final updatedCollectionIDs = {}; final List uploadedFilesToBeTrashed = []; final List deletedFiles = []; @@ -228,7 +228,7 @@ Future deleteFilesOnDeviceOnly( } catch (e, s) { _logger.severe("Could not delete file", e, s); } - deletedIDs.addAll(await _tryDeleteSharedMediaFiles(localSharedMediaIDs)); + deletedIDs.addAll(await SharedAssetService.tryDelete(localSharedMediaIDs)); final List deletedFiles = []; for (final file in files) { // Remove only those files that have been removed from disk @@ -343,7 +343,7 @@ Future deleteLocalFiles( localAssetIDs.add(id); } } - delLocalIDs.addAll(await _tryDeleteSharedMediaFiles(localSharedMediaIDs)); + delLocalIDs.addAll(await SharedAssetService.tryDelete(localSharedMediaIDs)); final bool shouldDeleteInBatches = await isAndroidSDKVersionLowerThan(android11SDKINT); @@ -419,7 +419,7 @@ Future deleteLocalFilesAfterRemovingAlreadyDeletedIDs( } } deletedIDs.addAll(alreadyDeletedIDs); - deletedIDs.addAll(await _tryDeleteSharedMediaFiles(localSharedMediaIDs)); + deletedIDs.addAll(await SharedAssetService.tryDelete(localSharedMediaIDs)); await dialog.hide(); @@ -504,7 +504,7 @@ Future retryFreeUpSpaceAfterRemovingAssetsNonExistingInDisk( localAssetIDs.add(localID); } } - deletedIDs.addAll(await _tryDeleteSharedMediaFiles(localSharedMediaIDs)); + deletedIDs.addAll(await SharedAssetService.tryDelete(localSharedMediaIDs)); await dialog.hide(); @@ -621,10 +621,10 @@ Future> deleteLocalFilesInBatches( return delLocalIDs; } -Future _localFileExist(EnteFile file) { +Future _localFileExist(EnteFile file) async { if (file.isSharedMediaToAppSandbox) { - final localFile = File(getSharedMediaFilePath(file)); - return localFile.exists(); + final localFile = await SharedAssetService.getFile(file.localID!); + return localFile != null; } else { return file.getAsset.then((asset) { if (asset == null) { @@ -635,29 +635,6 @@ Future _localFileExist(EnteFile file) { } } -Future> _tryDeleteSharedMediaFiles(List localIDs) { - final List actuallyDeletedIDs = []; - try { - return Future.forEach(localIDs, (id) async { - final String localPath = getSharedAssetPath(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; - }); - } catch (e, s) { - _logger.severe("Unexpected error while deleting share media files", e, s); - return Future.value(actuallyDeletedIDs); - } -} - Future shouldProceedWithDeletion(BuildContext context) async { final actionResult = await showChoiceActionSheet( context, diff --git a/mobile/lib/utils/file_uploader.dart b/mobile/lib/utils/file_uploader.dart index 309b41c9d8..8157aa6e7a 100644 --- a/mobile/lib/utils/file_uploader.dart +++ b/mobile/lib/utils/file_uploader.dart @@ -395,7 +395,7 @@ class FileUploader { } if (Platform.isAndroid) { - await SharedAssertService.cleanUpUntrackedItems(); + await SharedAssetService.cleanUpUntrackedItems(); } } catch (e, s) { _logger.severe("Failed to remove stale files", e, s); diff --git a/mobile/lib/utils/file_uploader_util.dart b/mobile/lib/utils/file_uploader_util.dart index cc7472a49b..91229be1d9 100644 --- a/mobile/lib/utils/file_uploader_util.dart +++ b/mobile/lib/utils/file_uploader_util.dart @@ -289,7 +289,7 @@ Future _getMediaUploadDataFromAppCache( EnteFile file, bool parseExif, ) async { - final localPath = getSharedAssetPath(file.localID!); + final localPath = SharedAssetService.getPath(file.localID!); final sourceFile = File(localPath); if (!sourceFile.existsSync()) { _logger.warning("File doesn't exist in app sandbox"); @@ -300,7 +300,7 @@ Future _getMediaUploadDataFromAppCache( } try { Map? exifData; - final Uint8List? thumbnailData = await SharedAssertService.getThumbnail( + final Uint8List? thumbnailData = await SharedAssetService.getThumbnail( file.localID!, file.isVideo, ); diff --git a/mobile/lib/utils/file_util.dart b/mobile/lib/utils/file_util.dart index 4e767bf86a..7c6415ddbe 100644 --- a/mobile/lib/utils/file_util.dart +++ b/mobile/lib/utils/file_util.dart @@ -17,6 +17,7 @@ import "package:photos/image/in_memory_image_cache.dart"; import "package:photos/models/file/extensions/file_props.dart"; import 'package:photos/models/file/file.dart'; import 'package:photos/models/file/file_type.dart'; +import "package:photos/services/local/shared_assert.service.dart"; import 'package:photos/utils/file_download_util.dart'; import 'package:photos/utils/thumbnail_util.dart'; @@ -64,20 +65,13 @@ Future getFile( } } -Future doesLocalFileExist(EnteFile file) async { - return await _getLocalDiskFile(file) != null; -} - Future _getLocalDiskFile( EnteFile file, { bool liveVideo = false, bool isOrigin = false, }) { if (file.isSharedMediaToAppSandbox) { - final localFile = File(getSharedMediaFilePath(file)); - return localFile.exists().then((exist) { - return exist ? localFile : null; - }); + return SharedAssetService.getFile(file.localID!); } else if (file.fileType == FileType.livePhoto && liveVideo) { return Motionphoto.getLivePhotoFile(file.localID!); } else { @@ -90,16 +84,6 @@ Future _getLocalDiskFile( } } -String getSharedMediaFilePath(EnteFile file) { - return getSharedAssetPath(file.localID!); -} - -String getSharedAssetPath(String localID) { - return Configuration.instance.getSharedMediaDirectory() + - "/" + - localID.replaceAll(sharedMediaIdentifier, ''); -} - void preloadThumbnail(EnteFile file) { if (file.isRemoteFile) { getThumbnailFromServer(file); diff --git a/mobile/lib/utils/thumbnail_util.dart b/mobile/lib/utils/thumbnail_util.dart index c8ffee2ab0..95fba728b1 100644 --- a/mobile/lib/utils/thumbnail_util.dart +++ b/mobile/lib/utils/thumbnail_util.dart @@ -105,7 +105,7 @@ Future getThumbnailFromLocal( } if (file.isSharedMediaToAppSandbox) { //todo:neeraj support specifying size/quality - return SharedAssertService.getThumbnail( + return SharedAssetService.getThumbnail( file.localID!, file.isVideo, ).then((data) {