8 changed files with 171 additions and 39 deletions
			
			
		@ -1,41 +1,63 @@ | 
				
			|||||||
// ignore: prefer_mixin | 
					// ignore: prefer_mixin | 
				
			||||||
import 'package:flutter/material.dart'; | 
					import 'package:flutter/material.dart'; | 
				
			||||||
 | 
					import 'package:go_router/go_router.dart'; | 
				
			||||||
import 'package:neon/neon.dart'; | 
					import 'package:neon/neon.dart'; | 
				
			||||||
 | 
					import 'package:provider/provider.dart'; | 
				
			||||||
 | 
					
 | 
				
			||||||
class AppRouter extends RouterDelegate<Account> with ChangeNotifier, PopNavigatorRouterDelegateMixin<Account> { | 
					part 'router.g.dart'; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AppRouter extends GoRouter { | 
				
			||||||
  AppRouter({ | 
					  AppRouter({ | 
				
			||||||
    required this.navigatorKey, | 
					    required final GlobalKey<NavigatorState> navigatorKey, | 
				
			||||||
    required this.accountsBloc, | 
					    required final AccountsBloc accountsBloc, | 
				
			||||||
  }); | 
					  }) : super( | 
				
			||||||
 | 
					          refreshListenable: StreamListenable.behaviorSubject(accountsBloc.activeAccount), | 
				
			||||||
 | 
					          navigatorKey: navigatorKey, | 
				
			||||||
 | 
					          initialLocation: const HomeRoute().location, | 
				
			||||||
 | 
					          redirect: (final context, final state) { | 
				
			||||||
 | 
					            final account = accountsBloc.activeAccount.valueOrNull; | 
				
			||||||
 | 
					
 | 
				
			||||||
  final AccountsBloc accountsBloc; | 
					            if (account == null) { | 
				
			||||||
 | 
					              return const LoginRoute().location; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override | 
					            if (state.location == const LoginRoute().location) { | 
				
			||||||
  final GlobalKey<NavigatorState> navigatorKey; | 
					              return const HomeRoute().location; | 
				
			||||||
 | 
					            } | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override | 
					            return null; | 
				
			||||||
  Future setNewRoutePath(final Account? configuration) async {} | 
					          }, | 
				
			||||||
 | 
					          routes: $appRoutes, | 
				
			||||||
 | 
					        ); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override | 
					@TypedGoRoute<LoginRoute>( | 
				
			||||||
  Account? get currentConfiguration => accountsBloc.activeAccount.valueOrNull; | 
					  path: '/login', | 
				
			||||||
 | 
					  name: 'login', | 
				
			||||||
 | 
					) | 
				
			||||||
 | 
					@immutable | 
				
			||||||
 | 
					class LoginRoute extends GoRouteData { | 
				
			||||||
 | 
					  const LoginRoute({this.server}); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final String? server; | 
				
			||||||
 | 
					
 | 
				
			||||||
  @override | 
					  @override | 
				
			||||||
  Widget build(final BuildContext context) => Navigator( | 
					  Widget build(final BuildContext context, final GoRouterState state) => LoginPage(serverURL: server); | 
				
			||||||
        key: navigatorKey, | 
					} | 
				
			||||||
        onPopPage: (final route, final result) => route.didPop(result), | 
					
 | 
				
			||||||
        pages: [ | 
					@TypedGoRoute<HomeRoute>( | 
				
			||||||
          if (currentConfiguration == null) ...[ | 
					  path: '/', | 
				
			||||||
            const MaterialPage( | 
					 | 
				
			||||||
              child: LoginPage(), | 
					 | 
				
			||||||
            ), | 
					 | 
				
			||||||
          ] else ...[ | 
					 | 
				
			||||||
            MaterialPage( | 
					 | 
				
			||||||
  name: 'home', | 
					  name: 'home', | 
				
			||||||
              child: HomePage( | 
					) | 
				
			||||||
                key: Key(currentConfiguration!.id), | 
					@immutable | 
				
			||||||
              ), | 
					class HomeRoute extends GoRouteData { | 
				
			||||||
            ), | 
					  const HomeRoute(); | 
				
			||||||
          ], | 
					
 | 
				
			||||||
        ], | 
					  @override | 
				
			||||||
      ); | 
					  Widget build(final BuildContext context, final GoRouterState state) { | 
				
			||||||
 | 
					    final accountsBloc = Provider.of<AccountsBloc>(context, listen: false); | 
				
			||||||
 | 
					    final account = accountsBloc.activeAccount.valueOrNull!; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return HomePage(key: Key(account.id)); | 
				
			||||||
 | 
					  } | 
				
			||||||
} | 
					} | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,57 @@ | 
				
			|||||||
 | 
					// GENERATED CODE - DO NOT MODIFY BY HAND | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					part of 'router.dart'; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ************************************************************************** | 
				
			||||||
 | 
					// GoRouterGenerator | 
				
			||||||
 | 
					// ************************************************************************** | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					List<RouteBase> get $appRoutes => [ | 
				
			||||||
 | 
					      $loginRoute, | 
				
			||||||
 | 
					      $homeRoute, | 
				
			||||||
 | 
					    ]; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RouteBase get $loginRoute => GoRouteData.$route( | 
				
			||||||
 | 
					      path: '/login', | 
				
			||||||
 | 
					      name: 'login', | 
				
			||||||
 | 
					      factory: $LoginRouteExtension._fromState, | 
				
			||||||
 | 
					    ); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extension $LoginRouteExtension on LoginRoute { | 
				
			||||||
 | 
					  static LoginRoute _fromState(GoRouterState state) => LoginRoute( | 
				
			||||||
 | 
					        server: state.queryParameters['server'], | 
				
			||||||
 | 
					      ); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String get location => GoRouteData.$location( | 
				
			||||||
 | 
					        '/login', | 
				
			||||||
 | 
					        queryParams: { | 
				
			||||||
 | 
					          if (server != null) 'server': server, | 
				
			||||||
 | 
					        }, | 
				
			||||||
 | 
					      ); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void go(BuildContext context) => context.go(location); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Future<T?> push<T>(BuildContext context) => context.push<T>(location); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void pushReplacement(BuildContext context) => context.pushReplacement(location); | 
				
			||||||
 | 
					} | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RouteBase get $homeRoute => GoRouteData.$route( | 
				
			||||||
 | 
					      path: '/', | 
				
			||||||
 | 
					      name: 'home', | 
				
			||||||
 | 
					      factory: $HomeRouteExtension._fromState, | 
				
			||||||
 | 
					    ); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extension $HomeRouteExtension on HomeRoute { | 
				
			||||||
 | 
					  static HomeRoute _fromState(GoRouterState state) => const HomeRoute(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  String get location => GoRouteData.$location( | 
				
			||||||
 | 
					        '/', | 
				
			||||||
 | 
					      ); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void go(BuildContext context) => context.go(location); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Future<T?> push<T>(BuildContext context) => context.push<T>(location); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void pushReplacement(BuildContext context) => context.pushReplacement(location); | 
				
			||||||
 | 
					} | 
				
			||||||
@ -0,0 +1,38 @@ | 
				
			|||||||
 | 
					part of '../../neon.dart'; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Listenable Stream | 
				
			||||||
 | 
					/// | 
				
			||||||
 | 
					/// A class that implements [Listenable] for a stream. | 
				
			||||||
 | 
					/// Objects need to be manually disposed. | 
				
			||||||
 | 
					class StreamListenable extends ChangeNotifier { | 
				
			||||||
 | 
					  /// Listenable Stream | 
				
			||||||
 | 
					  /// | 
				
			||||||
 | 
					  /// Implementation for all types of [Stream]s. | 
				
			||||||
 | 
					  /// For an implementation tailored towards [BehaviorSubject] have a look at [StreamListenable.behaviorSubject]. | 
				
			||||||
 | 
					  StreamListenable(final Stream<dynamic> stream) { | 
				
			||||||
 | 
					    notifyListeners(); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _subscription = stream.asBroadcastStream().listen((final value) { | 
				
			||||||
 | 
					      notifyListeners(); | 
				
			||||||
 | 
					    }); | 
				
			||||||
 | 
					  } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /// Listenable BehaviorSubject | 
				
			||||||
 | 
					  /// | 
				
			||||||
 | 
					  /// Implementation for a [BehaviorSubject]. It ensures to not unececcary notify listeners. | 
				
			||||||
 | 
					  /// For an implementation tailored towards otnher kinds of [Stream] have a look at [StreamListenable]. | 
				
			||||||
 | 
					  StreamListenable.behaviorSubject(final BehaviorSubject<dynamic> subject) { | 
				
			||||||
 | 
					    _subscription = subject.listen((final value) { | 
				
			||||||
 | 
					      notifyListeners(); | 
				
			||||||
 | 
					    }); | 
				
			||||||
 | 
					  } | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  late final StreamSubscription<dynamic> _subscription; | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override | 
				
			||||||
 | 
					  void dispose() { | 
				
			||||||
 | 
					    unawaited(_subscription.cancel()); | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    super.dispose(); | 
				
			||||||
 | 
					  } | 
				
			||||||
 | 
					} | 
				
			||||||
					Loading…
					
					
				
		Reference in new issue