diff --git a/lib/app/router/router.dart b/lib/app/router/router.dart index 89e5bf8..fdcd21f 100644 --- a/lib/app/router/router.dart +++ b/lib/app/router/router.dart @@ -1,21 +1,53 @@ -import 'package:evlve/app/router/router_listenable.dart'; import 'package:evlve/app/router/routes.dart'; +import 'package:evlve/modules/auth/auth.dart'; +import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; part 'router.g.dart'; @riverpod -Raw router(RouterRef ref) { - final notifier = ref.watch(routerListenableProvider.notifier); +GoRouter router(RouterRef ref) { + final authState = ValueNotifier>(const AsyncLoading()); + ref + ..onDispose(authState.dispose) + ..listen(authControllerProvider, (_, value) { + authState.value = value; + }); + final router = GoRouter( - routes: $appRoutes, navigatorKey: rootKey, - debugLogDiagnostics: true, - redirect: notifier.redirect, - refreshListenable: notifier, + refreshListenable: authState, initialLocation: SplashRoute.path, + debugLogDiagnostics: true, + routes: $appRoutes, + redirect: (context, state) { + if (authState.value.unwrapPrevious().hasError) { + return const LoginRoute().location; + } + if (authState.value.isLoading || !authState.value.hasValue) { + return const SplashRoute().location; + } + final auth = authState.value.requireValue; + final isSplash = state.uri.path == const SplashRoute().location; + if (isSplash) { + return auth.map( + loggedIn: (_) { + final currentRoute = state.uri.toString(); + final isLoggingIn = + currentRoute.startsWith(const LoginRoute().location); + return isLoggingIn ? const ScheduleRoute().location : null; + }, + loggedOut: (_) => const LoginRoute().location, + requireOtp: (_) => const OtpRoute().location, + ); + } + + return null; + }, ); + ref.onDispose(router.dispose); + return router; } diff --git a/lib/app/router/router_listenable.dart b/lib/app/router/router_listenable.dart deleted file mode 100644 index 8f5475f..0000000 --- a/lib/app/router/router_listenable.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:evlve/app/router/routes.dart'; -import 'package:evlve/modules/auth/auth.dart'; -import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; -import 'package:riverpod_annotation/riverpod_annotation.dart'; - -part 'router_listenable.g.dart'; - -@riverpod -class RouterListenable extends _$RouterListenable implements Listenable { - VoidCallback? _routerListener; - AuthState? _authState; - - @override - Future build() async { - _authState = await ref.watch( - authControllerProvider.select((value) { - return value.whenOrNull(data: (state) => _authState = state); - }), - ); - - ref.listenSelf((_, __) { - if (state.isLoading) return; - _routerListener?.call(); - }); - } - - /// Redirects the user when our authentication changes - String? redirect(BuildContext context, GoRouterState state) { - if (this.state.isLoading || this.state.hasError) return null; - - return _authState?.map( - loggedIn: (_) { - final currentRoute = state.uri.toString(); - final isLoggingIn = - currentRoute.contains(const LoginRoute().location) || - currentRoute.contains(const SplashRoute().location); - return isLoggingIn ? const ScheduleRoute().location : null; - }, - loggedOut: (_) => const LoginRoute().location, - requireOtp: (_) => const OtpRoute().location, - ); - } - - @override - void addListener(VoidCallback listener) { - _routerListener = listener; - } - - @override - void removeListener(VoidCallback listener) { - _routerListener = null; - } -}