1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2025-01-01 08:31:59 +00:00

Implemented auto backup (#11)

This commit is contained in:
Alex 2022-02-07 23:42:35 -06:00 committed by GitHub
parent 2a4d4ea999
commit 919928ab70
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 10715 additions and 31 deletions

View file

@ -4,6 +4,7 @@ import 'package:hive_flutter/hive_flutter.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/shared/providers/app_state.provider.dart'; import 'package:immich_mobile/shared/providers/app_state.provider.dart';
import 'package:immich_mobile/shared/providers/backup.provider.dart';
import 'constants/hive_box.dart'; import 'constants/hive_box.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
@ -36,6 +37,7 @@ class _ImmichAppState extends ConsumerState<ImmichApp> with WidgetsBindingObserv
case AppLifecycleState.resumed: case AppLifecycleState.resumed:
debugPrint("[APP STATE] resumed"); debugPrint("[APP STATE] resumed");
ref.read(appStateProvider.notifier).state = AppStateEnum.resumed; ref.read(appStateProvider.notifier).state = AppStateEnum.resumed;
ref.read(backupProvider.notifier).resumeBackup();
break; break;
case AppLifecycleState.inactive: case AppLifecycleState.inactive:
debugPrint("[APP STATE] inactive"); debugPrint("[APP STATE] inactive");
@ -53,7 +55,7 @@ class _ImmichAppState extends ConsumerState<ImmichApp> with WidgetsBindingObserv
} }
Future<void> initApp() async { Future<void> initApp() async {
// WidgetsBinding.instance?.addObserver(this); WidgetsBinding.instance?.addObserver(this);
} }
@override @override

View file

@ -56,10 +56,9 @@ class ProfileDrawer extends ConsumerWidget {
onTap: () async { onTap: () async {
bool res = await ref.read(authenticationProvider.notifier).logout(); bool res = await ref.read(authenticationProvider.notifier).logout();
ref.read(assetProvider.notifier).clearAllAsset();
if (res) { if (res) {
AutoRouter.of(context).popUntilRoot(); AutoRouter.of(context).popUntilRoot();
ref.read(assetProvider.notifier).clearAllAsset();
} }
}, },
) )

View file

@ -11,7 +11,7 @@ import 'package:immich_mobile/shared/services/network.service.dart';
import 'package:immich_mobile/shared/models/device_info.model.dart'; import 'package:immich_mobile/shared/models/device_info.model.dart';
class AuthenticationNotifier extends StateNotifier<AuthenticationState> { class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
AuthenticationNotifier() AuthenticationNotifier(this.ref)
: super( : super(
AuthenticationState( AuthenticationState(
deviceId: "", deviceId: "",
@ -31,6 +31,7 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
), ),
); );
final Ref ref;
final DeviceInfoService _deviceInfoService = DeviceInfoService(); final DeviceInfoService _deviceInfoService = DeviceInfoService();
final BackupService _backupService = BackupService(); final BackupService _backupService = BackupService();
final NetworkService _networkService = NetworkService(); final NetworkService _networkService = NetworkService();
@ -126,5 +127,5 @@ class AuthenticationNotifier extends StateNotifier<AuthenticationState> {
} }
final authenticationProvider = StateNotifierProvider<AuthenticationNotifier, AuthenticationState>((ref) { final authenticationProvider = StateNotifierProvider<AuthenticationNotifier, AuthenticationState>((ref) {
return AuthenticationNotifier(); return AuthenticationNotifier(ref);
}); });

View file

