NavigationLogic constructor

NavigationLogic({
  1. required List<RouteBase> routes,
  2. AlertController? alertController,
  3. Stream? authState,
  4. Widget defaultLoading()?,
  5. Widget defaultLoadingOverlay()?,
  6. List<NavigationItem>? defaultMenuItems,
  7. FeatureAccessController? featureAccessController,
  8. void initialiseRoute(
    1. BuildContext context
    )?,
  9. int parentDepth = 1,
  10. SmartBackOrder smartBackOrder = SmartBackOrder.backThenUp,
  11. bool useSmartBack = false,
  12. GlobalKey<NavigatorState>? navigatorKey,
  13. GoRouterWidgetBuilder? errorBuilder,
  14. SlickRoute? initialLocation,
  15. String? accessDeniedPath,
  16. String? signInPath,
  17. String? signOutPath,
  18. bool ignoreSystemRouter = false,
})

Creates a new NavigationLogic instance with GoRouter.

accessDeniedPath - Path to redirect unauthorized users (e.g., '/access-denied' or AccessDeniedRoute().location) authState - Optional stream for authentication state changes defaultMenuItems - Default menu items (optional) defaultLoading - Default loading widget (e.g. a spinner) defaultLoadingOveraly - Default loading overlay widget errorBuilder - Function that returns an error screen, e.g. not found (Optional but recommended) featureAccessController - Optional controller for route permission checks ignoreSystemRouter - Bypass / ignore the system router, e.g. browser history (optional: default to false) navigatorKey - Navigator Key (optional) initialiseRoute - Global callback that runs when any route is entered (optional) parentDepth - The maximum depth a matching parent route can be for canGoUp and goUp (optional: default to 1, immediate parent) routes - List of GoRoute definitions for the application (use $appRoutes generated in e.g. routes.g.dart) signInPath - Path to redirect unauthenticated users (e.g., '/sign-in' or SignInRoute().location) signOutPath - Path for signing out users (e.g., '/sign-out' or SignOutRoute().location) smartBackOrder - The order for _smartGoBack useSmartBack - Whether to use "smart Back": navigate to a parent before using the history stack

Implementation

NavigationLogic({
  required List<RouteBase> routes,
  this.alertController,
  this.authState,
  this.defaultLoading,
  this.defaultLoadingOverlay,
  this.defaultMenuItems,
  this.featureAccessController,
  this.initialiseRoute,
  this.parentDepth = 1,
  this.smartBackOrder = SmartBackOrder.backThenUp,
  this.useSmartBack = false,
  GlobalKey<NavigatorState>? navigatorKey,
  GoRouterWidgetBuilder? errorBuilder,
  SlickRoute? initialLocation,
  String? accessDeniedPath,
  String? signInPath,
  String? signOutPath,
  bool ignoreSystemRouter = false,
})  : _signInPath = signInPath,
      _signOutPath = signOutPath,
      _accessDeniedPath = accessDeniedPath,
      assert(
        featureAccessController == null ||
            (signInPath != null && accessDeniedPath != null),
        '`signInPath` and `accessDeniedPath` must be provided when using `featureAccessController`',
      ) {
  if (!_navigationLogicInitialised) {
    GetIt.instance.registerSingleton(this);
    _navigationLogicInitialised = true;
  } else {
    throw Exception('Only one instance of NavigationLogic can be created');
  }

  defaultLoading ??= () => const DefaultLoading();
  _initialLocation = initialLocation;

  // Initialize GoRouter with redirect logic for authentication and permissions
  goRouter = GoRouter(
    navigatorKey: navigatorKey,
    initialLocation: initialLocation?.location,
    routes: routes,
    redirect: _handleRedirect,
    refreshListenable: this,
    routerNeglect: ignoreSystemRouter,
    errorBuilder: errorBuilder,
    // errorBuilder:
  );

  // Listen to route changes to sync with browser navigation
  goRouter.routeInformationProvider.addListener(_onRouteChanged);
  if (initialiseRoute != null) {
    goRouter.routeInformationProvider
        .addListener(_onRouteChangedForInitialise);
  }

  final auth = authState;
  if (auth != null) {
    _onAuthStateChangedSubscription = auth.listen(_onAuthStateChanged);
  } else {
    _isInitialising = false;
  }

  if (!DirtyStateMonitor.isInitialised) {
    DirtyStateMonitor.initialise();
  }
}