mirror of
https://github.com/immich-app/immich.git
synced 2025-12-06 17:23:10 +03:00
Compare commits
3 Commits
feat/widge
...
feat/mobil
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
295943e0b5 | ||
|
|
6c343bf2ed | ||
|
|
a3e8701f0a |
42
mobile/lib/models/backup/backup_candidate.model.dart
Normal file
42
mobile/lib/models/backup/backup_candidate.model.dart
Normal file
@@ -0,0 +1,42 @@
|
||||
// ignore_for_file: public_member_api_docs, sort_constructors_first
|
||||
|
||||
import 'package:photo_manager/photo_manager.dart';
|
||||
|
||||
class BackupCandidate {
|
||||
final String id;
|
||||
final List<String> albumName;
|
||||
final AssetEntity asset;
|
||||
|
||||
BackupCandidate({
|
||||
required this.id,
|
||||
required this.albumName,
|
||||
required this.asset,
|
||||
});
|
||||
|
||||
BackupCandidate copyWith({
|
||||
String? id,
|
||||
List<String>? albumName,
|
||||
AssetEntity? asset,
|
||||
}) {
|
||||
return BackupCandidate(
|
||||
id: id ?? this.id,
|
||||
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.id == id &&
|
||||
other.albumName == albumName &&
|
||||
other.asset == asset;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => id.hashCode ^ albumName.hashCode ^ asset.hashCode;
|
||||
}
|
||||
@@ -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<AvailableAlbum> excludedBackupAlbums;
|
||||
|
||||
/// Assets that are not overlapping in selected backup albums and excluded backup albums
|
||||
final Set<AssetEntity> allUniqueAssets;
|
||||
final Set<BackupCandidate> allUniqueAssets;
|
||||
|
||||
/// All assets from the selected albums that have been backup
|
||||
final Set<String> selectedAlbumsBackupAssetsIds;
|
||||
@@ -94,7 +94,7 @@ class BackUpState {
|
||||
List<AvailableAlbum>? availableAlbums,
|
||||
Set<AvailableAlbum>? selectedBackupAlbums,
|
||||
Set<AvailableAlbum>? excludedBackupAlbums,
|
||||
Set<AssetEntity>? allUniqueAssets,
|
||||
Set<BackupCandidate>? allUniqueAssets,
|
||||
Set<String>? selectedAlbumsBackupAssetsIds,
|
||||
CurrentUploadAsset? currentUploadAsset,
|
||||
}) {
|
||||
|
||||
@@ -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,10 +290,12 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
/// Those assets are unique and are used as the total assets
|
||||
///
|
||||
Future<void> _updateBackupAssetCount() async {
|
||||
debugPrint("UPDATE BACKUP ASSET COUNTTT");
|
||||
final duplicatedAssetIds = await _backupService.getDuplicatedAssetIds();
|
||||
final Set<AssetEntity> assetsFromSelectedAlbums = {};
|
||||
final Set<AssetEntity> assetsFromExcludedAlbums = {};
|
||||
final Set<BackupCandidate> assetsFromSelectedAlbums = {};
|
||||
final Set<BackupCandidate> assetsFromExcludedAlbums = {};
|
||||
|
||||
/// Extracing assets from selected albums
|
||||
for (final album in state.selectedBackupAlbums) {
|
||||
final assetCount = await album.albumEntity.assetCountAsync;
|
||||
|
||||
@@ -304,9 +307,19 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
start: 0,
|
||||
end: assetCount,
|
||||
);
|
||||
assetsFromSelectedAlbums.addAll(assets);
|
||||
|
||||
final candidate = assets.map(
|
||||
(e) => BackupCandidate(
|
||||
id: e.id,
|
||||
albumName: [album.albumEntity.name],
|
||||
asset: e,
|
||||
),
|
||||
);
|
||||
|
||||
assetsFromSelectedAlbums.addAll(candidate.toSet());
|
||||
}
|
||||
|
||||
/// Extracing assets from excluded albums
|
||||
for (final album in state.excludedBackupAlbums) {
|
||||
final assetCount = await album.albumEntity.assetCountAsync;
|
||||
|
||||
@@ -318,29 +331,48 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
start: 0,
|
||||
end: assetCount,
|
||||
);
|
||||
assetsFromExcludedAlbums.addAll(assets);
|
||||
|
||||
final candidate = assets.map(
|
||||
(e) => BackupCandidate(
|
||||
id: e.id,
|
||||
albumName: [album.albumEntity.name],
|
||||
asset: e,
|
||||
),
|
||||
);
|
||||
|
||||
assetsFromExcludedAlbums.addAll(candidate);
|
||||
}
|
||||
|
||||
final Set<AssetEntity> allUniqueAssets =
|
||||
Set<BackupCandidate> allUniqueAssets =
|
||||
assetsFromSelectedAlbums.difference(assetsFromExcludedAlbums);
|
||||
final allAssetsInDatabase = await _backupService.getDeviceBackupAsset();
|
||||
|
||||
final allAssetsInDatabase = await _backupService.getDeviceBackupAsset();
|
||||
if (allAssetsInDatabase == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find asset that were backup from selected albums
|
||||
final Set<String> 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),
|
||||
);
|
||||
|
||||
/// Merge different album name of the same id
|
||||
allUniqueAssets = allUniqueAssets.map((e) {
|
||||
final List<String> albumNames = allUniqueAssets
|
||||
.where((a) => a.id == e.id)
|
||||
.map((a) => a.albumName)
|
||||
.expand((e) => e)
|
||||
.toList();
|
||||
return e.copyWith(albumName: albumNames);
|
||||
}).toSet();
|
||||
|
||||
if (allUniqueAssets.isEmpty) {
|
||||
log.info("No assets are selected for back up");
|
||||
state = state.copyWith(
|
||||
@@ -359,6 +391,8 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
|
||||
// Save to persistent storage
|
||||
await _updatePersistentAlbumsSelection();
|
||||
|
||||
debugPrint("backup asset ${allUniqueAssets.length}", wrapWidth: 80);
|
||||
}
|
||||
|
||||
/// Get all necessary information for calculating the available albums,
|
||||
@@ -505,7 +539,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
if (isDuplicated) {
|
||||
state = state.copyWith(
|
||||
allUniqueAssets: state.allUniqueAssets
|
||||
.where((asset) => asset.id != deviceAssetId)
|
||||
.where((e) => e.asset.id != deviceAssetId)
|
||||
.toSet(),
|
||||
);
|
||||
} else {
|
||||
@@ -522,7 +556,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
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(
|
||||
|
||||
Reference in New Issue
Block a user