Skip to content

Commit

Permalink
Update app startup logic to be compatible with URL-based navigation a…
Browse files Browse the repository at this point in the history
…nd deep links (#158)

* Start updating the app startup logic

* Remove the /startup route (that was silly)
  • Loading branch information
bizz84 authored Nov 26, 2024
1 parent 2fdc5e7 commit 3615f9d
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 84 deletions.
6 changes: 6 additions & 0 deletions lib/src/app.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:starter_architecture_flutter_firebase/src/routing/app_router.dart';
import 'package:starter_architecture_flutter_firebase/src/routing/app_startup.dart';

class MyApp extends ConsumerWidget {
const MyApp({super.key});
Expand All @@ -12,6 +13,11 @@ class MyApp extends ConsumerWidget {
final goRouter = ref.watch(goRouterProvider);
return MaterialApp.router(
routerConfig: goRouter,
builder: (_, child) {
return AppStartupWidget(
onLoaded: (_) => child!,
);
},
theme: ThemeData(
colorSchemeSeed: primaryColor,
unselectedWidgetColor: Colors.grey,
Expand Down
24 changes: 2 additions & 22 deletions lib/src/routing/app_router.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:riverpod/riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:starter_architecture_flutter_firebase/src/routing/app_startup.dart';
import 'package:starter_architecture_flutter_firebase/src/features/authentication/data/firebase_auth_repository.dart';
import 'package:starter_architecture_flutter_firebase/src/features/authentication/presentation/custom_profile_screen.dart';
import 'package:starter_architecture_flutter_firebase/src/features/authentication/presentation/custom_sign_in_screen.dart';
Expand Down Expand Up @@ -43,18 +42,12 @@ enum AppRoute {

@riverpod
GoRouter goRouter(Ref ref) {
// rebuild GoRouter when app startup state changes
final appStartupState = ref.watch(appStartupProvider);
final authRepository = ref.watch(authRepositoryProvider);
return GoRouter(
initialLocation: '/signIn',
navigatorKey: _rootNavigatorKey,
debugLogDiagnostics: true,
redirect: (context, state) {
// If the app is still initializing, show the /startup route
if (appStartupState.isLoading || appStartupState.hasError) {
return '/startup';
}
final onboardingRepository =
ref.read(onboardingRepositoryProvider).requireValue;
final didCompleteOnboarding = onboardingRepository.isOnboardingComplete();
Expand All @@ -69,14 +62,11 @@ GoRouter goRouter(Ref ref) {
}
final isLoggedIn = authRepository.currentUser != null;
if (isLoggedIn) {
if (path.startsWith('/startup') ||
path.startsWith('/onboarding') ||
path.startsWith('/signIn')) {
if (path.startsWith('/onboarding') || path.startsWith('/signIn')) {
return '/jobs';
}
} else {
if (path.startsWith('/startup') ||
path.startsWith('/onboarding') ||
if (path.startsWith('/onboarding') ||
path.startsWith('/jobs') ||
path.startsWith('/entries') ||
path.startsWith('/account')) {
Expand All @@ -87,16 +77,6 @@ GoRouter goRouter(Ref ref) {
},
refreshListenable: GoRouterRefreshStream(authRepository.authStateChanges()),
routes: [
GoRoute(
path: '/startup',
pageBuilder: (context, state) => NoTransitionPage(
child: AppStartupWidget(
// * This is just a placeholder
// * The loaded route will be managed by GoRouter on state change
onLoaded: (_) => const SizedBox.shrink(),
),
),
),
GoRoute(
path: '/onboarding',
name: AppRoute.onboarding.name,
Expand Down
13 changes: 13 additions & 0 deletions lib/src/routing/app_startup.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ Future<void> appStartup(Ref ref) async {
// ensure dependent providers are disposed as well
ref.invalidate(onboardingRepositoryProvider);
});
// Uncomment this to test that URL-based navigation and deep linking works
// even when there's a delay in the app startup logic
// await Future.delayed(Duration(seconds: 1));
// await for all initialization code to be complete before returning
await ref.watch(onboardingRepositoryProvider.future);
}
Expand Down Expand Up @@ -76,3 +79,13 @@ class AppStartupErrorWidget extends StatelessWidget {
);
}
}

class AppStartupDataWidget extends StatelessWidget {
const AppStartupDataWidget({super.key, required this.child});
final Widget child;

@override
Widget build(BuildContext context) {
return child;
}
}
Loading

0 comments on commit 3615f9d

Please sign in to comment.