Showing
5 changed files
with
119 additions
and
106 deletions
@@ -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 | + |
-
Please register or login to post a comment