Schaban

Add Page Middleware

@@ -9,6 +9,7 @@ export 'src/routes/custom_transition.dart'; @@ -9,6 +9,7 @@ export 'src/routes/custom_transition.dart';
9 export 'src/routes/default_route.dart'; 9 export 'src/routes/default_route.dart';
10 export 'src/routes/get_route.dart'; 10 export 'src/routes/get_route.dart';
11 export 'src/routes/observers/route_observer.dart'; 11 export 'src/routes/observers/route_observer.dart';
  12 +export 'src/routes/route_middleware.dart';
12 export 'src/routes/transitions_type.dart'; 13 export 'src/routes/transitions_type.dart';
13 export 'src/snackbar/snack.dart'; 14 export 'src/snackbar/snack.dart';
14 export 'src/snackbar/snack_route.dart'; 15 export 'src/snackbar/snack_route.dart';
@@ -188,7 +188,14 @@ class GetCupertinoApp extends StatelessWidget { @@ -188,7 +188,14 @@ class GetCupertinoApp extends StatelessWidget {
188 super(key: key); 188 super(key: key);
189 189
190 Route<dynamic> generator(RouteSettings settings) { 190 Route<dynamic> generator(RouteSettings settings) {
191 - final match = Get.routeTree.matchRoute(settings.name); 191 + var match = Get.routeTree.matchRoute(settings.name);
  192 +
  193 + final redirect =
  194 + MiddlewareRunner(match.route.middlewares).runOnPageCalled();
  195 + if (!redirect.isNullOrBlank) {
  196 + match = Get.routeTree.matchRoute(redirect);
  197 + }
  198 +
192 Get.parameters = match?.parameters; 199 Get.parameters = match?.parameters;
193 200
194 if (match?.route == null) { 201 if (match?.route == null) {
@@ -207,6 +214,7 @@ class GetCupertinoApp extends StatelessWidget { @@ -207,6 +214,7 @@ class GetCupertinoApp extends StatelessWidget {
207 transition: unknownRoute.transition, 214 transition: unknownRoute.transition,
208 popGesture: unknownRoute.popGesture, 215 popGesture: unknownRoute.popGesture,
209 fullscreenDialog: unknownRoute.fullscreenDialog, 216 fullscreenDialog: unknownRoute.fullscreenDialog,
  217 + middlewares: unknownRoute.middlewares,
210 ); 218 );
211 } 219 }
212 220
@@ -225,6 +233,7 @@ class GetCupertinoApp extends StatelessWidget { @@ -225,6 +233,7 @@ class GetCupertinoApp extends StatelessWidget {
225 transition: match.route.transition, 233 transition: match.route.transition,
226 popGesture: match.route.popGesture, 234 popGesture: match.route.popGesture,
227 fullscreenDialog: match.route.fullscreenDialog, 235 fullscreenDialog: match.route.fullscreenDialog,
  236 + middlewares: match.route.middlewares,
228 ); 237 );
229 } 238 }
230 239
@@ -199,7 +199,14 @@ class GetMaterialApp extends StatelessWidget { @@ -199,7 +199,14 @@ class GetMaterialApp extends StatelessWidget {
199 super(key: key); 199 super(key: key);
200 200
201 Route<dynamic> generator(RouteSettings settings) { 201 Route<dynamic> generator(RouteSettings settings) {
202 - final match = Get.routeTree.matchRoute(settings.name); 202 + var match = Get.routeTree.matchRoute(settings.name);
  203 +
  204 + final redirect =
  205 + MiddlewareRunner(match.route.middlewares).runOnPageCalled();
  206 + if (!redirect.isNullOrBlank) {
  207 + match = Get.routeTree.matchRoute(redirect);
  208 + }
  209 +
203 Get.parameters = match?.parameters; 210 Get.parameters = match?.parameters;
204 211
205 if (match?.route == null) { 212 if (match?.route == null) {
@@ -218,6 +225,7 @@ class GetMaterialApp extends StatelessWidget { @@ -218,6 +225,7 @@ class GetMaterialApp extends StatelessWidget {
218 transition: unknownRoute.transition, 225 transition: unknownRoute.transition,
219 popGesture: unknownRoute.popGesture, 226 popGesture: unknownRoute.popGesture,
220 fullscreenDialog: unknownRoute.fullscreenDialog, 227 fullscreenDialog: unknownRoute.fullscreenDialog,
  228 + middlewares: unknownRoute.middlewares,
221 ); 229 );
222 } 230 }
223 231
@@ -236,6 +244,7 @@ class GetMaterialApp extends StatelessWidget { @@ -236,6 +244,7 @@ class GetMaterialApp extends StatelessWidget {
236 transition: match.route.transition, 244 transition: match.route.transition,
237 popGesture: match.route.popGesture, 245 popGesture: match.route.popGesture,
238 fullscreenDialog: match.route.fullscreenDialog, 246 fullscreenDialog: match.route.fullscreenDialog,
  247 + middlewares: match.route.middlewares
239 ); 248 );
240 } 249 }
241 250
@@ -70,23 +70,24 @@ class ParseRouteTree { @@ -70,23 +70,24 @@ class ParseRouteTree {
70 } 70 }
71 71
72 /// Change the Path for a [GetPage] 72 /// Change the Path for a [GetPage]
73 - GetPage _changePath(GetPage orgin, String routePath) => GetPage(  
74 - name: routePath + orgin.name,  
75 - page: orgin.page,  
76 - title: orgin.title,  
77 - alignment: orgin.alignment,  
78 - transition: orgin.transition,  
79 - binding: orgin.binding,  
80 - bindings: orgin.bindings,  
81 - curve: orgin.curve,  
82 - customTransition: orgin.customTransition,  
83 - fullscreenDialog: orgin.fullscreenDialog,  
84 - maintainState: orgin.maintainState,  
85 - opaque: orgin.opaque,  
86 - parameter: orgin.parameter,  
87 - popGesture: orgin.popGesture,  
88 - settings: orgin.settings,  
89 - transitionDuration: orgin.transitionDuration, 73 + GetPage _changePath(GetPage origin, String routePath) => GetPage(
  74 + name: routePath + origin.name,
  75 + page: origin.page,
  76 + title: origin.title,
  77 + alignment: origin.alignment,
  78 + transition: origin.transition,
  79 + binding: origin.binding,
  80 + bindings: origin.bindings,
  81 + curve: origin.curve,
  82 + customTransition: origin.customTransition,
  83 + fullscreenDialog: origin.fullscreenDialog,
  84 + maintainState: origin.maintainState,
  85 + opaque: origin.opaque,
  86 + parameter: origin.parameter,
  87 + popGesture: origin.popGesture,
  88 + settings: origin.settings,
  89 + transitionDuration: origin.transitionDuration,
  90 + middlewares: origin.middlewares,
90 ); 91 );
91 92
92 _GetPageMatch matchRoute(String path) { 93 _GetPageMatch matchRoute(String path) {
@@ -30,6 +30,7 @@ class GetPageRoute<T> extends PageRoute<T> { @@ -30,6 +30,7 @@ class GetPageRoute<T> extends PageRoute<T> {
30 this.barrierLabel, 30 this.barrierLabel,
31 this.maintainState = true, 31 this.maintainState = true,
32 bool fullscreenDialog = false, 32 bool fullscreenDialog = false,
  33 + this.middlewares
33 }) : assert(opaque != null), 34 }) : assert(opaque != null),
34 assert(barrierDismissible != null), 35 assert(barrierDismissible != null),
35 assert(maintainState != null), 36 assert(maintainState != null),
@@ -65,6 +66,8 @@ class GetPageRoute<T> extends PageRoute<T> { @@ -65,6 +66,8 @@ class GetPageRoute<T> extends PageRoute<T> {
65 66
66 final Alignment alignment; 67 final Alignment alignment;
67 68
  69 + final List<GetPageMiddleware> middlewares;
  70 +
68 @override 71 @override
69 final Color barrierColor; 72 final Color barrierColor;
70 73
@@ -111,14 +114,18 @@ class GetPageRoute<T> extends PageRoute<T> { @@ -111,14 +114,18 @@ class GetPageRoute<T> extends PageRoute<T> {
111 Animation<double> secondaryAnimation, 114 Animation<double> secondaryAnimation,
112 ) { 115 ) {
113 Get.reference = settings.name ?? routeName; 116 Get.reference = settings.name ?? routeName;
  117 +
  118 + final middlewareRunner = MiddlewareRunner(middlewares);
  119 + final bindingsToBind = middlewareRunner.runOnBindingsStart(bindings);
114 binding?.dependencies(); 120 binding?.dependencies();
115 - if (bindings != null) {  
116 - for (final binding in bindings) { 121 + if (bindingsToBind != null) {
  122 + for (final binding in bindingsToBind) {
117 binding.dependencies(); 123 binding.dependencies();
118 } 124 }
119 } 125 }
120 - // final pageWidget = page();  
121 - return page(); 126 +
  127 + final pageToBuild = middlewareRunner.runOnPageBuildStart(page);
  128 + return middlewareRunner.runOnPageBuilt(pageToBuild());
122 } 129 }
123 130
124 static bool isPopGestureInProgress(PageRoute<dynamic> route) { 131 static bool isPopGestureInProgress(PageRoute<dynamic> route) {
1 import 'package:flutter/widgets.dart'; 1 import 'package:flutter/widgets.dart';
  2 +
2 import '../../../get_instance/get_instance.dart'; 3 import '../../../get_instance/get_instance.dart';
  4 +import '../../get_navigation.dart';
3 import 'custom_transition.dart'; 5 import 'custom_transition.dart';
4 import 'transitions_type.dart'; 6 import 'transitions_type.dart';
5 7
@@ -21,6 +23,7 @@ class GetPage { @@ -21,6 +23,7 @@ class GetPage {
21 final bool fullscreenDialog; 23 final bool fullscreenDialog;
22 final RouteSettings settings; 24 final RouteSettings settings;
23 final List<GetPage> children; 25 final List<GetPage> children;
  26 + final List<GetPageMiddleware> middlewares;
24 27
25 const GetPage({ 28 const GetPage({
26 @required this.name, 29 @required this.name,
@@ -40,6 +43,7 @@ class GetPage { @@ -40,6 +43,7 @@ class GetPage {
40 this.customTransition, 43 this.customTransition,
41 this.fullscreenDialog = false, 44 this.fullscreenDialog = false,
42 this.children, 45 this.children,
  46 + this.middlewares,
43 }) : assert(page != null), 47 }) : assert(page != null),
44 assert(name != null), 48 assert(name != null),
45 assert(maintainState != null), 49 assert(maintainState != null),
  1 +import 'package:flutter/cupertino.dart';
  2 +import '../../../get.dart';
  3 +
  4 +/// The Page Middlewares
  5 +/// The Functions will be called in this order
  6 +/// (( [onPageCalled] -> [onBindingsStart] -> [onPageBuildStart] ->
  7 +/// [onPageBuilt] -> [onPageDispose] ))
  8 +abstract class GetPageMiddleware {
  9 + /// The Order of the Middlewares to run.
  10 + int priority;
  11 +
  12 + /// This function will be the first thing to call when this Page is called
  13 + /// you can use it to redirect befor anything in this page happend.
  14 + /// {@tool snippet}
  15 + /// ```dart
  16 + /// GetPage onPageCalled( ) {
  17 + /// final authService = Get.find<AuthService>();
  18 + /// return authService.isAuthed ? null : '/login';
  19 + /// }
  20 + /// ```
  21 + /// {@end-tool}
  22 + String redirect();
  23 +
  24 + ///This function will be called right before the [Bindings] are initialize.
  25 + /// Here you can change [Bindings] for this page
  26 + List<Bindings> onBindingsStart(List<Bindings> bindings);
  27 +
  28 + /// This function will be called right after the [Bindings] are initialize.
  29 + GetPageBuilder onPageBuildStart(GetPageBuilder page);
  30 +
  31 + // Get the built page
  32 + Widget onPageBuilt(Widget page);
  33 +
  34 + void onPageDispose();
  35 +}
  36 +
  37 +class MiddlewareRunner {
  38 + MiddlewareRunner(this._middlewares);
  39 +
  40 + final List<GetPageMiddleware> _middlewares;
  41 +
  42 + List<GetPageMiddleware> _getMiddlewares() {
  43 + if (_middlewares != null) {
  44 + _middlewares.sort((a, b) => a.priority.compareTo(b.priority));
  45 + return _middlewares;
  46 + }
  47 + return <GetPageMiddleware>[];
  48 + }
  49 +
  50 + String runOnPageCalled() {
  51 + var to = '';
  52 + _getMiddlewares().forEach((element) {
  53 + to = element.redirect();
  54 + });
  55 + if (!to.isNullOrBlank) {
  56 + Get.log('Redirect to $to');
  57 + }
  58 + return to;
  59 + }
  60 +
  61 + List<Bindings> runOnBindingsStart(List<Bindings> bindings) {
  62 + _getMiddlewares().forEach((element) {
  63 + bindings = element.onBindingsStart(bindings);
  64 + });
  65 + return bindings;
  66 + }
  67 +
  68 + GetPageBuilder runOnPageBuildStart(GetPageBuilder page) {
  69 + _getMiddlewares().forEach((element) {
  70 + page = element.onPageBuildStart(page);
  71 + });
  72 + return page;
  73 + }
  74 +
  75 + Widget runOnPageBuilt(Widget page) {
  76 + _getMiddlewares().forEach((element) {
  77 + page = element.onPageBuilt(page);
  78 + });
  79 + return page;
  80 + }
  81 +
  82 + void runOnPageDispose() =>
  83 + _getMiddlewares().forEach((element) => element.onPageDispose());
  84 +}