LCOV - code coverage report
Current view: top level - src - router_delegate.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 51 55 92.7 %
Date: 2023-03-02 15:31:08 Functions: 0 0 -

          Line data    Source code
       1             : import 'package:flutter/foundation.dart';
       2             : import 'package:flutter/material.dart';
       3             : 
       4             : import 'destination.dart';
       5             : import 'navigation_controller.dart';
       6             : import 'navigation_scheme.dart';
       7             : import 'utils/utils.dart';
       8             : 
       9             : /// Implementation of [RouterDelegate].
      10             : ///
      11             : /// Uses [navigationScheme] to build routes.
      12             : ///
      13             : /// See also:
      14             : /// - [NavigationScheme]
      15             : /// - [NavigationController]
      16             : /// - [Destination]
      17             : ///
      18             : class TheseusRouterDelegate extends RouterDelegate<Destination>
      19             :     with ChangeNotifier {
      20             :   /// Creates router delegate.
      21             :   ///
      22           5 :   TheseusRouterDelegate({
      23             :     required this.navigationScheme,
      24             :   }) {
      25          10 :     Log.d(runtimeType, 'TheseusRouterDelegate():');
      26          10 :     _key = GlobalKey<NavigatorState>(debugLabel: 'TheseusNavigator');
      27          15 :     navigationScheme.addListener(_onCurrentDestinationChanged);
      28             :   }
      29             : 
      30             :   /// A navigation scheme that contains destinations and navigators.
      31             :   ///
      32             :   /// This router delegate is listening the navigation scheme to identify if the
      33             :   /// current destination is changed, and in turn, notifies its listeners when this
      34             :   /// happens.
      35             :   ///
      36             :   final NavigationScheme navigationScheme;
      37             : 
      38             :   late final GlobalKey<NavigatorState> _key;
      39             : 
      40           2 :   @override
      41             :   Widget build(BuildContext context) {
      42          10 :     Log.d(runtimeType, 'build(): isResolving=${navigationScheme.isResolving}');
      43           2 :     return Navigator(
      44           2 :       key: _key,
      45           2 :       pages: [
      46           2 :         MaterialPage(
      47             :           key: const ValueKey('TheseusRootPage'),
      48           6 :           child: navigationScheme.rootNavigator.build(context),
      49             :         ),
      50           4 :         if (navigationScheme.isResolving)
      51           2 :           _TheseusPageOverlay(
      52           4 :             child: navigationScheme.waitingOverlayBuilder
      53           6 :                     ?.call(context, navigationScheme.currentDestination) ??
      54             :                 const _TheseusWaitingOverlay(
      55             :                   key: Key('_TheseusWaitingOverlay_'),
      56             :                 ),
      57             :           ),
      58             :       ],
      59           0 :       onPopPage: (route, result) {
      60           0 :         Log.d(runtimeType, 'onPopPage()');
      61           0 :         return route.didPop(result);
      62             :       },
      63             :     );
      64             :   }
      65             : 
      66             :   @override
      67           2 :   Future<bool> popRoute() async {
      68           4 :     Log.d(runtimeType, 'popRoute():');
      69           4 :     navigationScheme.goBack();
      70           4 :     if (navigationScheme.shouldClose) {
      71           2 :       if (Platform.isAndroid) {
      72             :         return false;
      73             :       } else {
      74           8 :         navigationScheme.goTo(navigationScheme.currentDestination);
      75             :         return true;
      76             :       }
      77             :     }
      78             :     return true;
      79             :   }
      80             : 
      81             :   @override
      82             :   // ignore: avoid_renaming_method_parameters
      83           3 :   Future<void> setNewRoutePath(destination) async {
      84           9 :     if (destination == navigationScheme.currentDestination) {
      85           9 :       Log.d(runtimeType, 'setNewRoutePath(): Ignore navigation to $destination. It is already the current destination.');
      86             :       return;
      87             :     }
      88           6 :     Log.d(runtimeType, 'setNewRoutePath(): destination=$destination');
      89             :     // The current navigation stack is reset if the new destination is not an error.
      90           6 :     final reset = destination != navigationScheme.errorDestination;
      91           4 :     return navigationScheme.goTo(
      92           6 :         destination.withSettings(destination.settings.copyWith(reset: reset)));
      93             :   }
      94             : 
      95           3 :   @override
      96           6 :   Destination get currentConfiguration => navigationScheme.currentDestination;
      97             : 
      98           3 :   @override
      99             :   void dispose() {
     100           9 :     navigationScheme.removeListener(_onCurrentDestinationChanged);
     101           3 :     super.dispose();
     102             :   }
     103             : 
     104           4 :   Future<void> _onCurrentDestinationChanged() async {
     105           8 :     final destination = navigationScheme.currentDestination;
     106           4 :     Log.d(
     107           8 :         runtimeType, 'onCurrentDestinationChanged(): destination=$destination');
     108             :     // Ignore closing app request here. It is processed in the 'popRoute()' method.
     109           8 :     if (navigationScheme.shouldClose) {
     110             :       return;
     111             :     }
     112           4 :     notifyListeners();
     113             :   }
     114             : }
     115             : 
     116             : class _TheseusPageOverlay extends Page {
     117           2 :   const _TheseusPageOverlay({
     118             :     required this.child,
     119             :     LocalKey? key,
     120           2 :   }) : super(key: key);
     121             : 
     122             :   final Widget child;
     123             : 
     124           2 :   @override
     125             :   Route createRoute(BuildContext context) {
     126           2 :     return PageRouteBuilder(
     127             :       settings: this,
     128             :       opaque: false,
     129           4 :       pageBuilder: (context, animation, secondaryAnimation) => child,
     130           2 :       transitionsBuilder: (context, animation, secondaryAnimation, child) =>
     131             :           child,
     132             :     );
     133             :   }
     134             : }
     135             : 
     136             : class _TheseusWaitingOverlay extends StatelessWidget {
     137          11 :   const _TheseusWaitingOverlay({
     138             :     Key? key,
     139           0 :   }) : super(key: key);
     140             : 
     141           2 :   @override
     142             :   Widget build(BuildContext context) {
     143           2 :     return Stack(
     144           2 :       children: [
     145           2 :         ModalBarrier(
     146           2 :           color: Colors.black.withAlpha(128),
     147             :           dismissible: false,
     148             :         ),
     149             :         const Center(
     150             :           child: CircularProgressIndicator(),
     151             :         ),
     152             :       ],
     153             :     );
     154             :   }
     155             : }

Generated by: LCOV version