Refactor shared assets

This commit is contained in:
Neeraj Gupta
2025-06-30 12:23:01 +05:30
parent 7061161181
commit 6745b110df
8 changed files with 61 additions and 60 deletions

View File

@@ -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<File?> 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<Uint8List?> 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<List<String>> tryDelete(List<String> localIDs) {
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;
});
} catch (e, s) {
_logger.severe("Unexpected error while deleting share media files", e, s);
return Future.value(actuallyDeletedIDs);
}
}
static Future<void> cleanUpUntrackedItems() async {
final sharedMediaDir =
Configuration.instance.getSharedMediaDirectory() + "/";
@@ -59,7 +97,7 @@ class SharedAssertService {
final Set<String> trackedSharedFilePaths = {};
for (String localID in existingLocalFileIDs) {
if (localID.contains(sharedMediaIdentifier)) {
trackedSharedFilePaths.add(getSharedAssetPath(localID));
trackedSharedFilePaths.add(getPath(localID));
}
}
for (final file in sharedFiles) {

View File

@@ -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<VideoWidgetMediaKit>
_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) {

View File

@@ -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<VideoWidgetNative>
_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) {

View File

@@ -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<void> 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 = <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 _tryDeleteSharedMediaFiles(localSharedMediaIDs));
deletedIDs.addAll(await SharedAssetService.tryDelete(localSharedMediaIDs));
final List<EnteFile> deletedFiles = [];
for (final file in files) {
// Remove only those files that have been removed from disk
@@ -343,7 +343,7 @@ Future<bool> 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<bool> deleteLocalFilesAfterRemovingAlreadyDeletedIDs(
}
}
deletedIDs.addAll(alreadyDeletedIDs);
deletedIDs.addAll(await _tryDeleteSharedMediaFiles(localSharedMediaIDs));
deletedIDs.addAll(await SharedAssetService.tryDelete(localSharedMediaIDs));
await dialog.hide();
@@ -504,7 +504,7 @@ Future<bool> retryFreeUpSpaceAfterRemovingAssetsNonExistingInDisk(
localAssetIDs.add(localID);
}
}
deletedIDs.addAll(await _tryDeleteSharedMediaFiles(localSharedMediaIDs));
deletedIDs.addAll(await SharedAssetService.tryDelete(localSharedMediaIDs));
await dialog.hide();
@@ -621,10 +621,10 @@ Future<List<String>> deleteLocalFilesInBatches(
return delLocalIDs;
}
Future<bool> _localFileExist(EnteFile file) {
Future<bool> _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<bool> _localFileExist(EnteFile file) {
}
}
Future<List<String>> _tryDeleteSharedMediaFiles(List<String> localIDs) {
final List<String> actuallyDeletedIDs = [];
try {
return Future.forEach<String>(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<bool> shouldProceedWithDeletion(BuildContext context) async {
final actionResult = await showChoiceActionSheet(
context,

View File

@@ -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);

View File

@@ -289,7 +289,7 @@ Future<MediaUploadData> _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<MediaUploadData> _getMediaUploadDataFromAppCache(
}
try {
Map<String, IfdTag>? exifData;
final Uint8List? thumbnailData = await SharedAssertService.getThumbnail(
final Uint8List? thumbnailData = await SharedAssetService.getThumbnail(
file.localID!,
file.isVideo,
);

View File

@@ -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<File?> getFile(
}
}
Future<bool> doesLocalFileExist(EnteFile file) async {
return await _getLocalDiskFile(file) != null;
}
Future<File?> _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<File?> _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);

View File

@@ -105,7 +105,7 @@ Future<Uint8List?> getThumbnailFromLocal(
}
if (file.isSharedMediaToAppSandbox) {
//todo:neeraj support specifying size/quality
return SharedAssertService.getThumbnail(
return SharedAssetService.getThumbnail(
file.localID!,
file.isVideo,
).then((data) {