Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[go_router] Fixes the GoRouter.goBranch so that it doesn't reset extr… #4723

Merged
merged 3 commits into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/go_router/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 11.0.0

- Fixes the GoRouter.goBranch so that it doesn't reset extra to null if extra is not serializable.
- **BREAKING CHANGE**:
- Updates the function signature of `GoRouteInformationProvider.restore`.
- Adds `NavigationType.restore` to `NavigationType` enum.

## 10.2.0

- Adds `onExit` to GoRoute.
Expand Down
1 change: 1 addition & 0 deletions packages/go_router/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ See the API documentation for details on the following topics:
- [Error handling](https://pub.dev/documentation/go_router/latest/topics/Error%20handling-topic.html)

## Migration Guides
- [Migrating to 11.0.0](https://flutter.dev/go/go-router-v11-breaking-changes).
- [Migrating to 10.0.0](https://flutter.dev/go/go-router-v10-breaking-changes).
- [Migrating to 9.0.0](https://flutter.dev/go/go-router-v9-breaking-changes).
- [Migrating to 8.0.0](https://flutter.dev/go/go-router-v8-breaking-changes).
Expand Down
24 changes: 17 additions & 7 deletions packages/go_router/lib/src/information_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ enum NavigatingType {

/// Replace the entire [RouteMatchList] with the new location.
go,

/// Restore the current match list with
/// [RouteInformationState.baseRouteMatchList].
restore,
}

/// The data class to be stored in [RouteInformation.state] to be used by
Expand All @@ -48,16 +52,18 @@ class RouteInformationState<T> {
this.completer,
this.baseRouteMatchList,
required this.type,
}) : assert((type != NavigatingType.go) ==
(completer != null && baseRouteMatchList != null));
}) : assert((type == NavigatingType.go || type == NavigatingType.restore) ==
(completer == null)),
assert((type != NavigatingType.go) == (baseRouteMatchList != null));

/// The extra object used when navigating with [GoRouter].
final Object? extra;

/// The completer that needs to be completed when the newly added route is
/// popped off the screen.
///
/// This is only null if [type] is [NavigatingType.go].
/// This is only null if [type] is [NavigatingType.go] or
/// [NavigatingType.restore].
final Completer<T?>? completer;

/// The base route match list to push on top to.
Expand Down Expand Up @@ -177,11 +183,15 @@ class GoRouteInformationProvider extends RouteInformationProvider
);
}

/// Restores the current route matches with the `encodedMatchList`.
void restore(String location, {required Object encodedMatchList}) {
/// Restores the current route matches with the `matchList`.
void restore(String location, {required RouteMatchList matchList}) {
_setValue(
location,
encodedMatchList,
matchList.uri.toString(),
RouteInformationState<void>(
extra: matchList.extra,
baseRouteMatchList: matchList,
type: NavigatingType.restore,
),
);
}

Expand Down
5 changes: 5 additions & 0 deletions packages/go_router/lib/src/parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@ class GoRouteInformationParser extends RouteInformationParser<RouteMatchList> {
);
case NavigatingType.go:
return newMatchList;
case NavigatingType.restore:
// Still need to consider redirection.
return baseRouteMatchList!.uri.toString() == newMatchList.uri.toString()
? baseRouteMatchList
: newMatchList;
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/lib/src/router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ class GoRouter implements RouterConfig<RouteMatchList> {
log.info('restoring ${matchList.uri}');
routeInformationProvider.restore(
matchList.uri.toString(),
encodedMatchList: RouteMatchListCodec(configuration).encode(matchList),
matchList: matchList,
);
}

Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -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: 10.2.0
version: 11.0.0
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

Expand Down
46 changes: 46 additions & 0 deletions packages/go_router/test/go_router_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2843,6 +2843,52 @@ void main() {
expect(matches.pathParameters['pid'], pid);
});

testWidgets('StatefulShellRoute preserve extra when switching branch',
(WidgetTester tester) async {
StatefulNavigationShell? routeState;
Object? latestExtra;
final List<RouteBase> routes = <RouteBase>[
StatefulShellRoute.indexedStack(
builder: (BuildContext context, GoRouterState state,
StatefulNavigationShell navigationShell) {
routeState = navigationShell;
return navigationShell;
},
branches: <StatefulShellBranch>[
StatefulShellBranch(
routes: <RouteBase>[
GoRoute(
path: '/a',
builder: (BuildContext context, GoRouterState state) =>
const Text('Screen A'),
),
],
),
StatefulShellBranch(
routes: <RouteBase>[
GoRoute(
path: '/b',
builder: (BuildContext context, GoRouterState state) {
latestExtra = state.extra;
return const DummyScreen();
}),
],
),
],
),
];
final Object expectedExtra = Object();

await createRouter(routes, tester,
initialLocation: '/b', initialExtra: expectedExtra);
expect(latestExtra, expectedExtra);
routeState!.goBranch(0);
await tester.pumpAndSettle();
routeState!.goBranch(1);
await tester.pumpAndSettle();
expect(latestExtra, expectedExtra);
});

testWidgets('goNames should allow dynamics values for queryParams',
(WidgetTester tester) async {
const Map<String, dynamic> queryParametersAll = <String, List<dynamic>>{
Expand Down