LCOV - code coverage report
Current view: top level - src - router_delegate.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 48 51 94.1 %
Date: 2022-12-25 21:41:53 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           0 :                     ?.call(context, navigationScheme.currentDestination) ??
      54             :                 const _TheseusWaitingOverlay(
      55             :                   key: Key('_TheseusWaitingOverlay_'),
      56             :                 ),
      57             :           ),
      58             :       ],
      59           0 :       onPopPage: (route, result) => route.didPop(result),
      60             :     );
      61             :   }
      62             : 
      63             :   @override
      64           2 :   Future<bool> popRoute() async {
      65           4 :     Log.d(runtimeType, 'popRoute():');
      66           4 :     navigationScheme.goBack();
      67           4 :     if (navigationScheme.shouldClose) {
      68           2 :       if (Platform.isAndroid) {
      69             :         return false;
      70             :       } else {
      71           8 :         navigationScheme.goTo(navigationScheme.currentDestination);
      72             :         return true;
      73             :       }
      74             :     }
      75             :     return true;
      76             :   }
      77             : 
      78             :   @override
      79             :   // ignore: avoid_renaming_method_parameters
      80           3 :   Future<void> setNewRoutePath(destination) async {
      81           9 :     Log.d(runtimeType, 'setNewRoutePath(): destination=$destination');
      82             :     // The current navigation stack is reset if the new destination is not an error.
      83           9 :     final reset = destination != navigationScheme.errorDestination;
      84           9 :     return SynchronousFuture(navigationScheme.goTo(destination
      85           9 :         .withSettings(destination.settings.copyWith(reset: reset))));
      86             :   }
      87             : 
      88           3 :   @override
      89           6 :   Destination get currentConfiguration => navigationScheme.currentDestination;
      90             : 
      91           3 :   @override
      92             :   void dispose() {
      93           9 :     navigationScheme.removeListener(_onCurrentDestinationChanged);
      94           3 :     super.dispose();
      95             :   }
      96             : 
      97           4 :   Future<void> _onCurrentDestinationChanged() async {
      98           8 :     final destination = navigationScheme.currentDestination;
      99           4 :     Log.d(
     100           8 :         runtimeType, 'onCurrentDestinationChanged(): destination=$destination');
     101             :     // Ignore closing app request here. It is processed in the 'popRoute()' method.
     102           8 :     if (navigationScheme.shouldClose) {
     103             :       return;
     104             :     }
     105           4 :     notifyListeners();
     106             :   }
     107             : }
     108             : 
     109             : class _TheseusPageOverlay extends Page {
     110           2 :   const _TheseusPageOverlay({
     111             :     required this.child,
     112             :     LocalKey? key,
     113           2 :   }) : super(key: key);
     114             : 
     115             :   final Widget child;
     116             : 
     117           2 :   @override
     118             :   Route createRoute(BuildContext context) {
     119           2 :     return PageRouteBuilder(
     120             :       settings: this,
     121             :       opaque: false,
     122           4 :       pageBuilder: (context, animation, secondaryAnimation) => child,
     123           2 :       transitionsBuilder: (context, animation, secondaryAnimation, child) =>
     124             :           child,
     125             :     );
     126             :   }
     127             : }
     128             : 
     129             : class _TheseusWaitingOverlay extends StatelessWidget {
     130          10 :   const _TheseusWaitingOverlay({
     131             :     Key? key,
     132           0 :   }) : super(key: key);
     133             : 
     134           2 :   @override
     135             :   Widget build(BuildContext context) {
     136           2 :     return Stack(
     137           2 :       children: [
     138           2 :         ModalBarrier(
     139           2 :           color: Colors.black.withAlpha(128),
     140             :           dismissible: false,
     141             :         ),
     142             :         const Center(
     143             :           child: CircularProgressIndicator(),
     144             :         ),
     145             :       ],
     146             :     );
     147             :   }
     148             : }

Generated by: LCOV version