LCOV - code coverage report
Current view: top level - src - beam_page.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 58 58 100.0 %
Date: 2021-07-18 19:09:57 Functions: 0 0 -

          Line data    Source code
       1             : import 'package:flutter/cupertino.dart';
       2             : import 'package:flutter/material.dart';
       3             : 
       4             : import '../beamer.dart';
       5             : 
       6             : /// Types for how to route should be built.
       7          10 : enum BeamPageType {
       8             :   material,
       9             :   cupertino,
      10             :   fadeTransition,
      11             :   slideTransition,
      12             :   scaleTransition,
      13             :   noTransition,
      14             : }
      15             : 
      16             : /// A wrapper for screens in a navigation stack.
      17             : class BeamPage extends Page {
      18          17 :   const BeamPage({
      19             :     LocalKey? key,
      20             :     String? name,
      21             :     required this.child,
      22             :     this.title,
      23             :     this.onPopPage = defaultOnPopPage,
      24             :     this.popToNamed,
      25             :     this.type = BeamPageType.material,
      26             :     this.routeBuilder,
      27             :     this.fullScreenDialog = false,
      28             :     this.keepQueryOnPop = false,
      29           6 :   }) : super(key: key, name: name);
      30             : 
      31             :   /// The default pop behavior for [BeamPage].
      32           3 :   static bool defaultOnPopPage(
      33             :     BuildContext context,
      34             :     BeamerDelegate delegate,
      35             :     BeamPage poppedPage,
      36             :   ) {
      37           3 :     final beamLocation = delegate.currentBeamLocation;
      38           9 :     final previousRouteInformation = delegate.routeHistory.length > 1
      39          15 :         ? delegate.routeHistory[delegate.routeHistory.length - 2]
      40             :         : null;
      41             :     final previousUri = previousRouteInformation != null
      42           6 :         ? Uri.parse(previousRouteInformation.location ?? '/')
      43             :         : null;
      44             : 
      45           9 :     final location = beamLocation.state.routeInformation.location ?? '/';
      46           6 :     final pathSegments = Uri.parse(location).pathSegments;
      47           6 :     final queryParameters = Uri.parse(location).queryParameters;
      48           3 :     var popUri = Uri(
      49           6 :       pathSegments: List.from(pathSegments)..removeLast(),
      50           3 :       queryParameters: poppedPage.keepQueryOnPop ? queryParameters : null,
      51             :     );
      52           6 :     final popUriPath = '/' + popUri.path;
      53             : 
      54           3 :     popUri = Uri(
      55           3 :       pathSegments: popUri.pathSegments,
      56             :       queryParameters:
      57           8 :           (popUriPath == previousUri?.path && !poppedPage.keepQueryOnPop)
      58           2 :               ? previousUri?.queryParameters
      59           3 :               : popUri.queryParameters,
      60             :     );
      61             : 
      62           3 :     delegate.removeLastRouteInformation();
      63           3 :     delegate.update(
      64           6 :       configuration: delegate.configuration.copyWith(
      65             :         location:
      66          11 :             popUriPath + (popUri.query.isNotEmpty ? '?${popUri.query}' : ''),
      67             :       ),
      68             :     );
      69             : 
      70             :     return true;
      71             :   }
      72             : 
      73             :   /// The concrete Widget representing app's screen.
      74             :   final Widget child;
      75             : 
      76             :   /// The BeamPage's title. On the web, this is used for the browser tab title.
      77             :   final String? title;
      78             : 
      79             :   /// Overrides the default pop by executing an arbitrary closure.
      80             :   /// Mainly used to manually update the [delegate.currentBeamLocation] state.
      81             :   ///
      82             :   /// [poppedPage] is this [BeamPage].
      83             :   ///
      84             :   /// Return `false` (rarely used) to prevent **any** navigation from happening,
      85             :   /// otherwise return `true`.
      86             :   ///
      87             :   /// More powerful than [popToNamed].
      88             :   final bool Function(
      89             :     BuildContext context,
      90             :     BeamerDelegate delegate,
      91             :     BeamPage poppedPage,
      92             :   ) onPopPage;
      93             : 
      94             :   /// Overrides the default pop by beaming to specified URI string.
      95             :   ///
      96             :   /// Less powerful than [onPopPage].
      97             :   final String? popToNamed;
      98             : 
      99             :   /// The type to determine how a route should be built.
     100             :   ///
     101             :   /// See [BeamPageType] for available types.
     102             :   final BeamPageType type;
     103             : 
     104             :   /// A builder for custom [Route] to use in [createRoute].
     105             :   ///
     106             :   /// [settings] must be passed to [PageRoute.settings].
     107             :   /// [child] is the child of this [BeamPage]
     108             :   final Route Function(RouteSettings settings, Widget child)? routeBuilder;
     109             : 
     110             :   /// Whether to present current [BeamPage] as a fullscreen dialog
     111             :   ///
     112             :   /// On iOS, dialog transitions animate differently and are also not closeable with the back swipe gesture
     113             :   final bool fullScreenDialog;
     114             : 
     115             :   /// When this [BeamPage] pops from [Navigator] stack, whether to keep the
     116             :   /// query parameters within current [BeamLocation].
     117             :   ///
     118             :   /// Defaults to `false`.
     119             :   final bool keepQueryOnPop;
     120             : 
     121           6 :   @override
     122             :   Route createRoute(BuildContext context) {
     123           6 :     if (routeBuilder != null) {
     124           2 :       return routeBuilder!(this, child);
     125             :     }
     126           6 :     switch (type) {
     127           6 :       case BeamPageType.cupertino:
     128           1 :         return CupertinoPageRoute(
     129           1 :           title: title,
     130           1 :           fullscreenDialog: fullScreenDialog,
     131             :           settings: this,
     132           2 :           builder: (context) => child,
     133             :         );
     134           6 :       case BeamPageType.fadeTransition:
     135           1 :         return PageRouteBuilder(
     136           1 :           fullscreenDialog: fullScreenDialog,
     137             :           settings: this,
     138           2 :           pageBuilder: (_, __, ___) => child,
     139           2 :           transitionsBuilder: (_, animation, __, child) => FadeTransition(
     140             :             opacity: animation,
     141             :             child: child,
     142             :           ),
     143             :         );
     144           6 :       case BeamPageType.slideTransition:
     145           1 :         return PageRouteBuilder(
     146           1 :           fullscreenDialog: fullScreenDialog,
     147             :           settings: this,
     148           2 :           pageBuilder: (_, __, ___) => child,
     149           2 :           transitionsBuilder: (_, animation, __, child) => SlideTransition(
     150           1 :             position: animation.drive(
     151           1 :                 Tween(begin: const Offset(0, 1), end: const Offset(0, 0))
     152           2 :                     .chain(CurveTween(curve: Curves.ease))),
     153             :             child: child,
     154             :           ),
     155             :         );
     156           6 :       case BeamPageType.scaleTransition:
     157           1 :         return PageRouteBuilder(
     158           1 :           fullscreenDialog: fullScreenDialog,
     159             :           settings: this,
     160           2 :           pageBuilder: (_, __, ___) => child,
     161           2 :           transitionsBuilder: (_, animation, __, child) => ScaleTransition(
     162             :             scale: animation,
     163             :             child: child,
     164             :           ),
     165             :         );
     166           6 :       case BeamPageType.noTransition:
     167           1 :         return PageRouteBuilder(
     168           1 :           fullscreenDialog: fullScreenDialog,
     169             :           settings: this,
     170           2 :           pageBuilder: (context, animation, secondaryAnimation) => child,
     171             :         );
     172             :       default:
     173           6 :         return MaterialPageRoute(
     174           6 :           fullscreenDialog: fullScreenDialog,
     175             :           settings: this,
     176          12 :           builder: (context) => child,
     177             :         );
     178             :     }
     179             :   }
     180             : }

Generated by: LCOV version 1.14