feat(mobile): Adds onboarding for permissions (#1865)

* adds onboarding

* fixed error where login was taking you to permission page

* fixed a bad rebase and added more checks to not start backup service on login if no gallery permission

* forgot the permission handler import in AppDelegate

* reverts album selection page

* change to ref watch

* added device_info_plus to podspec

* removed unused import

---------

Co-authored-by: Marty Fuhry <marty@fuhry.farm>
This commit is contained in:
martyfuhry
2023-02-28 11:22:18 -05:00
committed by GitHub
parent df1710f4cc
commit 12217bde8a
21 changed files with 510 additions and 55 deletions

View File

@@ -0,0 +1,19 @@
import 'package:auto_route/auto_route.dart';
import 'package:immich_mobile/modules/onboarding/providers/gallery_permission.provider.dart';
import 'package:immich_mobile/routing/router.dart';
class GalleryPermissionGuard extends AutoRouteGuard {
final GalleryPermissionNotifier _permission;
GalleryPermissionGuard(this._permission);
@override
void onNavigation(NavigationResolver resolver, StackRouter router) async {
final p = _permission.hasPermission;
if (p) {
resolver.next(true);
} else {
router.replaceAll([const PermissionOnboardingRoute()]);
}
}
}

View File

@@ -19,11 +19,14 @@ import 'package:immich_mobile/modules/favorite/views/favorites_page.dart';
import 'package:immich_mobile/modules/home/views/home_page.dart';
import 'package:immich_mobile/modules/login/views/change_password_page.dart';
import 'package:immich_mobile/modules/login/views/login_page.dart';
import 'package:immich_mobile/modules/onboarding/providers/gallery_permission.provider.dart';
import 'package:immich_mobile/modules/onboarding/views/permission_onboarding_page.dart';
import 'package:immich_mobile/modules/search/views/search_page.dart';
import 'package:immich_mobile/modules/search/views/search_result_page.dart';
import 'package:immich_mobile/modules/settings/views/settings_page.dart';
import 'package:immich_mobile/routing/auth_guard.dart';
import 'package:immich_mobile/routing/duplicate_guard.dart';
import 'package:immich_mobile/routing/gallery_permission_guard.dart';
import 'package:immich_mobile/shared/models/asset.dart';
import 'package:immich_mobile/shared/models/album.dart';
import 'package:immich_mobile/shared/providers/api.provider.dart';
@@ -39,6 +42,7 @@ part 'router.gr.dart';
replaceInRouteName: 'Page,Route',
routes: <AutoRoute>[
AutoRoute(page: SplashScreenPage, initial: true),
AutoRoute(page: PermissionOnboardingPage, guards: [AuthGuard, DuplicateGuard]),
AutoRoute(page: LoginPage,
guards: [
DuplicateGuard,
@@ -47,7 +51,7 @@ part 'router.gr.dart';
AutoRoute(page: ChangePasswordPage),
CustomRoute(
page: TabControllerPage,
guards: [AuthGuard, DuplicateGuard],
guards: [AuthGuard, DuplicateGuard, GalleryPermissionGuard],
children: [
AutoRoute(page: HomePage, guards: [AuthGuard, DuplicateGuard]),
AutoRoute(page: SearchPage, guards: [AuthGuard, DuplicateGuard]),
@@ -56,7 +60,7 @@ part 'router.gr.dart';
],
transitionsBuilder: TransitionsBuilders.fadeIn,
),
AutoRoute(page: GalleryViewerPage, guards: [AuthGuard, DuplicateGuard]),
AutoRoute(page: GalleryViewerPage, guards: [AuthGuard, DuplicateGuard, GalleryPermissionGuard]),
AutoRoute(page: VideoViewerPage, guards: [AuthGuard, DuplicateGuard]),
AutoRoute(page: BackupControllerPage, guards: [AuthGuard, DuplicateGuard]),
AutoRoute(page: SearchResultPage, guards: [AuthGuard, DuplicateGuard]),
@@ -101,12 +105,15 @@ class AppRouter extends _$AppRouter {
// ignore: unused_field
final ApiService _apiService;
AppRouter(this._apiService)
: super(
AppRouter(
this._apiService,
GalleryPermissionNotifier galleryPermissionNotifier,
) : super(
authGuard: AuthGuard(_apiService),
duplicateGuard: DuplicateGuard(),
galleryPermissionGuard: GalleryPermissionGuard(galleryPermissionNotifier),
);
}
final appRouterProvider =
Provider((ref) => AppRouter(ref.watch(apiServiceProvider)));
Provider((ref) => AppRouter(ref.watch(apiServiceProvider), ref.watch(galleryPermissionNotifier.notifier)));

View File

@@ -15,13 +15,16 @@ part of 'router.dart';
class _$AppRouter extends RootStackRouter {
_$AppRouter({
GlobalKey<NavigatorState>? navigatorKey,
required this.duplicateGuard,
required this.authGuard,
required this.duplicateGuard,
required this.galleryPermissionGuard,
}) : super(navigatorKey);
final AuthGuard authGuard;
final DuplicateGuard duplicateGuard;
final AuthGuard authGuard;
final GalleryPermissionGuard galleryPermissionGuard;
@override
final Map<String, PageFactory> pagesMap = {
@@ -31,6 +34,12 @@ class _$AppRouter extends RootStackRouter {
child: const SplashScreenPage(),
);
},
PermissionOnboardingRoute.name: (routeData) {
return MaterialPageX<dynamic>(
routeData: routeData,
child: const PermissionOnboardingPage(),
);
},
LoginRoute.name: (routeData) {
return MaterialPageX<dynamic>(
routeData: routeData,
@@ -225,6 +234,14 @@ class _$AppRouter extends RootStackRouter {
SplashScreenRoute.name,
path: '/',
),
RouteConfig(
PermissionOnboardingRoute.name,
path: '/permission-onboarding-page',
guards: [
authGuard,
duplicateGuard,
],
),
RouteConfig(
LoginRoute.name,
path: '/login-page',
@@ -240,6 +257,7 @@ class _$AppRouter extends RootStackRouter {
guards: [
authGuard,
duplicateGuard,
galleryPermissionGuard,
],
children: [
RouteConfig(
@@ -286,6 +304,7 @@ class _$AppRouter extends RootStackRouter {
guards: [
authGuard,
duplicateGuard,
galleryPermissionGuard,
],
),
RouteConfig(
@@ -411,6 +430,18 @@ class SplashScreenRoute extends PageRouteInfo<void> {
static const String name = 'SplashScreenRoute';
}
/// generated route for
/// [PermissionOnboardingPage]
class PermissionOnboardingRoute extends PageRouteInfo<void> {
const PermissionOnboardingRoute()
: super(
PermissionOnboardingRoute.name,
path: '/permission-onboarding-page',
);
static const String name = 'PermissionOnboardingRoute';
}
/// generated route for
/// [LoginPage]
class LoginRoute extends PageRouteInfo<void> {