diff --git a/mobile/ios/fastlane/Fastfile b/mobile/ios/fastlane/Fastfile index 8fc1ed9f0..314ab0e22 100644 --- a/mobile/ios/fastlane/Fastfile +++ b/mobile/ios/fastlane/Fastfile @@ -19,7 +19,7 @@ platform :ios do desc "iOS Beta" lane :beta do increment_version_number( - version_number: "1.13.0" + version_number: "1.12.1" ) increment_build_number( build_number: latest_testflight_build_number + 1, diff --git a/mobile/lib/constants/hive_box.dart b/mobile/lib/constants/hive_box.dart index fd9642aa7..336e8fc4c 100644 --- a/mobile/lib/constants/hive_box.dart +++ b/mobile/lib/constants/hive_box.dart @@ -2,18 +2,17 @@ const String userInfoBox = "immichBoxUserInfo"; // Box const String accessTokenKey = "immichBoxAccessTokenKey"; // Key 1 const String deviceIdKey = 'immichBoxDeviceIdKey'; // Key 2 - -// Server endpoint -const String serverEndpointKey = 'immichBoxServerEndpoint'; +const String isLoggedInKey = 'immichIsLoggedInKey'; // Key 3 +const String serverEndpointKey = 'immichBoxServerEndpoint'; // Key 4 // Login Info -const String hiveLoginInfoBox = "immichLoginInfoBox"; -const String savedLoginInfoKey = "immichSavedLoginInfoKey"; +const String hiveLoginInfoBox = "immichLoginInfoBox"; // Box +const String savedLoginInfoKey = "immichSavedLoginInfoKey"; // Key 1 // Backup Info -const String hiveBackupInfoBox = "immichBackupAlbumInfoBox"; -const String backupInfoKey = "immichBackupAlbumInfoKey"; +const String hiveBackupInfoBox = "immichBackupAlbumInfoBox"; // Box +const String backupInfoKey = "immichBackupAlbumInfoKey"; // Key 1 // Github Release Info -const String hiveGithubReleaseInfoBox = "immichGithubReleaseInfoBox"; -const String githubReleaseInfoKey = "immichGithubReleaseInfoKey"; +const String hiveGithubReleaseInfoBox = "immichGithubReleaseInfoBox"; // Box +const String githubReleaseInfoKey = "immichGithubReleaseInfoKey"; // Key 1 diff --git a/mobile/lib/modules/home/ui/profile_drawer.dart b/mobile/lib/modules/home/ui/profile_drawer.dart index 46866605c..2221a652c 100644 --- a/mobile/lib/modules/home/ui/profile_drawer.dart +++ b/mobile/lib/modules/home/ui/profile_drawer.dart @@ -6,6 +6,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:image_picker/image_picker.dart'; import 'package:immich_mobile/constants/hive_box.dart'; import 'package:immich_mobile/modules/home/providers/upload_profile_image.provider.dart'; +import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/shared/providers/asset.provider.dart'; import 'package:immich_mobile/modules/login/models/authentication_state.model.dart'; import 'package:immich_mobile/modules/login/providers/authentication.provider.dart'; @@ -185,7 +186,8 @@ class ProfileDrawer extends HookConsumerWidget { ref.watch(backupProvider.notifier).cancelBackup(); ref.watch(assetProvider.notifier).clearAllAsset(); ref.watch(websocketProvider.notifier).disconnect(); - AutoRouter.of(context).popUntilRoot(); + // AutoRouter.of(context).popUntilRoot(); + AutoRouter.of(context).replace(const LoginRoute()); } }, ) diff --git a/mobile/lib/modules/login/ui/login_form.dart b/mobile/lib/modules/login/ui/login_form.dart index 0a0e84ea9..5dae8e4bd 100644 --- a/mobile/lib/modules/login/ui/login_form.dart +++ b/mobile/lib/modules/login/ui/login_form.dart @@ -67,7 +67,7 @@ class LoginForm extends HookConsumerWidget { shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5)), enableFeedback: true, title: const Text( - "Save login", + "Stay logged in", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold, color: Colors.grey), ), value: isSaveLoginInfo.value, diff --git a/mobile/lib/routing/router.dart b/mobile/lib/routing/router.dart index 27a82e43f..b520f49a1 100644 --- a/mobile/lib/routing/router.dart +++ b/mobile/lib/routing/router.dart @@ -18,6 +18,7 @@ import 'package:immich_mobile/routing/auth_guard.dart'; import 'package:immich_mobile/shared/models/immich_asset.model.dart'; import 'package:immich_mobile/modules/backup/views/backup_controller_page.dart'; import 'package:immich_mobile/modules/asset_viewer/views/image_viewer_page.dart'; +import 'package:immich_mobile/shared/views/splash_screen.dart'; import 'package:immich_mobile/shared/views/tab_controller_page.dart'; import 'package:immich_mobile/modules/asset_viewer/views/video_viewer_page.dart'; import 'package:photo_manager/photo_manager.dart'; @@ -27,8 +28,9 @@ part 'router.gr.dart'; @MaterialAutoRouter( replaceInRouteName: 'Page,Route', routes: [ - AutoRoute(page: LoginPage, initial: true), - AutoRoute( + AutoRoute(page: SplashScreenPage, initial: true), + AutoRoute(page: LoginPage), + CustomRoute( page: TabControllerPage, guards: [AuthGuard], children: [ @@ -36,6 +38,7 @@ part 'router.gr.dart'; AutoRoute(page: SearchPage, guards: [AuthGuard]), AutoRoute(page: SharingPage, guards: [AuthGuard]) ], + transitionsBuilder: TransitionsBuilders.fadeIn, ), AutoRoute(page: ImageViewerPage, guards: [AuthGuard]), AutoRoute(page: VideoViewerPage, guards: [AuthGuard]), diff --git a/mobile/lib/routing/router.gr.dart b/mobile/lib/routing/router.gr.dart index d59e33470..4cf533818 100644 --- a/mobile/lib/routing/router.gr.dart +++ b/mobile/lib/routing/router.gr.dart @@ -21,13 +21,21 @@ class _$AppRouter extends RootStackRouter { @override final Map pagesMap = { + SplashScreenRoute.name: (routeData) { + return MaterialPageX( + routeData: routeData, child: const SplashScreenPage()); + }, LoginRoute.name: (routeData) { return MaterialPageX( routeData: routeData, child: const LoginPage()); }, TabControllerRoute.name: (routeData) { - return MaterialPageX( - routeData: routeData, child: const TabControllerPage()); + return CustomPage( + routeData: routeData, + child: const TabControllerPage(), + transitionsBuilder: TransitionsBuilders.fadeIn, + opaque: true, + barrierDismissible: false); }, ImageViewerRoute.name: (routeData) { final args = routeData.argsAs(); @@ -121,7 +129,8 @@ class _$AppRouter extends RootStackRouter { @override List get routes => [ - RouteConfig(LoginRoute.name, path: '/'), + RouteConfig(SplashScreenRoute.name, path: '/'), + RouteConfig(LoginRoute.name, path: '/login-page'), RouteConfig(TabControllerRoute.name, path: '/tab-controller-page', guards: [ @@ -167,10 +176,18 @@ class _$AppRouter extends RootStackRouter { ]; } +/// generated route for +/// [SplashScreenPage] +class SplashScreenRoute extends PageRouteInfo { + const SplashScreenRoute() : super(SplashScreenRoute.name, path: '/'); + + static const String name = 'SplashScreenRoute'; +} + /// generated route for /// [LoginPage] class LoginRoute extends PageRouteInfo { - const LoginRoute() : super(LoginRoute.name, path: '/'); + const LoginRoute() : super(LoginRoute.name, path: '/login-page'); static const String name = 'LoginRoute'; } diff --git a/mobile/lib/shared/services/network.service.dart b/mobile/lib/shared/services/network.service.dart index 6998cc159..206099aad 100644 --- a/mobile/lib/shared/services/network.service.dart +++ b/mobile/lib/shared/services/network.service.dart @@ -128,7 +128,7 @@ class NetworkService { String validUrl = Uri.parse('$savedEndpoint/server-info/ping').toString(); - debugPrint("pint server at url $validUrl"); + debugPrint("ping server at url $validUrl"); Response res = await dio.get(validUrl); var jsonRespsonse = jsonDecode(res.toString()); diff --git a/mobile/lib/shared/views/splash_screen.dart b/mobile/lib/shared/views/splash_screen.dart new file mode 100644 index 000000000..206d8c17a --- /dev/null +++ b/mobile/lib/shared/views/splash_screen.dart @@ -0,0 +1,72 @@ +import 'package:auto_route/auto_route.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_hooks/flutter_hooks.dart'; +import 'package:hive_flutter/hive_flutter.dart'; +import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/constants/hive_box.dart'; +import 'package:immich_mobile/constants/immich_colors.dart'; +import 'package:immich_mobile/modules/backup/providers/backup.provider.dart'; +import 'package:immich_mobile/modules/login/models/hive_saved_login_info.model.dart'; +import 'package:immich_mobile/modules/login/providers/authentication.provider.dart'; +import 'package:immich_mobile/routing/router.dart'; + +class SplashScreenPage extends HookConsumerWidget { + const SplashScreenPage({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context, WidgetRef ref) { + HiveSavedLoginInfo? loginInfo = Hive.box(hiveLoginInfoBox).get(savedLoginInfoKey); + + void performLoggingIn() async { + var isAuthenticated = await ref + .read(authenticationProvider.notifier) + .login(loginInfo!.email, loginInfo.password, loginInfo.serverUrl, true); + + if (isAuthenticated) { + // Resume backup (if enable) then navigate + ref.watch(backupProvider.notifier).resumeBackup(); + AutoRouter.of(context).pushNamed("/tab-controller-page"); + } else { + AutoRouter.of(context).push(const LoginRoute()); + } + } + + useEffect(() { + if (loginInfo != null && loginInfo.isSaveLogin) { + performLoggingIn(); + } else { + AutoRouter.of(context).push(const LoginRoute()); + } + return null; + }, []); + + return Scaffold( + backgroundColor: immichBackgroundColor, + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Image( + image: AssetImage('assets/immich-logo-no-outline.png'), + width: 200, + filterQuality: FilterQuality.high, + ), + Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + 'IMMICH', + style: TextStyle( + fontFamily: 'SnowburstOne', + fontWeight: FontWeight.bold, + fontSize: 48, + color: Theme.of(context).primaryColor, + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 30e8aee89..51ee30611 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -2,7 +2,7 @@ name: immich_mobile description: Immich - selfhosted backup media file on mobile phone publish_to: "none" -version: 1.13.0+19 +version: 1.12.1+19 environment: sdk: ">=2.15.1 <3.0.0"