diff --git a/mobile/lib/models/backup/backup_candidate.model.dart b/mobile/lib/models/backup/backup_candidate.model.dart new file mode 100644 index 0000000000..cbbc3e7961 --- /dev/null +++ b/mobile/lib/models/backup/backup_candidate.model.dart @@ -0,0 +1,36 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first + +import 'package:photo_manager/photo_manager.dart'; + +class BackupCandidate { + final String albumName; + final AssetEntity asset; + + BackupCandidate({ + required this.albumName, + required this.asset, + }); + + BackupCandidate copyWith({ + String? albumName, + AssetEntity? asset, + }) { + return BackupCandidate( + albumName: albumName ?? this.albumName, + asset: asset ?? this.asset, + ); + } + + @override + String toString() => 'BackupCandidate(albumName: $albumName, asset: $asset)'; + + @override + bool operator ==(covariant BackupCandidate other) { + if (identical(this, other)) return true; + + return other.albumName == albumName && other.asset == asset; + } + + @override + int get hashCode => albumName.hashCode ^ asset.hashCode; +} diff --git a/mobile/lib/models/backup/backup_state.model.dart b/mobile/lib/models/backup/backup_state.model.dart index bb693a5b75..d829f411fc 100644 --- a/mobile/lib/models/backup/backup_state.model.dart +++ b/mobile/lib/models/backup/backup_state.model.dart @@ -2,7 +2,7 @@ import 'package:cancellation_token_http/http.dart'; import 'package:collection/collection.dart'; -import 'package:photo_manager/photo_manager.dart'; +import 'package:immich_mobile/models/backup/backup_candidate.model.dart'; import 'package:immich_mobile/models/backup/available_album.model.dart'; import 'package:immich_mobile/models/backup/current_upload_asset.model.dart'; @@ -41,7 +41,7 @@ class BackUpState { final Set excludedBackupAlbums; /// Assets that are not overlapping in selected backup albums and excluded backup albums - final Set allUniqueAssets; + final Set allUniqueAssets; /// All assets from the selected albums that have been backup final Set selectedAlbumsBackupAssetsIds; @@ -94,7 +94,7 @@ class BackUpState { List? availableAlbums, Set? selectedBackupAlbums, Set? excludedBackupAlbums, - Set? allUniqueAssets, + Set? allUniqueAssets, Set? selectedAlbumsBackupAssetsIds, CurrentUploadAsset? currentUploadAsset, }) { diff --git a/mobile/lib/providers/backup/backup.provider.dart b/mobile/lib/providers/backup/backup.provider.dart index 58027e3b94..315cb53571 100644 --- a/mobile/lib/providers/backup/backup.provider.dart +++ b/mobile/lib/providers/backup/backup.provider.dart @@ -6,6 +6,7 @@ import 'package:flutter/widgets.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/models/backup/available_album.model.dart'; import 'package:immich_mobile/entities/backup_album.entity.dart'; +import 'package:immich_mobile/models/backup/backup_candidate.model.dart'; import 'package:immich_mobile/models/backup/backup_state.model.dart'; import 'package:immich_mobile/models/backup/current_upload_asset.model.dart'; import 'package:immich_mobile/models/backup/error_upload_asset.model.dart'; @@ -289,9 +290,10 @@ class BackupNotifier extends StateNotifier { /// Those assets are unique and are used as the total assets /// Future _updateBackupAssetCount() async { + debugPrint("UPDATE BACKUP ASSET COUNTTT"); final duplicatedAssetIds = await _backupService.getDuplicatedAssetIds(); - final Set assetsFromSelectedAlbums = {}; - final Set assetsFromExcludedAlbums = {}; + final Set assetsFromSelectedAlbums = {}; + final Set assetsFromExcludedAlbums = {}; for (final album in state.selectedBackupAlbums) { final assetCount = await album.albumEntity.assetCountAsync; @@ -304,7 +306,12 @@ class BackupNotifier extends StateNotifier { start: 0, end: assetCount, ); - assetsFromSelectedAlbums.addAll(assets); + + final candidate = assets.map( + (e) => BackupCandidate(albumName: album.albumEntity.name, asset: e), + ); + + assetsFromSelectedAlbums.addAll(candidate.toSet()); } for (final album in state.excludedBackupAlbums) { @@ -318,10 +325,15 @@ class BackupNotifier extends StateNotifier { start: 0, end: assetCount, ); - assetsFromExcludedAlbums.addAll(assets); + + final candidate = assets.map( + (e) => BackupCandidate(albumName: album.albumEntity.name, asset: e), + ); + + assetsFromExcludedAlbums.addAll(candidate); } - final Set allUniqueAssets = + final Set allUniqueAssets = assetsFromSelectedAlbums.difference(assetsFromExcludedAlbums); final allAssetsInDatabase = await _backupService.getDeviceBackupAsset(); @@ -331,14 +343,14 @@ class BackupNotifier extends StateNotifier { // Find asset that were backup from selected albums final Set selectedAlbumsBackupAssets = - Set.from(allUniqueAssets.map((e) => e.id)); + Set.from(allUniqueAssets.map((e) => e.asset.id)); selectedAlbumsBackupAssets .removeWhere((assetId) => !allAssetsInDatabase.contains(assetId)); // Remove duplicated asset from all unique assets allUniqueAssets.removeWhere( - (asset) => duplicatedAssetIds.contains(asset.id), + (e) => duplicatedAssetIds.contains(e.asset.id), ); if (allUniqueAssets.isEmpty) { @@ -359,6 +371,8 @@ class BackupNotifier extends StateNotifier { // Save to persistent storage await _updatePersistentAlbumsSelection(); + + debugPrint("backup asset $allUniqueAssets", wrapWidth: 80); } /// Get all necessary information for calculating the available albums, @@ -505,7 +519,7 @@ class BackupNotifier extends StateNotifier { if (isDuplicated) { state = state.copyWith( allUniqueAssets: state.allUniqueAssets - .where((asset) => asset.id != deviceAssetId) + .where((e) => e.asset.id != deviceAssetId) .toSet(), ); } else { @@ -522,7 +536,7 @@ class BackupNotifier extends StateNotifier { state.selectedAlbumsBackupAssetsIds.length == 0) { final latestAssetBackup = - state.allUniqueAssets.map((e) => e.modifiedDateTime).reduce( + state.allUniqueAssets.map((e) => e.asset.modifiedDateTime).reduce( (v, e) => e.isAfter(v) ? e : v, ); state = state.copyWith(