@ -3,7 +3,9 @@ import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/modules/home/providers/asset.provider.dart';
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart'; import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
import 'package:immich_mobile/shared/providers/backup.provider.dart';
import 'package:immich_mobile/shared/ui/immich_toast.dart'; import 'package:immich_mobile/shared/ui/immich_toast.dart';
class LoginForm extends HookConsumerWidget { class LoginForm extends HookConsumerWidget {
@ -110,11 +112,16 @@ class LoginButton extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
return ElevatedButton( return ElevatedButton(
onPressed: () async { onPressed: () async {
// This will remove current cache asset state of previous user login.
ref.watch(assetProvider.notifier).clearAllAsset();
var isAuthenicated = await ref var isAuthenicated = await ref
.read(authenticationProvider.notifier) .read(authenticationProvider.notifier)
.login(emailController.text, passwordController.text, serverEndpointController.text); .login(emailController.text, passwordController.text, serverEndpointController.text);
if (isAuthenicated) { if (isAuthenicated) {
// Resume backup (if enable) then navigate
ref.watch(backupProvider.notifier).resumeBackup();
AutoRouter.of(context).pushNamed("/home-page"); AutoRouter.of(context).pushNamed("/home-page");
} else { } else {
ImmichToast.show( ImmichToast.show(

View file

@ -1,6 +1,9 @@
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/hive_box.dart';
import 'package:immich_mobile/modules/login/providers/authentication.provider.dart';
import 'package:immich_mobile/shared/services/server_info.service.dart'; import 'package:immich_mobile/shared/services/server_info.service.dart';
import 'package:immich_mobile/shared/models/backup_state.model.dart'; import 'package:immich_mobile/shared/models/backup_state.model.dart';
import 'package:immich_mobile/shared/models/server_info.model.dart'; import 'package:immich_mobile/shared/models/server_info.model.dart';
@ -8,7 +11,7 @@ import 'package:immich_mobile/shared/services/backup.service.dart';
import 'package:photo_manager/photo_manager.dart'; import 'package:photo_manager/photo_manager.dart';
class BackupNotifier extends StateNotifier<BackUpState> { class BackupNotifier extends StateNotifier<BackUpState> {
BackupNotifier() BackupNotifier(this.ref)
: super( : super(
BackUpState( BackUpState(
backupProgress: BackUpProgressEnum.idle, backupProgress: BackUpProgressEnum.idle,
@ -29,6 +32,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
), ),
); );
final Ref ref;
final BackupService _backupService = BackupService(); final BackupService _backupService = BackupService();
final ServerInfoService _serverInfoService = ServerInfoService(); final ServerInfoService _serverInfoService = ServerInfoService();
@ -96,7 +100,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
void cancelBackup() { void cancelBackup() {
state.cancelToken.cancel('Cancel Backup'); state.cancelToken.cancel('Cancel Backup');
state = state.copyWith(backupProgress: BackUpProgressEnum.idle); state = state.copyWith(backupProgress: BackUpProgressEnum.idle, progressInPercentage: 0.0);
} }
void _onAssetUploaded() { void _onAssetUploaded() {
@ -130,8 +134,38 @@ class BackupNotifier extends StateNotifier<BackUpState> {
), ),
); );
} }
void resumeBackup() {
debugPrint("[resumeBackup]");
var authState = ref.read(authenticationProvider);
// Check if user is login
var accessKey = Hive.box(userInfoBox).get(accessTokenKey);
// User has been logged out return
if (accessKey == null || !authState.isAuthenticated) {
debugPrint("[resumeBackup] not authenticated - abort");
return;
}
// Check if this device is enable backup by the user
if ((authState.deviceInfo.deviceId == authState.deviceId) && authState.deviceInfo.isAutoBackup) {
// check if backup is alreayd in process - then return
if (state.backupProgress == BackUpProgressEnum.inProgress) {
debugPrint("[resumeBackup] Backup is already in progress - abort");
return;
}
// Run backup
debugPrint("[resumeBackup] Start back up");
startBackupProcess();
}
debugPrint("[resumeBackup] User disables auto backup");
return;
}
} }
final backupProvider = StateNotifierProvider<BackupNotifier, BackUpState>((ref) { final backupProvider = StateNotifierProvider<BackupNotifier, BackUpState>((ref) {
return BackupNotifier(); return BackupNotifier(ref);
}); });

10685
server/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -44,6 +44,6 @@ import { ServerInfoModule } from './api-v1/server-info/server-info.module';
}) })
export class AppModule implements NestModule { export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer): void { configure(consumer: MiddlewareConsumer): void {
consumer.apply(AppLoggerMiddleware).forRoutes('*'); // consumer.apply(AppLoggerMiddleware).forRoutes('*');
} }
} }