Schaban

WIP

@@ -188,55 +188,7 @@ class GetCupertinoApp extends StatelessWidget { @@ -188,55 +188,7 @@ 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 - var match = Get.routeTree.matchRoute(settings.name);  
192 -  
193 - var runner = MiddlewareRunner(match.route.middlewares);  
194 - var redirect = runner.runRedirect();  
195 - while (!redirect.isNullOrBlank) {  
196 - match = Get.routeTree.matchRoute(redirect);  
197 - runner = MiddlewareRunner(match.route.middlewares);  
198 - redirect = runner.runRedirect();  
199 - }  
200 -  
201 - Get.parameters = match?.parameters;  
202 - if (match?.route == null) {  
203 - return GetPageRoute(  
204 - page: unknownRoute.page,  
205 - parameter: unknownRoute.parameter,  
206 - settings:  
207 - RouteSettings(name: settings.name, arguments: settings.arguments),  
208 - curve: unknownRoute.curve,  
209 - opaque: unknownRoute.opaque,  
210 - customTransition: unknownRoute.customTransition,  
211 - binding: unknownRoute.binding,  
212 - bindings: unknownRoute.bindings,  
213 - transitionDuration:  
214 - (unknownRoute.transitionDuration ?? Get.defaultTransitionDuration),  
215 - transition: unknownRoute.transition,  
216 - popGesture: unknownRoute.popGesture,  
217 - fullscreenDialog: unknownRoute.fullscreenDialog,  
218 - middlewares: unknownRoute.middlewares,  
219 - );  
220 - }  
221 -  
222 - match.route = runner.runOnPageCalled(match.route);  
223 - return GetPageRoute(  
224 - page: match.route.page,  
225 - parameter: match.route.parameter,  
226 - settings:  
227 - RouteSettings(name: settings.name, arguments: settings.arguments),  
228 - curve: match.route.curve,  
229 - opaque: match.route.opaque,  
230 - customTransition: match.route.customTransition,  
231 - binding: match.route.binding,  
232 - bindings: match.route.bindings,  
233 - transitionDuration:  
234 - (match.route.transitionDuration ?? Get.defaultTransitionDuration),  
235 - transition: match.route.transition,  
236 - popGesture: match.route.popGesture,  
237 - fullscreenDialog: match.route.fullscreenDialog,  
238 - middlewares: match.route.middlewares,  
239 - ); 191 + return PageRedirect(settings, unknownRoute).page();
240 } 192 }
241 193
242 List<Route<dynamic>> initialRoutesGenerate(String name) { 194 List<Route<dynamic>> initialRoutesGenerate(String name) {
@@ -199,53 +199,7 @@ class GetMaterialApp extends StatelessWidget { @@ -199,53 +199,7 @@ 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 - var match = Get.routeTree.matchRoute(settings.name);  
203 -  
204 - final redirect =  
205 - MiddlewareRunner(match.route.middlewares).runRedirect();  
206 - if (!redirect.isNullOrBlank) {  
207 - match = Get.routeTree.matchRoute(redirect);  
208 - }  
209 -  
210 - Get.parameters = match?.parameters;  
211 -  
212 - if (match?.route == null) {  
213 - return GetPageRoute(  
214 - page: unknownRoute.page,  
215 - parameter: unknownRoute.parameter,  
216 - settings:  
217 - RouteSettings(name: settings.name, arguments: settings.arguments),  
218 - curve: unknownRoute.curve,  
219 - opaque: unknownRoute.opaque,  
220 - customTransition: unknownRoute.customTransition,  
221 - binding: unknownRoute.binding,  
222 - bindings: unknownRoute.bindings,  
223 - transitionDuration:  
224 - (unknownRoute.transitionDuration ?? Get.defaultTransitionDuration),  
225 - transition: unknownRoute.transition,  
226 - popGesture: unknownRoute.popGesture,  
227 - fullscreenDialog: unknownRoute.fullscreenDialog,  
228 - middlewares: unknownRoute.middlewares,  
229 - );  
230 - }  
231 -  
232 - return GetPageRoute(  
233 - page: match.route.page,  
234 - parameter: match.route.parameter,  
235 - settings:  
236 - RouteSettings(name: settings.name, arguments: settings.arguments),  
237 - curve: match.route.curve,  
238 - opaque: match.route.opaque,  
239 - customTransition: match.route.customTransition,  
240 - binding: match.route.binding,  
241 - bindings: match.route.bindings,  
242 - transitionDuration:  
243 - (match.route.transitionDuration ?? Get.defaultTransitionDuration),  
244 - transition: match.route.transition,  
245 - popGesture: match.route.popGesture,  
246 - fullscreenDialog: match.route.fullscreenDialog,  
247 - middlewares: match.route.middlewares  
248 - ); 202 + return PageRedirect(settings, unknownRoute).page();
249 } 203 }
250 204
251 List<Route<dynamic>> initialRoutesGenerate(String name) { 205 List<Route<dynamic>> initialRoutesGenerate(String name) {
@@ -115,7 +115,8 @@ class GetObserver extends NavigatorObserver { @@ -115,7 +115,8 @@ class GetObserver extends NavigatorObserver {
115 value.removed = ''; 115 value.removed = '';
116 value.previous = _extractRouteName(previousRoute) ?? ''; 116 value.previous = _extractRouteName(previousRoute) ?? '';
117 value.isSnackbar = newRoute.isSnackbar ? true : value.isSnackbar ?? false; 117 value.isSnackbar = newRoute.isSnackbar ? true : value.isSnackbar ?? false;
118 - value.isBottomSheet = newRoute.isBottomSheet ? true : value.isBottomSheet ?? false; 118 + value.isBottomSheet =
  119 + newRoute.isBottomSheet ? true : value.isBottomSheet ?? false;
119 value.isDialog = newRoute.isDialog ? true : value.isDialog ?? false; 120 value.isDialog = newRoute.isDialog ? true : value.isDialog ?? false;
120 }); 121 });
121 122
@@ -154,7 +155,8 @@ class GetObserver extends NavigatorObserver { @@ -154,7 +155,8 @@ class GetObserver extends NavigatorObserver {
154 value.removed = ''; 155 value.removed = '';
155 value.previous = newRoute.name ?? ''; 156 value.previous = newRoute.name ?? '';
156 value.isSnackbar = currentRoute.isSnackbar ? false : value.isSnackbar; 157 value.isSnackbar = currentRoute.isSnackbar ? false : value.isSnackbar;
157 - value.isBottomSheet = currentRoute.isBottomSheet ? false : value.isBottomSheet; 158 + value.isBottomSheet =
  159 + currentRoute.isBottomSheet ? false : value.isBottomSheet;
158 value.isDialog = currentRoute.isDialog ? false : value.isDialog; 160 value.isDialog = currentRoute.isDialog ? false : value.isDialog;
159 }); 161 });
160 162
@@ -184,7 +186,8 @@ class GetObserver extends NavigatorObserver { @@ -184,7 +186,8 @@ class GetObserver extends NavigatorObserver {
184 value.removed = ''; 186 value.removed = '';
185 value.previous = '$oldName'; 187 value.previous = '$oldName';
186 value.isSnackbar = currentRoute.isSnackbar ? false : value.isSnackbar; 188 value.isSnackbar = currentRoute.isSnackbar ? false : value.isSnackbar;
187 - value.isBottomSheet = currentRoute.isBottomSheet ? false : value.isBottomSheet; 189 + value.isBottomSheet =
  190 + currentRoute.isBottomSheet ? false : value.isBottomSheet;
188 value.isDialog = currentRoute.isDialog ? false : value.isDialog; 191 value.isDialog = currentRoute.isDialog ? false : value.isDialog;
189 }); 192 });
190 193
@@ -205,7 +208,8 @@ class GetObserver extends NavigatorObserver { @@ -205,7 +208,8 @@ class GetObserver extends NavigatorObserver {
205 value.removed = routeName ?? ''; 208 value.removed = routeName ?? '';
206 value.previous = routeName ?? ''; 209 value.previous = routeName ?? '';
207 value.isSnackbar = currentRoute.isSnackbar ? false : value.isSnackbar; 210 value.isSnackbar = currentRoute.isSnackbar ? false : value.isSnackbar;
208 - value.isBottomSheet = currentRoute.isBottomSheet ? false : value.isBottomSheet; 211 + value.isBottomSheet =
  212 + currentRoute.isBottomSheet ? false : value.isBottomSheet;
209 value.isDialog = currentRoute.isDialog ? false : value.isDialog; 213 value.isDialog = currentRoute.isDialog ? false : value.isDialog;
210 }); 214 });
211 215
@@ -28,7 +28,7 @@ abstract class _RouteMiddleware { @@ -28,7 +28,7 @@ abstract class _RouteMiddleware {
28 /// } 28 /// }
29 /// ``` 29 /// ```
30 /// {@end-tool} 30 /// {@end-tool}
31 - String redirect(); 31 + RouteSettings redirect();
32 32
33 /// This function will be called when this Page is called 33 /// This function will be called when this Page is called
34 /// you can use it to change something about the page or give it new page 34 /// you can use it to change something about the page or give it new page
@@ -68,7 +68,7 @@ class GetMiddleware implements _RouteMiddleware { @@ -68,7 +68,7 @@ class GetMiddleware implements _RouteMiddleware {
68 GetMiddleware({this.priority}); 68 GetMiddleware({this.priority});
69 69
70 @override 70 @override
71 - String redirect() => ''; 71 + RouteSettings redirect() => null;
72 72
73 @override 73 @override
74 GetPage onPageCalled(GetPage page) => page; 74 GetPage onPageCalled(GetPage page) => page;
@@ -106,12 +106,12 @@ class MiddlewareRunner { @@ -106,12 +106,12 @@ class MiddlewareRunner {
106 return page; 106 return page;
107 } 107 }
108 108
109 - String runRedirect() {  
110 - var to = ''; 109 + RouteSettings runRedirect() {
  110 + RouteSettings to;
111 _getMiddlewares().forEach((element) { 111 _getMiddlewares().forEach((element) {
112 to = element.redirect(); 112 to = element.redirect();
113 }); 113 });
114 - if (!to.isNullOrBlank) { 114 + if (to != null) {
115 Get.log('Redirect to $to'); 115 Get.log('Redirect to $to');
116 } 116 }
117 return to; 117 return to;
@@ -141,3 +141,74 @@ class MiddlewareRunner { @@ -141,3 +141,74 @@ class MiddlewareRunner {
141 void runOnPageDispose() => 141 void runOnPageDispose() =>
142 _getMiddlewares().forEach((element) => element.onPageDispose()); 142 _getMiddlewares().forEach((element) => element.onPageDispose());
143 } 143 }
  144 +
  145 +class PageRedirect {
  146 + GetPage route;
  147 + GetPage unknownRoute;
  148 + RouteSettings settings;
  149 + bool isUnknown;
  150 +
  151 + PageRedirect(this.settings, this.unknownRoute,
  152 + {this.isUnknown = false, this.route});
  153 +
  154 + // redirect all pages that needes redirecting
  155 + GetPageRoute page() {
  156 + while (needRecheck()) {}
  157 + return isUnknown
  158 + ? GetPageRoute(
  159 + page: unknownRoute.page,
  160 + parameter: unknownRoute.parameter,
  161 + settings: RouteSettings(
  162 + name: settings.name, arguments: settings.arguments),
  163 + curve: unknownRoute.curve,
  164 + opaque: unknownRoute.opaque,
  165 + customTransition: unknownRoute.customTransition,
  166 + binding: unknownRoute.binding,
  167 + bindings: unknownRoute.bindings,
  168 + transitionDuration: (unknownRoute.transitionDuration ??
  169 + Get.defaultTransitionDuration),
  170 + transition: unknownRoute.transition,
  171 + popGesture: unknownRoute.popGesture,
  172 + fullscreenDialog: unknownRoute.fullscreenDialog,
  173 + middlewares: unknownRoute.middlewares,
  174 + )
  175 + : GetPageRoute(
  176 + page: route.page,
  177 + parameter: route.parameter,
  178 + settings: RouteSettings(
  179 + name: settings.name, arguments: settings.arguments),
  180 + curve: route.curve,
  181 + opaque: route.opaque,
  182 + customTransition: route.customTransition,
  183 + binding: route.binding,
  184 + bindings: route.bindings,
  185 + transitionDuration:
  186 + (route.transitionDuration ?? Get.defaultTransitionDuration),
  187 + transition: route.transition,
  188 + popGesture: route.popGesture,
  189 + fullscreenDialog: route.fullscreenDialog,
  190 + middlewares: route.middlewares);
  191 + }
  192 +
  193 + /// check if redirect is needed
  194 + bool needRecheck() {
  195 + final match = Get.routeTree.matchRoute(settings.name);
  196 + Get.parameters = match?.parameters;
  197 +
  198 + // No Match found
  199 + if (match?.route == null) {
  200 + isUnknown = true;
  201 + return false;
  202 + }
  203 +
  204 + final runner = MiddlewareRunner(match.route.middlewares);
  205 + route = runner.runOnPageCalled(match.route);
  206 +
  207 + // No middlewares found return match.
  208 + if (match.route.middlewares == null || match.route.middlewares.isEmpty) {
  209 + return false;
  210 + }
  211 +
  212 + return runner.runRedirect() != null;
  213 + }
  214 +}
  1 +import 'package:flutter/cupertino.dart';
  2 +import 'package:flutter_test/flutter_test.dart';
  3 +import 'package:get/get.dart';
1 4
2 -main( ) { 5 +import 'get_main_test.dart';
3 6
  7 +class RedirectMiddleware extends GetMiddleware {
  8 + @override
  9 + RouteSettings redirect() => RouteSettings(name: '/second');
4 } 10 }
  11 +
  12 +main() {
  13 + testWidgets("Middleware redirect smoke test", (tester) async {
  14 + await tester.pumpWidget(
  15 + GetMaterialApp(
  16 + initialRoute: '/',
  17 + getPages: [
  18 + GetPage(name: '/', page: () => Container()),
  19 + GetPage(
  20 + name: '/first',
  21 + page: () => FirstScreen(),
  22 + middlewares: [RedirectMiddleware()]),
  23 + GetPage(name: '/second', page: () => SecondScreen()),
  24 + GetPage(name: '/third', page: () => ThirdScreen()),
  25 + ],
  26 + ),
  27 + );
  28 +
  29 + Get.toNamed('/first');
  30 +
  31 + await tester.pumpAndSettle();
  32 + print(Get.routing.current);
  33 + expect(find.byType(SecondScreen), findsOneWidget);
  34 + });
  35 +}
  36 +