1
0
mirror of https://github.com/immich-app/immich.git synced 2024-12-25 10:43:13 +02:00

refactor(mobile): store backup settings on device (#2054)

Co-authored-by: Fynn Petersen-Frey <zoodyy@users.noreply.github.com>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
Fynn Petersen-Frey 2023-03-23 16:25:58 +01:00 committed by GitHub
parent 32a065afc7
commit 40832f0ea7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 26 additions and 105 deletions

View File

@ -15,6 +15,7 @@ class BackUpState {
final double progressInPercentage;
final CancellationToken cancelToken;
final ServerInfoResponseDto serverInfo;
final bool autoBackup;
final bool backgroundBackup;
final bool backupRequireWifi;
final bool backupRequireCharging;
@ -40,6 +41,7 @@ class BackUpState {
required this.progressInPercentage,
required this.cancelToken,
required this.serverInfo,
required this.autoBackup,
required this.backgroundBackup,
required this.backupRequireWifi,
required this.backupRequireCharging,
@ -58,6 +60,7 @@ class BackUpState {
double? progressInPercentage,
CancellationToken? cancelToken,
ServerInfoResponseDto? serverInfo,
bool? autoBackup,
bool? backgroundBackup,
bool? backupRequireWifi,
bool? backupRequireCharging,
@ -75,6 +78,7 @@ class BackUpState {
progressInPercentage: progressInPercentage ?? this.progressInPercentage,
cancelToken: cancelToken ?? this.cancelToken,
serverInfo: serverInfo ?? this.serverInfo,
autoBackup: autoBackup ?? this.autoBackup,
backgroundBackup: backgroundBackup ?? this.backgroundBackup,
backupRequireWifi: backupRequireWifi ?? this.backupRequireWifi,
backupRequireCharging:
@ -92,7 +96,7 @@ class BackUpState {
@override
String toString() {
return 'BackUpState(backupProgress: $backupProgress, allAssetsInDatabase: $allAssetsInDatabase, progressInPercentage: $progressInPercentage, cancelToken: $cancelToken, serverInfo: $serverInfo, backgroundBackup: $backgroundBackup, backupRequireWifi: $backupRequireWifi, backupRequireCharging: $backupRequireCharging, backupTriggerDelay: $backupTriggerDelay, availableAlbums: $availableAlbums, selectedBackupAlbums: $selectedBackupAlbums, excludedBackupAlbums: $excludedBackupAlbums, allUniqueAssets: $allUniqueAssets, selectedAlbumsBackupAssetsIds: $selectedAlbumsBackupAssetsIds, currentUploadAsset: $currentUploadAsset)';
return 'BackUpState(backupProgress: $backupProgress, allAssetsInDatabase: $allAssetsInDatabase, progressInPercentage: $progressInPercentage, cancelToken: $cancelToken, serverInfo: $serverInfo, autoBackup: $autoBackup, backgroundBackup: $backgroundBackup, backupRequireWifi: $backupRequireWifi, backupRequireCharging: $backupRequireCharging, backupTriggerDelay: $backupTriggerDelay, availableAlbums: $availableAlbums, selectedBackupAlbums: $selectedBackupAlbums, excludedBackupAlbums: $excludedBackupAlbums, allUniqueAssets: $allUniqueAssets, selectedAlbumsBackupAssetsIds: $selectedAlbumsBackupAssetsIds, currentUploadAsset: $currentUploadAsset)';
}
@override
@ -106,6 +110,7 @@ class BackUpState {
other.progressInPercentage == progressInPercentage &&
other.cancelToken == cancelToken &&
other.serverInfo == serverInfo &&
other.autoBackup == autoBackup &&
other.backgroundBackup == backgroundBackup &&
other.backupRequireWifi == backupRequireWifi &&
other.backupRequireCharging == backupRequireCharging &&
@ -128,6 +133,7 @@ class BackUpState {
progressInPercentage.hashCode ^
cancelToken.hashCode ^
serverInfo.hashCode ^
autoBackup.hashCode ^
backgroundBackup.hashCode ^
backupRequireWifi.hashCode ^
backupRequireCharging.hashCode ^

View File

@ -39,6 +39,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
allAssetsInDatabase: const [],
progressInPercentage: 0,
cancelToken: CancellationToken(),
autoBackup: Store.get(StoreKey.autoBackup, false),
backgroundBackup: false,
backupRequireWifi: Store.get(StoreKey.backupRequireWifi, true),
backupRequireCharging:
@ -121,6 +122,11 @@ class BackupNotifier extends StateNotifier<BackUpState> {
_updateBackupAssetCount();
}
void setAutoBackup(bool enabled) {
Store.put(StoreKey.autoBackup, enabled);
state = state.copyWith(autoBackup: enabled);
}
void configureBackgroundBackup({
bool? enabled,
bool? requireWifi,
@ -550,8 +556,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
}
// Check if this device is enable backup by the user
if ((_authState.deviceInfo.deviceId == _authState.deviceId) &&
_authState.deviceInfo.isAutoBackup) {
if (state.autoBackup) {
// check if backup is alreayd in process - then return
if (state.backupProgress == BackUpProgressEnum.inProgress) {
log.info("[_resumeBackup] Backup is already in progress - abort");
@ -567,7 +572,6 @@ class BackupNotifier extends StateNotifier<BackUpState> {
log.info("[_resumeBackup] Start back up");
await startBackupProcess();
}
return;
}

View File

@ -363,31 +363,6 @@ class BackupService {
return "OTHER";
}
}
Future<DeviceInfoResponseDto> setAutoBackup(
bool status,
String deviceId,
DeviceTypeEnum deviceType,
) async {
try {
var updatedDeviceInfo = await _apiService.deviceInfoApi.upsertDeviceInfo(
UpsertDeviceInfoDto(
deviceId: deviceId,
deviceType: deviceType,
isAutoBackup: status,
),
);
if (updatedDeviceInfo == null) {
throw Exception("Error updating device info");
}
return updatedDeviceInfo;
} catch (e) {
debugPrint("Error setAutoBackup: ${e.toString()}");
throw Error();
}
}
}
class MultipartRequest extends http.MultipartRequest {

View File

@ -10,9 +10,7 @@ import 'package:immich_mobile/modules/backup/providers/error_backup_list.provide
import 'package:immich_mobile/modules/backup/providers/ios_background_settings.provider.dart';
import 'package:immich_mobile/modules/backup/ui/current_backup_asset_info_box.dart';
import 'package:immich_mobile/modules/backup/ui/ios_debug_info_tile.dart';
import 'package:immich_mobile/modules/login/models/authentication_state.model.dart';
import 'package:immich_mobile/modules/backup/models/backup_state.model.dart';
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
import 'package:immich_mobile/modules/backup/providers/backup.provider.dart';
import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/shared/providers/websocket.provider.dart';
@ -26,7 +24,6 @@ class BackupControllerPage extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
BackUpState backupState = ref.watch(backupProvider);
AuthenticationState authenticationState = ref.watch(authenticationProvider);
final settings = ref.watch(iOSBackgroundSettingsProvider.notifier).settings;
final appRefreshDisabled =
@ -102,11 +99,11 @@ class BackupControllerPage extends HookConsumerWidget {
}
ListTile buildAutoBackupController() {
var backUpOption = authenticationState.deviceInfo.isAutoBackup
final isAutoBackup = backupState.autoBackup;
final backUpOption = isAutoBackup
? "backup_controller_page_status_on".tr()
: "backup_controller_page_status_off".tr();
var isAutoBackup = authenticationState.deviceInfo.isAutoBackup;
var backupBtnText = authenticationState.deviceInfo.isAutoBackup
final backupBtnText = isAutoBackup
? "backup_controller_page_turn_off".tr()
: "backup_controller_page_turn_on".tr();
return ListTile(
@ -134,17 +131,9 @@ class BackupControllerPage extends HookConsumerWidget {
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: ElevatedButton(
onPressed: () {
if (isAutoBackup) {
ref
.read(authenticationProvider.notifier)
.setAutoBackup(false);
} else {
ref
.read(authenticationProvider.notifier)
.setAutoBackup(true);
}
},
onPressed: () => ref
.read(backupProvider.notifier)
.setAutoBackup(!isAutoBackup),
child: Text(
backupBtnText,
style: const TextStyle(

View File

@ -28,8 +28,8 @@ class HomePageAppBar extends ConsumerWidget with PreferredSizeWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final BackUpState backupState = ref.watch(backupProvider);
bool isEnableAutoBackup = backupState.backgroundBackup ||
ref.watch(authenticationProvider).deviceInfo.isAutoBackup;
final bool isEnableAutoBackup =
backupState.backgroundBackup || backupState.autoBackup;
final ServerInfoState serverInfoState = ref.watch(serverInfoProvider);
AuthenticationState authState = ref.watch(authenticationProvider);

View File

@ -11,7 +11,6 @@ class AuthenticationState {
final bool isAdmin;
final bool shouldChangePassword;
final String profileImagePath;
final DeviceInfoResponseDto deviceInfo;
AuthenticationState({
required this.deviceId,
required this.deviceType,
@ -23,7 +22,6 @@ class AuthenticationState {
required this.isAdmin,
required this.shouldChangePassword,
required this.profileImagePath,
required this.deviceInfo,
});
AuthenticationState copyWith({
@ -37,7 +35,6 @@ class AuthenticationState {
bool? isAdmin,
bool? shouldChangePassword,
String? profileImagePath,
DeviceInfoResponseDto? deviceInfo,
}) {
return AuthenticationState(
deviceId: deviceId ?? this.deviceId,
@ -50,13 +47,12 @@ class AuthenticationState {
isAdmin: isAdmin ?? this.isAdmin,
shouldChangePassword: shouldChangePassword ?? this.shouldChangePassword,
profileImagePath: profileImagePath ?? this.profileImagePath,
deviceInfo: deviceInfo ?? this.deviceInfo,
);
}
@override
String toString() {
return 'AuthenticationState(deviceId: $deviceId, deviceType: $deviceType, userId: $userId, userEmail: $userEmail, isAuthenticated: $isAuthenticated, firstName: $firstName, lastName: $lastName, isAdmin: $isAdmin, shouldChangePassword: $shouldChangePassword, profileImagePath: $profileImagePath, deviceInfo: $deviceInfo)';
return 'AuthenticationState(deviceId: $deviceId, deviceType: $deviceType, userId: $userId, userEmail: $userEmail, isAuthenticated: $isAuthenticated, firstName: $firstName, lastName: $lastName, isAdmin: $isAdmin, shouldChangePassword: $shouldChangePassword, profileImagePath: $profileImagePath)';
}
@override
@ -73,8 +69,7 @@ class AuthenticationState {
other.lastName == lastName &&
other.isAdmin == isAdmin &&
other.shouldChangePassword == shouldChangePassword &&
other.profileImagePath == profileImagePath &&
other.deviceInfo == deviceInfo;
other.profileImagePath == profileImagePath;
}
@override
@ -88,7 +83,6 @@ class AuthenticationState {
lastName.hashCode ^
isAdmin.hashCode ^
shouldChangePassword.hashCode ^
profileImagePath.hashCode ^
deviceInfo.hashCode;
profileImagePath.hashCode;
}
}

View File

@ -5,7 +5,6 @@ import 'package:flutter/services.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/shared/models/store.dart';
import 'package:immich_mobile/modules/login/models/authentication_state.model.dart';
import 'package:immich_mobile/modules/backup/services/backup.service.dart';
import 'package:immich_mobile/shared/models/user.dart';
import 'package:immich_mobile/shared/providers/api.provider.dart';
import 'package:immich_mobile/shared/services/api.service.dart';
@ -16,7 +15,6 @@ import 'package:openapi/api.dart';
class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
AuthenticationNotifier(
this._deviceInfoService,
this._backupService,
this._apiService,
) : super(
AuthenticationState(
@ -30,19 +28,10 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
isAdmin: false,
shouldChangePassword: false,
isAuthenticated: false,
deviceInfo: DeviceInfoResponseDto(
id: 0,
userId: "",
deviceId: "",
deviceType: DeviceTypeEnum.ANDROID,
createdAt: "",
isAutoBackup: false,
),
),
);
final DeviceInfoService _deviceInfoService;
final BackupService _backupService;
final ApiService _apiService;
Future<bool> login(
@ -103,18 +92,6 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
}
}
setAutoBackup(bool backupState) async {
var deviceInfo = await _deviceInfoService.getDeviceInfo();
var deviceId = deviceInfo["deviceId"];
DeviceTypeEnum deviceType = deviceInfo["deviceType"];
DeviceInfoResponseDto updatedDeviceInfo =
await _backupService.setAutoBackup(backupState, deviceId, deviceType);
state = state.copyWith(deviceInfo: updatedDeviceInfo);
}
updateUserProfileImagePath(String path) {
state = state.copyWith(profileImagePath: path);
}
@ -174,28 +151,6 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
deviceType: deviceInfo["deviceType"],
);
}
// Register device info
try {
DeviceInfoResponseDto? deviceInfo =
await _apiService.deviceInfoApi.upsertDeviceInfo(
UpsertDeviceInfoDto(
deviceId: state.deviceId,
deviceType: state.deviceType,
),
);
if (deviceInfo == null) {
debugPrint('Device Info Response is null');
return false;
}
state = state.copyWith(deviceInfo: deviceInfo);
} catch (e) {
debugPrint("ERROR Register Device Info: $e");
return e is ApiException && e.innerException is SocketException;
}
return true;
}
}
@ -204,7 +159,6 @@ final authenticationProvider =
StateNotifierProvider<AuthenticationNotifier, AuthenticationState>((ref) {
return AuthenticationNotifier(
ref.watch(deviceInfoServiceProvider),
ref.watch(backupServiceProvider),
ref.watch(apiServiceProvider),
);
});

View File

@ -151,6 +151,7 @@ enum StoreKey<T> {
serverUrl<String>(10, type: String),
accessToken<String>(11, type: String),
serverEndpoint<String>(12, type: String),
autoBackup<bool>(13, type: bool),
// user settings from [AppSettingsEnum] below:
loadPreview<bool>(100, type: bool),
loadOriginal<bool>(101, type: bool),

View File

@ -16,7 +16,6 @@ class ApiService {
late AssetApi assetApi;
late SearchApi searchApi;
late ServerInfoApi serverInfoApi;
late DeviceInfoApi deviceInfoApi;
ApiService() {
final endpoint = Store.tryGet(StoreKey.serverEndpoint);
@ -38,7 +37,6 @@ class ApiService {
assetApi = AssetApi(_apiClient);
serverInfoApi = ServerInfoApi(_apiClient);
searchApi = SearchApi(_apiClient);
deviceInfoApi = DeviceInfoApi(_apiClient);
}
Future<String> resolveAndSetEndpoint(String serverUrl) async {