Showing
5 changed files
with
121 additions
and
108 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 | ||
| @@ -198,14 +201,15 @@ class GetObserver extends NavigatorObserver { | @@ -198,14 +201,15 @@ class GetObserver extends NavigatorObserver { | ||
| 198 | final currentRoute = _RouteData.ofRoute(route); | 201 | final currentRoute = _RouteData.ofRoute(route); |
| 199 | 202 | ||
| 200 | Get.log("REMOVING ROUTE $routeName"); | 203 | Get.log("REMOVING ROUTE $routeName"); |
| 201 | - | 204 | + |
| 202 | _routeSend?.update((value) { | 205 | _routeSend?.update((value) { |
| 203 | value.route = previousRoute; | 206 | value.route = previousRoute; |
| 204 | value.isBack = false; | 207 | value.isBack = false; |
| 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'; |
| 6 | + | ||
| 7 | +class RedirectMiddleware extends GetMiddleware { | ||
| 8 | + @override | ||
| 9 | + RouteSettings redirect() => RouteSettings(name: '/second'); | ||
| 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 | +} | ||
| 3 | 36 | ||
| 4 | -} |
-
Please register or login to post a comment