mirror of
https://github.com/immich-app/immich
synced 2025-11-14 17:36:12 +00:00
upload new photos in background with a service (#382)
* properly done background backup service * new concurrency/locking management with heartbeat fix communication erros with Kotlin plugin on start/stop service methods better error handling for BackgroundService public methods Add default notification message when service is running * configurable WiFi & charging requirement for service * use translations in background service
This commit is contained in:
parent
f35ebec7c6
commit
33b1410d82
21 changed files with 1462 additions and 79 deletions
|
|
@ -4,35 +4,45 @@ import 'package:photo_manager/photo_manager.dart';
|
|||
|
||||
class AvailableAlbum {
|
||||
final AssetPathEntity albumEntity;
|
||||
final DateTime? lastBackup;
|
||||
final Uint8List? thumbnailData;
|
||||
AvailableAlbum({
|
||||
required this.albumEntity,
|
||||
this.lastBackup,
|
||||
this.thumbnailData,
|
||||
});
|
||||
|
||||
AvailableAlbum copyWith({
|
||||
AssetPathEntity? albumEntity,
|
||||
DateTime? lastBackup,
|
||||
Uint8List? thumbnailData,
|
||||
}) {
|
||||
return AvailableAlbum(
|
||||
albumEntity: albumEntity ?? this.albumEntity,
|
||||
lastBackup: lastBackup ?? this.lastBackup,
|
||||
thumbnailData: thumbnailData ?? this.thumbnailData,
|
||||
);
|
||||
}
|
||||
|
||||
String get name => albumEntity.name;
|
||||
|
||||
int get assetCount => albumEntity.assetCount;
|
||||
|
||||
String get id => albumEntity.id;
|
||||
|
||||
bool get isAll => albumEntity.isAll;
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'AvailableAlbum(albumEntity: $albumEntity, thumbnailData: $thumbnailData)';
|
||||
'AvailableAlbum(albumEntity: $albumEntity, lastBackup: $lastBackup, thumbnailData: $thumbnailData)';
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is AvailableAlbum &&
|
||||
other.albumEntity == albumEntity &&
|
||||
other.thumbnailData == thumbnailData;
|
||||
return other is AvailableAlbum && other.albumEntity == albumEntity;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => albumEntity.hashCode ^ thumbnailData.hashCode;
|
||||
int get hashCode => albumEntity.hashCode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import 'package:photo_manager/photo_manager.dart';
|
|||
import 'package:immich_mobile/modules/backup/models/available_album.model.dart';
|
||||
import 'package:immich_mobile/modules/backup/models/current_upload_asset.model.dart';
|
||||
|
||||
enum BackUpProgressEnum { idle, inProgress, done }
|
||||
enum BackUpProgressEnum { idle, inProgress, inBackground, done }
|
||||
|
||||
class BackUpState {
|
||||
// enum
|
||||
|
|
@ -15,11 +15,14 @@ class BackUpState {
|
|||
final double progressInPercentage;
|
||||
final CancellationToken cancelToken;
|
||||
final ServerInfoResponseDto serverInfo;
|
||||
final bool backgroundBackup;
|
||||
final bool backupRequireWifi;
|
||||
final bool backupRequireCharging;
|
||||
|
||||
/// All available albums on the device
|
||||
final List<AvailableAlbum> availableAlbums;
|
||||
final Set<AssetPathEntity> selectedBackupAlbums;
|
||||
final Set<AssetPathEntity> excludedBackupAlbums;
|
||||
final Set<AvailableAlbum> selectedBackupAlbums;
|
||||
final Set<AvailableAlbum> excludedBackupAlbums;
|
||||
|
||||
/// Assets that are not overlapping in selected backup albums and excluded backup albums
|
||||
final Set<AssetEntity> allUniqueAssets;
|
||||
|
|
@ -36,6 +39,9 @@ class BackUpState {
|
|||
required this.progressInPercentage,
|
||||
required this.cancelToken,
|
||||
required this.serverInfo,
|
||||
required this.backgroundBackup,
|
||||
required this.backupRequireWifi,
|
||||
required this.backupRequireCharging,
|
||||
required this.availableAlbums,
|
||||
required this.selectedBackupAlbums,
|
||||
required this.excludedBackupAlbums,
|
||||
|
|
@ -50,9 +56,12 @@ class BackUpState {
|
|||
double? progressInPercentage,
|
||||
CancellationToken? cancelToken,
|
||||
ServerInfoResponseDto? serverInfo,
|
||||
bool? backgroundBackup,
|
||||
bool? backupRequireWifi,
|
||||
bool? backupRequireCharging,
|
||||
List<AvailableAlbum>? availableAlbums,
|
||||
Set<AssetPathEntity>? selectedBackupAlbums,
|
||||
Set<AssetPathEntity>? excludedBackupAlbums,
|
||||
Set<AvailableAlbum>? selectedBackupAlbums,
|
||||
Set<AvailableAlbum>? excludedBackupAlbums,
|
||||
Set<AssetEntity>? allUniqueAssets,
|
||||
Set<String>? selectedAlbumsBackupAssetsIds,
|
||||
CurrentUploadAsset? currentUploadAsset,
|
||||
|
|
@ -63,6 +72,10 @@ class BackUpState {
|
|||
progressInPercentage: progressInPercentage ?? this.progressInPercentage,
|
||||
cancelToken: cancelToken ?? this.cancelToken,
|
||||
serverInfo: serverInfo ?? this.serverInfo,
|
||||
backgroundBackup: backgroundBackup ?? this.backgroundBackup,
|
||||
backupRequireWifi: backupRequireWifi ?? this.backupRequireWifi,
|
||||
backupRequireCharging:
|
||||
backupRequireCharging ?? this.backupRequireCharging,
|
||||
availableAlbums: availableAlbums ?? this.availableAlbums,
|
||||
selectedBackupAlbums: selectedBackupAlbums ?? this.selectedBackupAlbums,
|
||||
excludedBackupAlbums: excludedBackupAlbums ?? this.excludedBackupAlbums,
|
||||
|
|
@ -75,7 +88,7 @@ class BackUpState {
|
|||
|
||||
@override
|
||||
String toString() {
|
||||
return 'BackUpState(backupProgress: $backupProgress, allAssetsInDatabase: $allAssetsInDatabase, progressInPercentage: $progressInPercentage, cancelToken: $cancelToken, serverInfo: $serverInfo, availableAlbums: $availableAlbums, selectedBackupAlbums: $selectedBackupAlbums, excludedBackupAlbums: $excludedBackupAlbums, allUniqueAssets: $allUniqueAssets, selectedAlbumsBackupAssetsIds: $selectedAlbumsBackupAssetsIds, currentUploadAsset: $currentUploadAsset)';
|
||||
return 'BackUpState(backupProgress: $backupProgress, allAssetsInDatabase: $allAssetsInDatabase, progressInPercentage: $progressInPercentage, cancelToken: $cancelToken, serverInfo: $serverInfo, backgroundBackup: $backgroundBackup, backupRequireWifi: $backupRequireWifi, backupRequireCharging: $backupRequireCharging, availableAlbums: $availableAlbums, selectedBackupAlbums: $selectedBackupAlbums, excludedBackupAlbums: $excludedBackupAlbums, allUniqueAssets: $allUniqueAssets, selectedAlbumsBackupAssetsIds: $selectedAlbumsBackupAssetsIds, currentUploadAsset: $currentUploadAsset)';
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -89,6 +102,9 @@ class BackUpState {
|
|||
other.progressInPercentage == progressInPercentage &&
|
||||
other.cancelToken == cancelToken &&
|
||||
other.serverInfo == serverInfo &&
|
||||
other.backgroundBackup == backgroundBackup &&
|
||||
other.backupRequireWifi == backupRequireWifi &&
|
||||
other.backupRequireCharging == backupRequireCharging &&
|
||||
collectionEquals(other.availableAlbums, availableAlbums) &&
|
||||
collectionEquals(other.selectedBackupAlbums, selectedBackupAlbums) &&
|
||||
collectionEquals(other.excludedBackupAlbums, excludedBackupAlbums) &&
|
||||
|
|
@ -107,6 +123,9 @@ class BackUpState {
|
|||
progressInPercentage.hashCode ^
|
||||
cancelToken.hashCode ^
|
||||
serverInfo.hashCode ^
|
||||
backgroundBackup.hashCode ^
|
||||
backupRequireWifi.hashCode ^
|
||||
backupRequireCharging.hashCode ^
|
||||
availableAlbums.hashCode ^
|
||||
selectedBackupAlbums.hashCode ^
|
||||
excludedBackupAlbums.hashCode ^
|
||||
|
|
|
|||
|
|
@ -13,9 +13,17 @@ class HiveBackupAlbums {
|
|||
@HiveField(1)
|
||||
List<String> excludedAlbumsIds;
|
||||
|
||||
@HiveField(2, defaultValue: [])
|
||||
List<DateTime> lastSelectedBackupTime;
|
||||
|
||||
@HiveField(3, defaultValue: [])
|
||||
List<DateTime> lastExcludedBackupTime;
|
||||
|
||||
HiveBackupAlbums({
|
||||
required this.selectedAlbumIds,
|
||||
required this.excludedAlbumsIds,
|
||||
required this.lastSelectedBackupTime,
|
||||
required this.lastExcludedBackupTime,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
@ -25,10 +33,16 @@ class HiveBackupAlbums {
|
|||
HiveBackupAlbums copyWith({
|
||||
List<String>? selectedAlbumIds,
|
||||
List<String>? excludedAlbumsIds,
|
||||
List<DateTime>? lastSelectedBackupTime,
|
||||
List<DateTime>? lastExcludedBackupTime,
|
||||
}) {
|
||||
return HiveBackupAlbums(
|
||||
selectedAlbumIds: selectedAlbumIds ?? this.selectedAlbumIds,
|
||||
excludedAlbumsIds: excludedAlbumsIds ?? this.excludedAlbumsIds,
|
||||
lastSelectedBackupTime:
|
||||
lastSelectedBackupTime ?? this.lastSelectedBackupTime,
|
||||
lastExcludedBackupTime:
|
||||
lastExcludedBackupTime ?? this.lastExcludedBackupTime,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -37,6 +51,8 @@ class HiveBackupAlbums {
|
|||
|
||||
result.addAll({'selectedAlbumIds': selectedAlbumIds});
|
||||
result.addAll({'excludedAlbumsIds': excludedAlbumsIds});
|
||||
result.addAll({'lastSelectedBackupTime': lastSelectedBackupTime});
|
||||
result.addAll({'lastExcludedBackupTime': lastExcludedBackupTime});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -45,6 +61,10 @@ class HiveBackupAlbums {
|
|||
return HiveBackupAlbums(
|
||||
selectedAlbumIds: List<String>.from(map['selectedAlbumIds']),
|
||||
excludedAlbumsIds: List<String>.from(map['excludedAlbumsIds']),
|
||||
lastSelectedBackupTime:
|
||||
List<DateTime>.from(map['lastSelectedBackupTime']),
|
||||
lastExcludedBackupTime:
|
||||
List<DateTime>.from(map['lastExcludedBackupTime']),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -60,9 +80,15 @@ class HiveBackupAlbums {
|
|||
|
||||
return other is HiveBackupAlbums &&
|
||||
listEquals(other.selectedAlbumIds, selectedAlbumIds) &&
|
||||
listEquals(other.excludedAlbumsIds, excludedAlbumsIds);
|
||||
listEquals(other.excludedAlbumsIds, excludedAlbumsIds) &&
|
||||
listEquals(other.lastSelectedBackupTime, lastSelectedBackupTime) &&
|
||||
listEquals(other.lastExcludedBackupTime, lastExcludedBackupTime);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => selectedAlbumIds.hashCode ^ excludedAlbumsIds.hashCode;
|
||||
int get hashCode =>
|
||||
selectedAlbumIds.hashCode ^
|
||||
excludedAlbumsIds.hashCode ^
|
||||
lastSelectedBackupTime.hashCode ^
|
||||
lastExcludedBackupTime.hashCode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,17 +19,25 @@ class HiveBackupAlbumsAdapter extends TypeAdapter<HiveBackupAlbums> {
|
|||
return HiveBackupAlbums(
|
||||
selectedAlbumIds: (fields[0] as List).cast<String>(),
|
||||
excludedAlbumsIds: (fields[1] as List).cast<String>(),
|
||||
lastSelectedBackupTime:
|
||||
fields[2] == null ? [] : (fields[2] as List).cast<DateTime>(),
|
||||
lastExcludedBackupTime:
|
||||
fields[3] == null ? [] : (fields[3] as List).cast<DateTime>(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, HiveBackupAlbums obj) {
|
||||
writer
|
||||
..writeByte(2)
|
||||
..writeByte(4)
|
||||
..writeByte(0)
|
||||
..write(obj.selectedAlbumIds)
|
||||
..writeByte(1)
|
||||
..write(obj.excludedAlbumsIds);
|
||||
..write(obj.excludedAlbumsIds)
|
||||
..writeByte(2)
|
||||
..write(obj.lastSelectedBackupTime)
|
||||
..writeByte(3)
|
||||
..write(obj.lastExcludedBackupTime);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue