LCOV - code coverage report
Current view: top level - src - router_delegate.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 42 44 95.5 %
Date: 2022-10-22 16:29:45 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             : {
      21             :   /// Creates router delegate.
      22             :   ///
      23           3 :   TheseusRouterDelegate({
      24             :     required this.navigationScheme,
      25             :   }) {
      26           6 :     Log.d(runtimeType, 'TheseusRouterDelegate():');
      27           6 :     _key = GlobalKey<NavigatorState>(debugLabel: 'TheseusNavigator');
      28           9 :     navigationScheme.addListener(_onCurrentDestinationChanged);
      29             :   }
      30             : 
      31             :   /// A navigation scheme that contains destinations and navigators.
      32             :   ///
      33             :   /// This router delegate is listening the navigation scheme to identify if the
      34             :   /// current destination is changed, and in turn, notifies its listeners when this
      35             :   /// happens.
      36             :   ///
      37             :   final NavigationScheme navigationScheme;
      38             : 
      39             :   late final GlobalKey<NavigatorState> _key;
      40             : 
      41           2 :   @override
      42             :   Widget build(BuildContext context) {
      43          10 :     Log.d(runtimeType, 'build(): isResolving=${navigationScheme.isResolving}');
      44           2 :     return Navigator(
      45           2 :       key: _key,
      46           2 :       pages: [
      47           2 :         MaterialPage(
      48             :           key: const ValueKey('TheseusRootPage'),
      49           6 :           child: navigationScheme.rootNavigator.build(context),
      50             :         ),
      51           4 :         if (navigationScheme.isResolving)
      52           2 :           const MaterialPage(
      53             :             child: _TheseusWaitingOverlay(
      54             :               key: Key('_TheseusWaitingOverlay_'),
      55             :             ),
      56             :           ),
      57             :       ],
      58           0 :       onPopPage: (route, result) => route.didPop(result),
      59             :     );
      60             :   }
      61             : 
      62             :   @override
      63           2 :   Future<bool> popRoute() async {
      64           4 :     Log.d(runtimeType, 'popRoute():');
      65           4 :     navigationScheme.goBack();
      66           4 :     if (navigationScheme.shouldClose) {
      67           2 :       if (Platform.isAndroid) {
      68             :         return false;
      69             :       } else {
      70           8 :         navigationScheme.goTo(navigationScheme.currentDestination);
      71             :         return true;
      72             :       }
      73             :     }
      74             :     return true;
      75             :   }
      76             : 
      77             :   @override
      78             :   // ignore: avoid_renaming_method_parameters
      79           3 :   Future<void> setNewRoutePath(destination) async {
      80           9 :     Log.d(runtimeType, 'setNewRoutePath(): destination=$destination');
      81             :     // The current navigation controller stack remains when:
      82             :     // - The 'upwardDestinationBuilder' is not specified, so we shouldn't build a custom stack.
      83             :     // - New destination is an 'errorDestination', from which we should be able return back to previous destination.
      84             :     // Otherwise the stack is reset.
      85           3 :     final reset = (destination.hasUpwardDestinationBuilder &&
      86           6 :         destination != navigationScheme.errorDestination);
      87           9 :     return SynchronousFuture(navigationScheme.goTo(destination
      88           9 :         .withConfiguration(destination.configuration.copyWith(reset: reset))));
      89             :   }
      90             : 
      91           3 :   @override
      92           6 :   Destination get currentConfiguration => navigationScheme.currentDestination;
      93             : 
      94           2 :   @override
      95             :   void dispose() {
      96           6 :     navigationScheme.removeListener(_onCurrentDestinationChanged);
      97           2 :     super.dispose();
      98             :   }
      99             : 
     100           3 :   Future<void> _onCurrentDestinationChanged() async {
     101           6 :     final destination = navigationScheme.currentDestination;
     102           6 :     Log.d(runtimeType,
     103           3 :         'onCurrentDestinationChanged(): destination=$destination');
     104             :     // Ignore closing app request here. It is processed in the 'popRoute()' method.
     105           6 :     if (navigationScheme.shouldClose) {
     106             :       return;
     107             :     }
     108           3 :     notifyListeners();
     109             :   }
     110             : }
     111             : 
     112             : class _TheseusWaitingOverlay extends StatelessWidget {
     113           9 :   const _TheseusWaitingOverlay({
     114             :     Key? key,
     115           0 :   }) : super(key: key);
     116             : 
     117           2 :   @override
     118             :   Widget build(BuildContext context) {
     119           2 :     return Stack(
     120           2 :       children: [
     121           2 :         ModalBarrier(
     122           2 :           color: Colors.black.withAlpha(128),
     123             :           dismissible: false,
     124             :         ),
     125             :         const Center(child: CircularProgressIndicator(),),
     126             :       ],
     127             :     );
     128             :   }
     129             : }

Generated by: LCOV version