LCOV - code coverage report
Current view: top level - lib/lib - nav.dart (source / functions) Coverage Total Hit
Test: lcov.info Lines: 61.3 % 75 46
Test Date: 2024-02-05 08:51:01 Functions: - 0 0

            Line data    Source code
       1              : // ignore_for_file: constant_identifier_names
       2              : 
       3              : library nav;
       4              : 
       5              : import 'dart:async';
       6              : 
       7              : import 'package:flutter/cupertino.dart';
       8              : import 'package:flutter/foundation.dart';
       9              : import 'package:nav/enum/enum_nav_ani.dart';
      10              : import 'package:nav/route/r_ripple.dart';
      11              : import 'package:nav/route/r_slide.dart';
      12              : import 'package:nav/screen/nav_screen.dart';
      13              : import 'package:nav/setting/nav_setting.dart';
      14              : 
      15              : export 'package:nav/enum/enum_nav_ani.dart';
      16              : 
      17              : mixin Nav<T extends StatefulWidget> on State<T> {
      18              :   static const int defaultDurationMs = 200;
      19              : 
      20              :   @Deprecated(
      21              :       'It will be removed on Nav 2025 - 3.0. Please use pushForResult Method with Generic instead of comparing string and dynamic')
      22              :   static const RESULT = "result";
      23              : 
      24              :   @Deprecated(
      25              :       'It will be removed on Nav 2025 - 3.0. Please use pushForResult Method with Generic instead of comparing string and dynamic')
      26              :   static const SUCCESS = "success";
      27              :   @Deprecated(
      28              :       'It will be removed on Nav 2025 - 3.0. Please use pushForResult Method with Generic instead of comparing string and dynamic')
      29              :   static const FAIL = "fail";
      30              :   @Deprecated(
      31              :       'It will be removed on Nav 2025 - 3.0. Please use pushForResult Method with Generic instead of comparing string and dynamic')
      32              :   static const CANCEL = "cancel";
      33              :   @Deprecated(
      34              :       'It will be removed on Nav 2025 - 3.0. Please use pushForResult Method with Generic instead of comparing string and dynamic')
      35              :   static const DELETED = "deleted";
      36              :   @Deprecated(
      37              :       'It will be removed on Nav 2025 - 3.0. Please use pushForResult Method with Generic instead of comparing string and dynamic')
      38              :   static const REFRESH = "refresh";
      39              : 
      40              :   GlobalKey<NavigatorState> get navigatorKey;
      41              : 
      42            3 :   static late GlobalKey<NavigatorState> _globalKey;
      43              :   static NavSetting? navSetting;
      44              : 
      45            5 :   @override
      46              :   void initState() {
      47            5 :     super.initState();
      48            5 :     _globalKey = navigatorKey;
      49              :   }
      50              : 
      51              :   ///some library package need to change global key for some purpose.
      52              :   ///It is not recommended to change globalKey because it will reset all the navigation states.
      53            1 :   void setGlobalKey(GlobalKey<NavigatorState> key) {
      54              :     _globalKey = key;
      55              :   }
      56              : 
      57            1 :   static void initialize(NavSetting navSetting) {
      58              :     Nav.navSetting = navSetting;
      59              :   }
      60              : 
      61              :   /// Get navigator state
      62            1 :   static NavigatorState? navigatorState(BuildContext? context) {
      63              :     NavigatorState? state;
      64              :     try {
      65              :       if (context != null) {
      66            1 :         state = Navigator.of(context);
      67              :         return state;
      68              :       } else {
      69            2 :         return _globalKey.currentState;
      70              :       }
      71              :     } catch (e) {
      72            2 :       return _globalKey.currentState;
      73              :     }
      74              :   }
      75              : 
      76            9 :   static BuildContext get globalContext => _globalKey.currentContext!;
      77              : 
      78              :   /// Push screen from right to left
      79              :   ///
      80              :   /// On ios "Swipe back gesture" is default
      81              :   /// Set prohibitSwipeBack true if you don't want allow swipe back.
      82              :   /// If you provide context, you can nest navigate in your specific context
      83            1 :   static Future<T?> pushFromRight<T>(
      84              :     Widget? screen, {
      85              :     bool prohibitSwipeBack = false,
      86              :     BuildContext? context,
      87              :   }) async {
      88              :     if (screen == null) {
      89              :       return null;
      90              :     }
      91            2 :     return navigatorState(context)?.push(
      92            1 :       getPushRightRoute(screen, prohibitSwipeBack: prohibitSwipeBack, context: context) as Route<T>,
      93              :     );
      94              :   }
      95              : 
      96            1 :   static Route<T> getPushRightRoute<T>(Widget screen,
      97              :       {bool prohibitSwipeBack = false,
      98              :       BuildContext? context,
      99              :       int durationMs = Nav.defaultDurationMs}) {
     100            2 :     return TargetPlatform.iOS == defaultTargetPlatform && !prohibitSwipeBack
     101            2 :         ? CupertinoPageRoute<T>(builder: (context) => screen)
     102            1 :         : SlideFromRightRoute<T>(screen, durationMs: durationMs);
     103              :   }
     104              : 
     105              :   /// Push screen from left to right
     106              :   ///
     107              :   /// If you provide context, you can nest navigate in your specific context
     108            0 :   static Future<T?> pushFromLeft<T>(Widget? screen, {BuildContext? context}) async {
     109              :     if (screen == null) {
     110              :       return null;
     111              :     }
     112            0 :     return navigatorState(context)?.push(
     113            0 :       SlideFromLeftRoute(screen),
     114              :     );
     115              :   }
     116              : 
     117              :   /// Push screen from bottom to top
     118              :   ///
     119              :   /// If you provide context, you can nest navigate in your specific context
     120            0 :   static Future<T?> pushFromBottom<T>(Widget screen, {BuildContext? context}) async =>
     121            0 :       navigatorState(context)?.push(
     122            0 :         SlideFromBottomRoute(screen),
     123              :       );
     124              : 
     125              :   /// Push screen from top to bottom
     126              :   ///
     127              :   /// If you provide context, you can nest navigate in your specific context
     128            0 :   static Future<T?> pushFromTop<T>(Widget screen, {BuildContext? context}) async =>
     129            0 :       navigatorState(context)?.push(
     130            0 :         SlideFromTopRoute(screen),
     131              :       );
     132              : 
     133              :   /// Push screen with Ripple Effect (Default: bottomRight to topLeft, You can change the alignment and offset)
     134              :   ///
     135              :   /// If you provide context, you can nest navigate in your specific context
     136            1 :   static Future<T?> pushWithRippleEffect<T>(
     137              :     Widget? screen, {
     138              :     BuildContext? context,
     139              :     AlignmentGeometry? alignment,
     140              :     Offset offset = const Offset(0, 0),
     141              :     int durationMs = Nav.defaultDurationMs,
     142              :   }) async {
     143              :     if (screen == null) {
     144              :       return null;
     145              :     }
     146              : 
     147            5 :     final height = MediaQuery.of(navigatorState(context)!.context).size.height;
     148            5 :     final width = MediaQuery.of(navigatorState(context)!.context).size.width;
     149              : 
     150            2 :     return navigatorState(context)?.push(
     151            1 :       RoundRevealRoute(screen,
     152            2 :           maxRadius: height + width / 2,
     153            1 :           centerAlignment: (alignment == null && offset == const Offset(0, 0))
     154              :               ? Alignment.bottomRight
     155              :               : alignment,
     156              :           centerOffset: offset,
     157              :           minRadius: 10,
     158              :           durationMs: durationMs),
     159              :     );
     160              :   }
     161              : 
     162              :   /// Push screen with NavAni param
     163              :   ///
     164              :   /// If you provide context, you can nest navigate in your specific context
     165            1 :   static Future<T?> push<T>(Widget? screen,
     166              :       {NavAni navAni = NavAni.Right,
     167              :       BuildContext? context,
     168              :       int durationMs = defaultDurationMs}) async {
     169              :     if (screen == null) {
     170              :       return null;
     171              :     }
     172            1 :     return navigatorState(context)
     173            4 :         ?.push(navAni.createRoute(screen, navigatorState(context)!.context, durationMs));
     174              :   }
     175              : 
     176              :   /// Push Replacement screen
     177              :   ///
     178              :   /// If you provide context, you can nest navigate in your specific context
     179            1 :   static Future<T?> pushReplacement<T, TO extends Object>(Widget? screen,
     180              :       {BuildContext? context,
     181              :       NavAni navAni = NavAni.Fade,
     182              :       TO? result,
     183              :       int durationMs = defaultDurationMs}) async {
     184              :     if (screen == null) {
     185              :       return null;
     186              :     }
     187            2 :     return navigatorState(context)?.pushReplacement(
     188            3 :         navAni.createRoute(screen, navigatorState(context)!.context, durationMs),
     189              :         result: result);
     190              :   }
     191              : 
     192              :   /// Clear All screen on navigator state and push the new one.
     193              :   ///
     194              :   /// If you provide context, you can nest navigate in your specific context
     195            1 :   static Future<T?> clearAllAndPush<T>(Widget? screen,
     196              :       {BuildContext? context,
     197              :       NavAni navAni = NavAni.Fade,
     198              :       int durationMs = defaultDurationMs}) async {
     199              :     if (screen == null) {
     200              :       return null;
     201              :     }
     202            2 :     return navigatorState(context)?.pushAndRemoveUntil(
     203            3 :         navAni.createRoute(screen, navigatorState(context)!.context, durationMs),
     204            1 :         (Route<dynamic> route) => false);
     205              :   }
     206              : 
     207            1 :   static Future<Result?> pushResult<Result>(NavScreen<Result> screen,
     208              :       {NavAni navAni = NavAni.Right,
     209              :       BuildContext? context,
     210              :       int durationMs = defaultDurationMs}) async {
     211            1 :     return push<Result>(screen, navAni: navAni, context: context, durationMs: durationMs);
     212              :   }
     213              : 
     214              :   /// Check result is success
     215            0 :   @Deprecated(
     216              :       'It will be removed on Nav 2025 - 3.0. Please use pushForResult Method with Generic instead of comparing string and dynamic')
     217              :   static bool isSuccess(result) {
     218            0 :     return result != null && result[RESULT] == SUCCESS;
     219              :   }
     220              : 
     221              :   /// Check result is fail
     222            0 :   @Deprecated(
     223              :       'It will be removed on Nav 2025 - 3.0. Please use pushForResult Method with Generic instead of comparing string and dynamic')
     224              :   static bool isFail(result) {
     225            0 :     return result != null && result[RESULT] == FAIL;
     226              :   }
     227              : 
     228              :   /// Check result is cancel
     229            0 :   @Deprecated(
     230              :       'It will be removed on Nav 2025 - 3.0. Please use pushForResult Method with Generic instead of comparing string and dynamic')
     231              :   static bool isCancel(result) {
     232            0 :     return result != null && result[RESULT] == CANCEL;
     233              :   }
     234              : 
     235              :   /// Check result is deleted
     236            0 :   @Deprecated(
     237              :       'It will be removed on Nav 2025 - 3.0. Please use pushForResult Method with Generic instead of comparing string and dynamic')
     238              :   static bool isDeleted(result) {
     239            0 :     return result != null && result[RESULT] == DELETED;
     240              :   }
     241              : 
     242              :   /// Check result is refresh
     243            0 :   @Deprecated(
     244              :       'It will be removed on Nav 2025 - 3.0. Please use pushForResult Method with Generic instead of comparing string and dynamic')
     245              :   static bool isRefresh(result) {
     246            0 :     return result != null && result[RESULT] == REFRESH;
     247              :   }
     248              : 
     249              :   /// pop screen with result
     250            1 :   static void pop<T>(BuildContext context, {T? result}) {
     251              :     if (result == null) {
     252            2 :       Navigator.of(context).pop();
     253              :     } else {
     254            2 :       Navigator.of(context).pop(result);
     255              :     }
     256              :   }
     257              : 
     258              :   /// simple pop with success result
     259            0 :   @Deprecated(
     260              :       'It will be removed on Nav 2025 - 3.0. Please use pushForResult Method with Generic instead of comparing string and dynamic')
     261              :   static void popResultSuccess(BuildContext context) {
     262            0 :     pop(context, result: {RESULT: SUCCESS});
     263              :   }
     264              : 
     265              :   /// simple pop with fail result
     266            0 :   @Deprecated(
     267              :       'It will be removed on Nav 2025 - 3.0. Please use pushForResult Method with Generic instead of comparing string and dynamic')
     268              :   static void popResultFail(BuildContext context) {
     269            0 :     pop(context, result: {RESULT: FAIL});
     270              :   }
     271              : 
     272              :   /// simple pop with cancel result
     273            0 :   @Deprecated(
     274              :       'It will be removed on Nav 2025 - 3.0. Please use pushForResult Method with Generic instead of comparing string and dynamic')
     275              :   static void popResultCancel(BuildContext context) {
     276            0 :     pop(context, result: {RESULT: CANCEL});
     277              :   }
     278              : 
     279              :   /// simple pop with delete result
     280            0 :   @Deprecated(
     281              :       'It will be removed on Nav 2025 - 3.0. Please use pushForResult Method with Generic instead of comparing string and dynamic')
     282              :   static void popResultDelete(BuildContext context) {
     283            0 :     pop(context, result: {RESULT: DELETED});
     284              :   }
     285              : 
     286              :   /// simple pop with refresh result
     287            0 :   @Deprecated(
     288              :       'It will be removed on Nav 2025 - 3.0. Please use pushForResult Method with Generic instead of comparing string and dynamic')
     289              :   static void popResultRefresh(BuildContext context) {
     290            0 :     pop(context, result: {RESULT: REFRESH});
     291              :   }
     292              : 
     293              :   /// Check if can pop
     294            1 :   static Future<bool> canPop({BuildContext? context}) async {
     295            3 :     return navigatorState(context)?.canPop() == true;
     296              :   }
     297              : 
     298            1 :   static void clearAll({BuildContext? context}) {
     299            1 :     final state = navigatorState(context);
     300            2 :     while (state?.canPop() == true) {
     301            1 :       state?.pop();
     302              :     }
     303              :   }
     304              : }
        

Generated by: LCOV version 2.0-1