diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index 73e6fe03ae8..d268648720c 100644 --- a/packages/go_router/CHANGELOG.md +++ b/packages/go_router/CHANGELOG.md @@ -1,3 +1,7 @@ +## 13.2.2 + +- Fixes restoreRouteInformation issue when GoRouter.optionURLReflectsImperativeAPIs is true and the last match is ShellRouteMatch + ## 13.2.1 - Updates minimum supported SDK version to Flutter 3.16/Dart 3.2. diff --git a/packages/go_router/lib/src/parser.dart b/packages/go_router/lib/src/parser.dart index 4ac4f03423c..9cd92c1848b 100644 --- a/packages/go_router/lib/src/parser.dart +++ b/packages/go_router/lib/src/parser.dart @@ -125,18 +125,27 @@ class GoRouteInformationParser extends RouteInformationParser { if (configuration.isEmpty) { return null; } - final String location; + String? location; if (GoRouter.optionURLReflectsImperativeAPIs && - configuration.matches.last is ImperativeRouteMatch) { - location = (configuration.matches.last as ImperativeRouteMatch) - .matches - .uri - .toString(); - } else { - location = configuration.uri.toString(); + (configuration.matches.last is ImperativeRouteMatch || + configuration.matches.last is ShellRouteMatch)) { + RouteMatchBase route = configuration.matches.last; + + while (route is! ImperativeRouteMatch) { + if (route is ShellRouteMatch && route.matches.isNotEmpty) { + route = route.matches.last; + } else { + break; + } + } + + if (route case final ImperativeRouteMatch safeRoute) { + location = safeRoute.matches.uri.toString(); + } } + return RouteInformation( - uri: Uri.parse(location), + uri: Uri.parse(location ?? configuration.uri.toString()), state: _routeMatchListCodec.encode(configuration), ); } diff --git a/packages/go_router/pubspec.yaml b/packages/go_router/pubspec.yaml index 3974ba27606..ac7945e62ec 100644 --- a/packages/go_router/pubspec.yaml +++ b/packages/go_router/pubspec.yaml @@ -1,7 +1,7 @@ name: go_router description: A declarative router for Flutter based on Navigation 2 supporting deep linking, data-driven routes and more -version: 13.2.1 +version: 13.2.2 repository: https://github.com/flutter/packages/tree/main/packages/go_router issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router%22 diff --git a/packages/go_router/test/go_router_test.dart b/packages/go_router/test/go_router_test.dart index 776e9a4d680..57d8612c076 100644 --- a/packages/go_router/test/go_router_test.dart +++ b/packages/go_router/test/go_router_test.dart @@ -1111,6 +1111,47 @@ void main() { log.clear(); }); + testWidgets( + 'on push shell route with optionURLReflectImperativeAPIs = true', + (WidgetTester tester) async { + GoRouter.optionURLReflectsImperativeAPIs = true; + final List routes = [ + GoRoute( + path: '/', + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), + routes: [ + ShellRoute( + builder: + (BuildContext context, GoRouterState state, Widget child) => + child, + routes: [ + GoRoute( + path: 'c', + builder: (BuildContext context, GoRouterState state) => + const DummyScreen(), + ) + ], + ), + ], + ), + ]; + + final GoRouter router = await createRouter(routes, tester); + + log.clear(); + router.push('/c?foo=bar'); + final RouteMatchListCodec codec = + RouteMatchListCodec(router.configuration); + await tester.pumpAndSettle(); + expect(log, [ + isMethodCall('selectMultiEntryHistory', arguments: null), + IsRouteUpdateCall('/c?foo=bar', false, + codec.encode(router.routerDelegate.currentConfiguration)), + ]); + GoRouter.optionURLReflectsImperativeAPIs = false; + }); + testWidgets('on push with optionURLReflectImperativeAPIs = true', (WidgetTester tester) async { GoRouter.optionURLReflectsImperativeAPIs = true;