Committed by
GitHub
Merge pull request #1644 from Bdaya-Dev/upmaster
Navigation fixes
Showing
13 changed files
with
110 additions
and
54 deletions
1 | +import 'dart:async'; | ||
2 | + | ||
3 | +import 'package:get/get.dart'; | ||
4 | + | ||
5 | +class DashboardController extends GetxController { | ||
6 | + final now = DateTime.now().obs; | ||
7 | + @override | ||
8 | + void onReady() { | ||
9 | + super.onReady(); | ||
10 | + Timer.periodic( | ||
11 | + Duration(seconds: 1), | ||
12 | + (timer) { | ||
13 | + now.value = DateTime.now(); | ||
14 | + }, | ||
15 | + ); | ||
16 | + } | ||
17 | +} |
1 | +import 'package:example_nav2/app/modules/dashboard/controllers/dashboard_controller.dart'; | ||
1 | import 'package:flutter/material.dart'; | 2 | import 'package:flutter/material.dart'; |
2 | import 'package:get/get.dart'; | 3 | import 'package:get/get.dart'; |
3 | 4 | ||
4 | -import '../controllers/home_controller.dart'; | 5 | +import '../../home/controllers/home_controller.dart'; |
5 | 6 | ||
6 | -class DashboardView extends GetView<HomeController> { | 7 | +class DashboardView extends GetView<DashboardController> { |
7 | @override | 8 | @override |
8 | Widget build(BuildContext context) { | 9 | Widget build(BuildContext context) { |
9 | return Scaffold( | 10 | return Scaffold( |
@@ -16,7 +17,7 @@ class DashboardView extends GetView<HomeController> { | @@ -16,7 +17,7 @@ class DashboardView extends GetView<HomeController> { | ||
16 | 'DashboardView is working', | 17 | 'DashboardView is working', |
17 | style: TextStyle(fontSize: 20), | 18 | style: TextStyle(fontSize: 20), |
18 | ), | 19 | ), |
19 | - Text('Time: ${controller.now.value.toString()}') | 20 | + Text('Time: ${controller.now.value.toString()}'), |
20 | ], | 21 | ], |
21 | ), | 22 | ), |
22 | ), | 23 | ), |
@@ -2,16 +2,4 @@ import 'dart:async'; | @@ -2,16 +2,4 @@ import 'dart:async'; | ||
2 | 2 | ||
3 | import 'package:get/get.dart'; | 3 | import 'package:get/get.dart'; |
4 | 4 | ||
5 | -class HomeController extends GetxController { | ||
6 | - final now = DateTime.now().obs; | ||
7 | - @override | ||
8 | - void onReady() { | ||
9 | - super.onReady(); | ||
10 | - Timer.periodic( | ||
11 | - Duration(seconds: 1), | ||
12 | - (timer) { | ||
13 | - now.value = DateTime.now(); | ||
14 | - }, | ||
15 | - ); | ||
16 | - } | ||
17 | -} | 5 | +class HomeController extends GetxController {} |
@@ -3,7 +3,7 @@ import 'package:get/get.dart'; | @@ -3,7 +3,7 @@ import 'package:get/get.dart'; | ||
3 | 3 | ||
4 | import '../../../routes/app_pages.dart'; | 4 | import '../../../routes/app_pages.dart'; |
5 | import '../controllers/home_controller.dart'; | 5 | import '../controllers/home_controller.dart'; |
6 | -import 'dashboard_view.dart'; | 6 | +import '../../dashboard/views/dashboard_view.dart'; |
7 | 7 | ||
8 | class HomeView extends GetView<HomeController> { | 8 | class HomeView extends GetView<HomeController> { |
9 | @override | 9 | @override |
@@ -22,7 +22,9 @@ class HomeView extends GetView<HomeController> { | @@ -22,7 +22,9 @@ class HomeView extends GetView<HomeController> { | ||
22 | return Scaffold( | 22 | return Scaffold( |
23 | body: GetRouterOutlet( | 23 | body: GetRouterOutlet( |
24 | name: Routes.HOME, | 24 | name: Routes.HOME, |
25 | - emptyWidget: (delegate) => DashboardView(), | 25 | + //It's preferable to use emptyPage instead of emptyWidget |
26 | + emptyPage: (delegate) => | ||
27 | + Get.routeTree.matchRoute(Routes.DASHBOARD).route!, | ||
26 | pickPages: (currentNavStack) { | 28 | pickPages: (currentNavStack) { |
27 | print('Home RouterOutlet: $currentNavStack'); | 29 | print('Home RouterOutlet: $currentNavStack'); |
28 | 30 | ||
@@ -37,7 +39,7 @@ class HomeView extends GetView<HomeController> { | @@ -37,7 +39,7 @@ class HomeView extends GetView<HomeController> { | ||
37 | onTap: (value) { | 39 | onTap: (value) { |
38 | switch (value) { | 40 | switch (value) { |
39 | case 0: | 41 | case 0: |
40 | - delegate.until(Routes.HOME); | 42 | + delegate.toNamed(Routes.HOME); |
41 | break; | 43 | break; |
42 | case 1: | 44 | case 1: |
43 | delegate.toNamed(Routes.PROFILE); | 45 | delegate.toNamed(Routes.PROFILE); |
@@ -12,7 +12,14 @@ class ProductsView extends GetView<ProductsController> { | @@ -12,7 +12,14 @@ class ProductsView extends GetView<ProductsController> { | ||
12 | onPressed: controller.loadDemoProductsFromSomeWhere, | 12 | onPressed: controller.loadDemoProductsFromSomeWhere, |
13 | label: Text('Add'), | 13 | label: Text('Add'), |
14 | ), | 14 | ), |
15 | - body: Obx( | 15 | + body: Column( |
16 | + children: [ | ||
17 | + Hero( | ||
18 | + tag: 'heroLogo', | ||
19 | + child: const FlutterLogo(), | ||
20 | + ), | ||
21 | + Expanded( | ||
22 | + child: Obx( | ||
16 | () => RefreshIndicator( | 23 | () => RefreshIndicator( |
17 | onRefresh: () async { | 24 | onRefresh: () async { |
18 | controller.products.clear(); | 25 | controller.products.clear(); |
@@ -24,7 +31,8 @@ class ProductsView extends GetView<ProductsController> { | @@ -24,7 +31,8 @@ class ProductsView extends GetView<ProductsController> { | ||
24 | final item = controller.products[index]; | 31 | final item = controller.products[index]; |
25 | return ListTile( | 32 | return ListTile( |
26 | onTap: () { | 33 | onTap: () { |
27 | - Get.rootDelegate.toNamed(Routes.PRODUCT_DETAILS(item.id)); | 34 | + Get.rootDelegate |
35 | + .toNamed(Routes.PRODUCT_DETAILS(item.id)); | ||
28 | }, | 36 | }, |
29 | title: Text(item.name), | 37 | title: Text(item.name), |
30 | subtitle: Text(item.id), | 38 | subtitle: Text(item.id), |
@@ -33,6 +41,9 @@ class ProductsView extends GetView<ProductsController> { | @@ -33,6 +41,9 @@ class ProductsView extends GetView<ProductsController> { | ||
33 | ), | 41 | ), |
34 | ), | 42 | ), |
35 | ), | 43 | ), |
44 | + ), | ||
45 | + ], | ||
46 | + ), | ||
36 | ); | 47 | ); |
37 | } | 48 | } |
38 | } | 49 | } |
1 | +import 'package:example_nav2/app/routes/app_pages.dart'; | ||
1 | import 'package:flutter/material.dart'; | 2 | import 'package:flutter/material.dart'; |
2 | 3 | ||
3 | import 'package:get/get.dart'; | 4 | import 'package:get/get.dart'; |
@@ -11,11 +12,16 @@ class ProfileView extends GetView<ProfileController> { | @@ -11,11 +12,16 @@ class ProfileView extends GetView<ProfileController> { | ||
11 | backgroundColor: Colors.amber, | 12 | backgroundColor: Colors.amber, |
12 | body: Center( | 13 | body: Center( |
13 | child: Column( | 14 | child: Column( |
15 | + mainAxisSize: MainAxisSize.min, | ||
14 | children: [ | 16 | children: [ |
15 | Text( | 17 | Text( |
16 | 'ProfileView is working', | 18 | 'ProfileView is working', |
17 | style: TextStyle(fontSize: 20), | 19 | style: TextStyle(fontSize: 20), |
18 | ), | 20 | ), |
21 | + Hero( | ||
22 | + tag: 'heroLogo', | ||
23 | + child: const FlutterLogo(), | ||
24 | + ), | ||
19 | MaterialButton( | 25 | MaterialButton( |
20 | child: Text('Show a test dialog'), | 26 | child: Text('Show a test dialog'), |
21 | onPressed: () { | 27 | onPressed: () { |
@@ -25,6 +31,18 @@ class ProfileView extends GetView<ProfileController> { | @@ -25,6 +31,18 @@ class ProfileView extends GetView<ProfileController> { | ||
25 | barrierDismissible: true, | 31 | barrierDismissible: true, |
26 | ); | 32 | ); |
27 | }, | 33 | }, |
34 | + ), | ||
35 | + MaterialButton( | ||
36 | + child: Text('Show a test dialog in Home router outlet'), | ||
37 | + onPressed: () { | ||
38 | + //shows a dialog | ||
39 | + | ||
40 | + Get.defaultDialog( | ||
41 | + title: 'Test Dialog In Home Outlet !!', | ||
42 | + barrierDismissible: true, | ||
43 | + navigatorKey: Get.nestedKey(Routes.HOME), | ||
44 | + ); | ||
45 | + }, | ||
28 | ) | 46 | ) |
29 | ], | 47 | ], |
30 | ), | 48 | ), |
1 | import 'package:get/get.dart'; | 1 | import 'package:get/get.dart'; |
2 | 2 | ||
3 | +import 'package:example_nav2/app/modules/dashboard/bindings/dashboard_binding.dart'; | ||
4 | +import 'package:example_nav2/app/modules/dashboard/views/dashboard_view.dart'; | ||
5 | + | ||
3 | import '../middleware/auth_middleware.dart'; | 6 | import '../middleware/auth_middleware.dart'; |
4 | import '../modules/home/bindings/home_binding.dart'; | 7 | import '../modules/home/bindings/home_binding.dart'; |
5 | import '../modules/home/views/home_view.dart'; | 8 | import '../modules/home/views/home_view.dart'; |
@@ -36,13 +39,11 @@ class AppPages { | @@ -36,13 +39,11 @@ class AppPages { | ||
36 | //only enter this route when not authed | 39 | //only enter this route when not authed |
37 | EnsureNotAuthedMiddleware(), | 40 | EnsureNotAuthedMiddleware(), |
38 | ], | 41 | ], |
39 | - participatesInRootNavigator: false, | ||
40 | name: _Paths.LOGIN, | 42 | name: _Paths.LOGIN, |
41 | page: () => LoginView(), | 43 | page: () => LoginView(), |
42 | binding: LoginBinding(), | 44 | binding: LoginBinding(), |
43 | ), | 45 | ), |
44 | GetPage( | 46 | GetPage( |
45 | - participatesInRootNavigator: false, | ||
46 | preventDuplicates: true, | 47 | preventDuplicates: true, |
47 | name: _Paths.HOME, | 48 | name: _Paths.HOME, |
48 | page: () => HomeView(), | 49 | page: () => HomeView(), |
@@ -52,6 +53,11 @@ class AppPages { | @@ -52,6 +53,11 @@ class AppPages { | ||
52 | title: null, | 53 | title: null, |
53 | children: [ | 54 | children: [ |
54 | GetPage( | 55 | GetPage( |
56 | + name: _Paths.DASHBOARD, | ||
57 | + page: () => DashboardView(), | ||
58 | + binding: DashboardBinding(), | ||
59 | + ), | ||
60 | + GetPage( | ||
55 | middlewares: [ | 61 | middlewares: [ |
56 | //only enter this route when authed | 62 | //only enter this route when authed |
57 | EnsureAuthMiddleware(), | 63 | EnsureAuthMiddleware(), |
@@ -83,7 +89,6 @@ class AppPages { | @@ -83,7 +89,6 @@ class AppPages { | ||
83 | ], | 89 | ], |
84 | ), | 90 | ), |
85 | GetPage( | 91 | GetPage( |
86 | - participatesInRootNavigator: true, | ||
87 | name: _Paths.SETTINGS, | 92 | name: _Paths.SETTINGS, |
88 | page: () => SettingsView(), | 93 | page: () => SettingsView(), |
89 | binding: SettingsBinding(), | 94 | binding: SettingsBinding(), |
@@ -14,6 +14,7 @@ abstract class Routes { | @@ -14,6 +14,7 @@ abstract class Routes { | ||
14 | static const LOGIN = _Paths.LOGIN; | 14 | static const LOGIN = _Paths.LOGIN; |
15 | static String LOGIN_THEN(String afterSuccessfulLogin) => | 15 | static String LOGIN_THEN(String afterSuccessfulLogin) => |
16 | '$LOGIN?then=${Uri.encodeQueryComponent(afterSuccessfulLogin)}'; | 16 | '$LOGIN?then=${Uri.encodeQueryComponent(afterSuccessfulLogin)}'; |
17 | + static const DASHBOARD = _Paths.HOME + _Paths.DASHBOARD; | ||
17 | } | 18 | } |
18 | 19 | ||
19 | abstract class _Paths { | 20 | abstract class _Paths { |
@@ -23,4 +24,5 @@ abstract class _Paths { | @@ -23,4 +24,5 @@ abstract class _Paths { | ||
23 | static const SETTINGS = '/settings'; | 24 | static const SETTINGS = '/settings'; |
24 | static const PRODUCT_DETAILS = '/:productId'; | 25 | static const PRODUCT_DETAILS = '/:productId'; |
25 | static const LOGIN = '/login'; | 26 | static const LOGIN = '/login'; |
27 | + static const DASHBOARD = '/dashboard'; | ||
26 | } | 28 | } |
@@ -215,7 +215,7 @@ extension ExtensionDialog on GetInterface { | @@ -215,7 +215,7 @@ extension ExtensionDialog on GetInterface { | ||
215 | bool barrierDismissible = true, | 215 | bool barrierDismissible = true, |
216 | Color? barrierColor, | 216 | Color? barrierColor, |
217 | bool useSafeArea = true, | 217 | bool useSafeArea = true, |
218 | - bool useRootNavigator = true, | 218 | + GlobalKey<NavigatorState>? navigatorKey, |
219 | Object? arguments, | 219 | Object? arguments, |
220 | Duration? transitionDuration, | 220 | Duration? transitionDuration, |
221 | Curve? transitionCurve, | 221 | Curve? transitionCurve, |
@@ -250,7 +250,7 @@ extension ExtensionDialog on GetInterface { | @@ -250,7 +250,7 @@ extension ExtensionDialog on GetInterface { | ||
250 | child: child, | 250 | child: child, |
251 | ); | 251 | ); |
252 | }, | 252 | }, |
253 | - useRootNavigator: useRootNavigator, | 253 | + navigatorKey: navigatorKey, |
254 | routeSettings: | 254 | routeSettings: |
255 | routeSettings ?? RouteSettings(arguments: arguments, name: name), | 255 | routeSettings ?? RouteSettings(arguments: arguments, name: name), |
256 | ); | 256 | ); |
@@ -264,12 +264,16 @@ extension ExtensionDialog on GetInterface { | @@ -264,12 +264,16 @@ extension ExtensionDialog on GetInterface { | ||
264 | Color barrierColor = const Color(0x80000000), | 264 | Color barrierColor = const Color(0x80000000), |
265 | Duration transitionDuration = const Duration(milliseconds: 200), | 265 | Duration transitionDuration = const Duration(milliseconds: 200), |
266 | RouteTransitionsBuilder? transitionBuilder, | 266 | RouteTransitionsBuilder? transitionBuilder, |
267 | - bool useRootNavigator = true, | 267 | + GlobalKey<NavigatorState>? navigatorKey, |
268 | RouteSettings? routeSettings, | 268 | RouteSettings? routeSettings, |
269 | }) { | 269 | }) { |
270 | assert(!barrierDismissible || barrierLabel != null); | 270 | assert(!barrierDismissible || barrierLabel != null); |
271 | - return Navigator.of(overlayContext!, rootNavigator: useRootNavigator) | ||
272 | - .push<T>(GetDialogRoute<T>( | 271 | + final nav = navigatorKey?.currentState ?? |
272 | + Navigator.of(overlayContext!, | ||
273 | + rootNavigator: | ||
274 | + true); //overlay context will always return the root navigator | ||
275 | + return nav.push<T>( | ||
276 | + GetDialogRoute<T>( | ||
273 | pageBuilder: pageBuilder, | 277 | pageBuilder: pageBuilder, |
274 | barrierDismissible: barrierDismissible, | 278 | barrierDismissible: barrierDismissible, |
275 | barrierLabel: barrierLabel, | 279 | barrierLabel: barrierLabel, |
@@ -277,7 +281,8 @@ extension ExtensionDialog on GetInterface { | @@ -277,7 +281,8 @@ extension ExtensionDialog on GetInterface { | ||
277 | transitionDuration: transitionDuration, | 281 | transitionDuration: transitionDuration, |
278 | transitionBuilder: transitionBuilder, | 282 | transitionBuilder: transitionBuilder, |
279 | settings: routeSettings, | 283 | settings: routeSettings, |
280 | - )); | 284 | + ), |
285 | + ); | ||
281 | } | 286 | } |
282 | 287 | ||
283 | /// Custom UI Dialog. | 288 | /// Custom UI Dialog. |
@@ -309,6 +314,9 @@ extension ExtensionDialog on GetInterface { | @@ -309,6 +314,9 @@ extension ExtensionDialog on GetInterface { | ||
309 | 314 | ||
310 | // onWillPop Scope | 315 | // onWillPop Scope |
311 | WillPopCallback? onWillPop, | 316 | WillPopCallback? onWillPop, |
317 | + | ||
318 | + // the navigator used to push the dialog | ||
319 | + GlobalKey<NavigatorState>? navigatorKey, | ||
312 | }) { | 320 | }) { |
313 | var leanCancel = onCancel != null || textCancel != null; | 321 | var leanCancel = onCancel != null || textCancel != null; |
314 | var leanConfirm = onConfirm != null || textConfirm != null; | 322 | var leanConfirm = onConfirm != null || textConfirm != null; |
@@ -394,19 +402,15 @@ extension ExtensionDialog on GetInterface { | @@ -394,19 +402,15 @@ extension ExtensionDialog on GetInterface { | ||
394 | buttonPadding: EdgeInsets.zero, | 402 | buttonPadding: EdgeInsets.zero, |
395 | ); | 403 | ); |
396 | 404 | ||
397 | - if (onWillPop != null) { | ||
398 | return dialog<T>( | 405 | return dialog<T>( |
399 | - WillPopScope( | 406 | + onWillPop != null |
407 | + ? WillPopScope( | ||
400 | onWillPop: onWillPop, | 408 | onWillPop: onWillPop, |
401 | child: baseAlertDialog, | 409 | child: baseAlertDialog, |
402 | - ), | ||
403 | - barrierDismissible: barrierDismissible, | ||
404 | - ); | ||
405 | - } | ||
406 | - | ||
407 | - return dialog<T>( | ||
408 | - baseAlertDialog, | 410 | + ) |
411 | + : baseAlertDialog, | ||
409 | barrierDismissible: barrierDismissible, | 412 | barrierDismissible: barrierDismissible, |
413 | + navigatorKey: navigatorKey, | ||
410 | ); | 414 | ); |
411 | } | 415 | } |
412 | } | 416 | } |
@@ -263,7 +263,7 @@ class GetDelegate extends RouterDelegate<GetNavConfig> | @@ -263,7 +263,7 @@ class GetDelegate extends RouterDelegate<GetNavConfig> | ||
263 | if (currentHistory == null) return <GetPage>[]; | 263 | if (currentHistory == null) return <GetPage>[]; |
264 | 264 | ||
265 | final res = currentHistory.currentTreeBranch | 265 | final res = currentHistory.currentTreeBranch |
266 | - .where((r) => r.participatesInRootNavigator); | 266 | + .where((r) => r.participatesInRootNavigator != null); |
267 | if (res.length == 0) { | 267 | if (res.length == 0) { |
268 | //default behavoir, all routes participate in root navigator | 268 | //default behavoir, all routes participate in root navigator |
269 | return currentHistory.currentTreeBranch; | 269 | return currentHistory.currentTreeBranch; |
@@ -421,10 +421,13 @@ class GetNavigator extends Navigator { | @@ -421,10 +421,13 @@ class GetNavigator extends Navigator { | ||
421 | bool reportsRouteUpdateToEngine = false, | 421 | bool reportsRouteUpdateToEngine = false, |
422 | TransitionDelegate? transitionDelegate, | 422 | TransitionDelegate? transitionDelegate, |
423 | String? name, | 423 | String? name, |
424 | - }) : assert(key != null || name != null, | ||
425 | - 'GetNavigator should either have a key or a name set'), | ||
426 | - super( | ||
427 | - key: key ?? Get.nestedKey(name), | 424 | + }) : super( |
425 | + //keys should be optional | ||
426 | + key: key != null | ||
427 | + ? key | ||
428 | + : name != null | ||
429 | + ? Get.nestedKey(name) | ||
430 | + : null, | ||
428 | onPopPage: onPopPage ?? | 431 | onPopPage: onPopPage ?? |
429 | (route, result) { | 432 | (route, result) { |
430 | final didPop = route.didPop(result); | 433 | final didPop = route.didPop(result); |
@@ -94,7 +94,7 @@ class GetRouterOutlet extends RouterOutlet<GetDelegate, GetNavConfig> { | @@ -94,7 +94,7 @@ class GetRouterOutlet extends RouterOutlet<GetDelegate, GetNavConfig> { | ||
94 | GetPage Function(GetDelegate delegate)? emptyPage, | 94 | GetPage Function(GetDelegate delegate)? emptyPage, |
95 | required List<GetPage> Function(GetNavConfig currentNavStack) pickPages, | 95 | required List<GetPage> Function(GetNavConfig currentNavStack) pickPages, |
96 | bool Function(Route<dynamic>, dynamic)? onPopPage, | 96 | bool Function(Route<dynamic>, dynamic)? onPopPage, |
97 | - required String name, | 97 | + String? name, |
98 | }) : assert( | 98 | }) : assert( |
99 | (emptyPage == null && emptyWidget == null) || | 99 | (emptyPage == null && emptyWidget == null) || |
100 | (emptyPage != null && emptyWidget == null) || | 100 | (emptyPage != null && emptyWidget == null) || |
@@ -106,13 +106,6 @@ class GetRouterOutlet extends RouterOutlet<GetDelegate, GetNavConfig> { | @@ -106,13 +106,6 @@ class GetRouterOutlet extends RouterOutlet<GetDelegate, GetNavConfig> { | ||
106 | (pages ?? <GetPage<dynamic>?>[emptyPage?.call(rDelegate)]) | 106 | (pages ?? <GetPage<dynamic>?>[emptyPage?.call(rDelegate)]) |
107 | .whereType<GetPage<dynamic>>() | 107 | .whereType<GetPage<dynamic>>() |
108 | .toList(); | 108 | .toList(); |
109 | - | ||
110 | - final badPages = pageRes.where( | ||
111 | - (element) => element.participatesInRootNavigator == true); | ||
112 | - if (badPages.length > 0) { | ||
113 | - throw """Pages in a router outlet shouldn't participate in the root navigator | ||
114 | - $badPages"""; | ||
115 | - } | ||
116 | if (pageRes.length > 0) { | 109 | if (pageRes.length > 0) { |
117 | return GetNavigator( | 110 | return GetNavigator( |
118 | onPopPage: onPopPage ?? | 111 | onPopPage: onPopPage ?? |
@@ -34,7 +34,7 @@ class GetPage<T> extends Page<T> { | @@ -34,7 +34,7 @@ class GetPage<T> extends Page<T> { | ||
34 | final String? title; | 34 | final String? title; |
35 | final Transition? transition; | 35 | final Transition? transition; |
36 | final Curve curve; | 36 | final Curve curve; |
37 | - final bool participatesInRootNavigator; | 37 | + final bool? participatesInRootNavigator; |
38 | final Alignment? alignment; | 38 | final Alignment? alignment; |
39 | final bool maintainState; | 39 | final bool maintainState; |
40 | final bool opaque; | 40 | final bool opaque; |
@@ -66,7 +66,7 @@ class GetPage<T> extends Page<T> { | @@ -66,7 +66,7 @@ class GetPage<T> extends Page<T> { | ||
66 | required this.name, | 66 | required this.name, |
67 | required this.page, | 67 | required this.page, |
68 | this.title, | 68 | this.title, |
69 | - this.participatesInRootNavigator = true, | 69 | + this.participatesInRootNavigator, |
70 | this.gestureWidth = 20, | 70 | this.gestureWidth = 20, |
71 | // RouteSettings settings, | 71 | // RouteSettings settings, |
72 | this.maintainState = true, | 72 | this.maintainState = true, |
-
Please register or login to post a comment