From 2f515a8b596bd1eb85ac4a542b06f9047ad8624d Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon <49735945+NazarenoCavazzon@users.noreply.github.com> Date: Sat, 9 Jul 2022 16:37:49 -0300 Subject: [PATCH 01/36] Added Asyncs pushes and a pop result --- packages/go_router/lib/go_router.dart | 2 +- packages/go_router/lib/src/go_router.dart | 34 +++++++++++++++++-- .../go_router/lib/src/go_router_delegate.dart | 22 ++++++++++-- packages/go_router/test/go_router_test.dart | 2 +- 4 files changed, 54 insertions(+), 6 deletions(-) diff --git a/packages/go_router/lib/go_router.dart b/packages/go_router/lib/go_router.dart index 56bd9579d67..21dc3483caa 100644 --- a/packages/go_router/lib/go_router.dart +++ b/packages/go_router/lib/go_router.dart @@ -75,5 +75,5 @@ extension GoRouterHelper on BuildContext { /// Pop the top page off the Navigator's page stack by calling /// [Navigator.pop]. - void pop() => GoRouter.of(this).pop(); + void pop([T? result]) => GoRouter.of(this).pop(); } diff --git a/packages/go_router/lib/src/go_router.dart b/packages/go_router/lib/src/go_router.dart index 17a7af14145..ec6f47cf1cc 100644 --- a/packages/go_router/lib/src/go_router.dart +++ b/packages/go_router/lib/src/go_router.dart @@ -147,6 +147,22 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { }); } + /// Push a URI location onto the page stack w/ optional query parameters and + /// a promise, e.g. + /// `/family/f2/person/p1?color=blue` + Future pushAsync(String location, + {Object? extra}) async { + assert(() { + log.info('pushing $location'); + return true; + }()); + final List matches = + await routeInformationParser.parseRouteInformation( + DebugGoRouteInformation(location: location, state: extra), + ); + return routerDelegate.pushAsync(matches.last); + } + /// Push a named route onto the page stack w/ optional parameters, e.g. /// `name='person', params={'fid': 'f2', 'pid': 'p1'}` void pushNamed( @@ -160,16 +176,30 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { extra: extra, ); + /// Push a named route onto the page stack w/ optional parameters and a + /// promise, e.g. + /// `name='person', params={'fid': 'f2', 'pid': 'p1'}` + Future pushNamedAsync( + String name, { + Map params = const {}, + Map queryParams = const {}, + Object? extra, + }) => + pushAsync( + namedLocation(name, params: params, queryParams: queryParams), + extra: extra, + ); + /// Returns `true` if there is more than 1 page on the stack. bool canPop() => routerDelegate.canPop(); /// Pop the top page off the GoRouter's page stack. - void pop() { + void pop([T? result]) { assert(() { log.info('popping $location'); return true; }()); - routerDelegate.pop(); + routerDelegate.pop(result); } /// Refresh the route. diff --git a/packages/go_router/lib/src/go_router_delegate.dart b/packages/go_router/lib/src/go_router_delegate.dart index 3ea7e624ea7..51888cbcae3 100644 --- a/packages/go_router/lib/src/go_router_delegate.dart +++ b/packages/go_router/lib/src/go_router_delegate.dart @@ -58,6 +58,8 @@ class GoRouterDelegate extends RouterDelegate> final GlobalKey _key = GlobalKey(); List _matches = const []; + final Map> _completers = + >{}; /// Push the given location onto the page stack void push(GoRouteMatch match) { @@ -70,8 +72,24 @@ class GoRouterDelegate extends RouterDelegate> return _matches.length > 1; } + /// Push the given location onto the page stack with a promise + Future pushAsync(GoRouteMatch match) { + final Completer completer = Completer(); + _completers[match.fullpath] = completer; + _matches.add(match); + notifyListeners(); + return completer.future; + } + /// Pop the top page off the GoRouter's page stack. - void pop() { + void pop([T? result]) { + final GoRouteMatch last = _matches.last; + final Completer? completer = _completers[last.fullpath] as Completer?; + + if (completer != null) { + completer.complete(result); + } + _completers.remove(last.fullpath); _matches.remove(_matches.last); assert(_matches.isNotEmpty, 'have popped the last page off of the stack; there are no pages left to show'); @@ -179,7 +197,7 @@ class GoRouterDelegate extends RouterDelegate> if (!route.didPop(result)) { return false; } - pop(); + pop(result); return true; }, ), diff --git a/packages/go_router/test/go_router_test.dart b/packages/go_router/test/go_router_test.dart index bd7e3e8fb9f..57cefa8a0aa 100644 --- a/packages/go_router/test/go_router_test.dart +++ b/packages/go_router/test/go_router_test.dart @@ -1930,7 +1930,7 @@ class GoRouterPopSpy extends GoRouter { bool popped = false; @override - void pop() { + void pop([T? result]) { popped = true; } } From 25577e2b0a7ac1437c5e3a452b508fccdeb2af2a Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon <49735945+NazarenoCavazzon@users.noreply.github.com> Date: Sat, 9 Jul 2022 16:48:29 -0300 Subject: [PATCH 02/36] Update go_router.dart --- packages/go_router/lib/go_router.dart | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/go_router/lib/go_router.dart b/packages/go_router/lib/go_router.dart index 21dc3483caa..f25a1c2d543 100644 --- a/packages/go_router/lib/go_router.dart +++ b/packages/go_router/lib/go_router.dart @@ -70,6 +70,21 @@ extension GoRouterHelper on BuildContext { extra: extra, ); + /// Navigate to a named route onto the page stack. + Future pushNamedAsync( + String name, { + Map params = const {}, + Map queryParams = const {}, + Object? extra, + }) async { + return GoRouter.of(this).pushNamedAsync( + name, + params: params, + queryParams: queryParams, + extra: extra, + ); + } + /// Returns `true` if there is more than 1 page on the stack. bool canPop() => GoRouter.of(this).canPop(); From 2be6daa0c5ca9ecf055bb25dc5649d5b5db6720d Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon <49735945+NazarenoCavazzon@users.noreply.github.com> Date: Sat, 9 Jul 2022 16:56:37 -0300 Subject: [PATCH 03/36] Added pushAsync --- packages/go_router/lib/go_router.dart | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/go_router/lib/go_router.dart b/packages/go_router/lib/go_router.dart index f25a1c2d543..f39ead751b1 100644 --- a/packages/go_router/lib/go_router.dart +++ b/packages/go_router/lib/go_router.dart @@ -56,6 +56,10 @@ extension GoRouterHelper on BuildContext { void push(String location, {Object? extra}) => GoRouter.of(this).push(location, extra: extra); + /// Push a location onto the page stack with a promise. + Future pushAsync(String location, {Object? extra}) => + GoRouter.of(this).pushAsync(location, extra: extra); + /// Navigate to a named route onto the page stack. void pushNamed( String name, { @@ -76,14 +80,13 @@ extension GoRouterHelper on BuildContext { Map params = const {}, Map queryParams = const {}, Object? extra, - }) async { - return GoRouter.of(this).pushNamedAsync( - name, - params: params, - queryParams: queryParams, - extra: extra, - ); - } + }) => + GoRouter.of(this).pushNamedAsync( + name, + params: params, + queryParams: queryParams, + extra: extra, + ); /// Returns `true` if there is more than 1 page on the stack. bool canPop() => GoRouter.of(this).canPop(); From 05ab251c575b2658c694dc66bdd27bf09360a5cb Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon <49735945+NazarenoCavazzon@users.noreply.github.com> Date: Sat, 9 Jul 2022 17:13:01 -0300 Subject: [PATCH 04/36] Added documentation to the _completers variable --- packages/go_router/lib/src/go_router_delegate.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/go_router/lib/src/go_router_delegate.dart b/packages/go_router/lib/src/go_router_delegate.dart index 51888cbcae3..f4442eddd7f 100644 --- a/packages/go_router/lib/src/go_router_delegate.dart +++ b/packages/go_router/lib/src/go_router_delegate.dart @@ -58,6 +58,8 @@ class GoRouterDelegate extends RouterDelegate> final GlobalKey _key = GlobalKey(); List _matches = const []; + + /// Map of the completers for each route. final Map> _completers = >{}; From 9f20a7173b42f1f0c89b1e6af01dc4f149de1695 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon <49735945+NazarenoCavazzon@users.noreply.github.com> Date: Sat, 9 Jul 2022 17:27:13 -0300 Subject: [PATCH 05/36] Update go_router.dart --- packages/go_router/lib/go_router.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/go_router/lib/go_router.dart b/packages/go_router/lib/go_router.dart index f39ead751b1..8479879e968 100644 --- a/packages/go_router/lib/go_router.dart +++ b/packages/go_router/lib/go_router.dart @@ -93,5 +93,5 @@ extension GoRouterHelper on BuildContext { /// Pop the top page off the Navigator's page stack by calling /// [Navigator.pop]. - void pop([T? result]) => GoRouter.of(this).pop(); + void pop([T? result]) => GoRouter.of(this).pop(result); } From 90954e147ceffcc037d082bebd7c0c296d360a8d Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon <49735945+NazarenoCavazzon@users.noreply.github.com> Date: Sat, 9 Jul 2022 17:32:43 -0300 Subject: [PATCH 06/36] Update go_router_delegate.dart --- packages/go_router/lib/src/go_router_delegate.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/go_router/lib/src/go_router_delegate.dart b/packages/go_router/lib/src/go_router_delegate.dart index f4442eddd7f..e8071b6b960 100644 --- a/packages/go_router/lib/src/go_router_delegate.dart +++ b/packages/go_router/lib/src/go_router_delegate.dart @@ -60,8 +60,8 @@ class GoRouterDelegate extends RouterDelegate> List _matches = const []; /// Map of the completers for each route. - final Map> _completers = - >{}; + final Map> _completers = + >{}; /// Push the given location onto the page stack void push(GoRouteMatch match) { @@ -86,7 +86,7 @@ class GoRouterDelegate extends RouterDelegate> /// Pop the top page off the GoRouter's page stack. void pop([T? result]) { final GoRouteMatch last = _matches.last; - final Completer? completer = _completers[last.fullpath] as Completer?; + final Completer? completer = _completers[last.fullpath]; if (completer != null) { completer.complete(result); From 1750b55a23ef512ebc33768993d2c6d6eb495c1c Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon <49735945+NazarenoCavazzon@users.noreply.github.com> Date: Sat, 9 Jul 2022 17:37:37 -0300 Subject: [PATCH 07/36] Changed T to dynamic --- packages/go_router/lib/go_router.dart | 8 ++++---- packages/go_router/lib/src/go_router.dart | 9 ++++----- packages/go_router/lib/src/go_router_delegate.dart | 8 ++++---- packages/go_router/test/go_router_test.dart | 2 +- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/packages/go_router/lib/go_router.dart b/packages/go_router/lib/go_router.dart index 8479879e968..a735a3cfc82 100644 --- a/packages/go_router/lib/go_router.dart +++ b/packages/go_router/lib/go_router.dart @@ -57,7 +57,7 @@ extension GoRouterHelper on BuildContext { GoRouter.of(this).push(location, extra: extra); /// Push a location onto the page stack with a promise. - Future pushAsync(String location, {Object? extra}) => + Future pushAsync(String location, {Object? extra}) => GoRouter.of(this).pushAsync(location, extra: extra); /// Navigate to a named route onto the page stack. @@ -75,13 +75,13 @@ extension GoRouterHelper on BuildContext { ); /// Navigate to a named route onto the page stack. - Future pushNamedAsync( + Future pushNamedAsync( String name, { Map params = const {}, Map queryParams = const {}, Object? extra, }) => - GoRouter.of(this).pushNamedAsync( + GoRouter.of(this).pushNamedAsync( name, params: params, queryParams: queryParams, @@ -93,5 +93,5 @@ extension GoRouterHelper on BuildContext { /// Pop the top page off the Navigator's page stack by calling /// [Navigator.pop]. - void pop([T? result]) => GoRouter.of(this).pop(result); + void pop([dynamic result]) => GoRouter.of(this).pop(result); } diff --git a/packages/go_router/lib/src/go_router.dart b/packages/go_router/lib/src/go_router.dart index ec6f47cf1cc..a70267fbc08 100644 --- a/packages/go_router/lib/src/go_router.dart +++ b/packages/go_router/lib/src/go_router.dart @@ -150,8 +150,7 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { /// Push a URI location onto the page stack w/ optional query parameters and /// a promise, e.g. /// `/family/f2/person/p1?color=blue` - Future pushAsync(String location, - {Object? extra}) async { + Future pushAsync(String location, {Object? extra}) async { assert(() { log.info('pushing $location'); return true; @@ -179,7 +178,7 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { /// Push a named route onto the page stack w/ optional parameters and a /// promise, e.g. /// `name='person', params={'fid': 'f2', 'pid': 'p1'}` - Future pushNamedAsync( + Future pushNamedAsync( String name, { Map params = const {}, Map queryParams = const {}, @@ -194,12 +193,12 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { bool canPop() => routerDelegate.canPop(); /// Pop the top page off the GoRouter's page stack. - void pop([T? result]) { + void pop([dynamic result]) { assert(() { log.info('popping $location'); return true; }()); - routerDelegate.pop(result); + routerDelegate.pop(result); } /// Refresh the route. diff --git a/packages/go_router/lib/src/go_router_delegate.dart b/packages/go_router/lib/src/go_router_delegate.dart index e8071b6b960..bccaa410ae1 100644 --- a/packages/go_router/lib/src/go_router_delegate.dart +++ b/packages/go_router/lib/src/go_router_delegate.dart @@ -75,8 +75,8 @@ class GoRouterDelegate extends RouterDelegate> } /// Push the given location onto the page stack with a promise - Future pushAsync(GoRouteMatch match) { - final Completer completer = Completer(); + Future pushAsync(GoRouteMatch match) { + final Completer completer = Completer(); _completers[match.fullpath] = completer; _matches.add(match); notifyListeners(); @@ -84,7 +84,7 @@ class GoRouterDelegate extends RouterDelegate> } /// Pop the top page off the GoRouter's page stack. - void pop([T? result]) { + void pop([dynamic result]) { final GoRouteMatch last = _matches.last; final Completer? completer = _completers[last.fullpath]; @@ -199,7 +199,7 @@ class GoRouterDelegate extends RouterDelegate> if (!route.didPop(result)) { return false; } - pop(result); + pop(result); return true; }, ), diff --git a/packages/go_router/test/go_router_test.dart b/packages/go_router/test/go_router_test.dart index 57cefa8a0aa..7b6829a708d 100644 --- a/packages/go_router/test/go_router_test.dart +++ b/packages/go_router/test/go_router_test.dart @@ -1930,7 +1930,7 @@ class GoRouterPopSpy extends GoRouter { bool popped = false; @override - void pop([T? result]) { + void pop([dynamic result]) { popped = true; } } From 06a2ae51845603360674fde97734b0b238b5481b Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon <49735945+NazarenoCavazzon@users.noreply.github.com> Date: Sat, 9 Jul 2022 17:43:32 -0300 Subject: [PATCH 08/36] Update go_router.dart --- packages/go_router/lib/go_router.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/go_router/lib/go_router.dart b/packages/go_router/lib/go_router.dart index a735a3cfc82..8884997641c 100644 --- a/packages/go_router/lib/go_router.dart +++ b/packages/go_router/lib/go_router.dart @@ -57,8 +57,8 @@ extension GoRouterHelper on BuildContext { GoRouter.of(this).push(location, extra: extra); /// Push a location onto the page stack with a promise. - Future pushAsync(String location, {Object? extra}) => - GoRouter.of(this).pushAsync(location, extra: extra); + Future pushAsync(String location, {Object? extra}) => + GoRouter.of(this).pushAsync(location, extra: extra) as Future; /// Navigate to a named route onto the page stack. void pushNamed( @@ -75,7 +75,7 @@ extension GoRouterHelper on BuildContext { ); /// Navigate to a named route onto the page stack. - Future pushNamedAsync( + Future pushNamedAsync( String name, { Map params = const {}, Map queryParams = const {}, @@ -86,7 +86,7 @@ extension GoRouterHelper on BuildContext { params: params, queryParams: queryParams, extra: extra, - ); + ) as Future; /// Returns `true` if there is more than 1 page on the stack. bool canPop() => GoRouter.of(this).canPop(); From b77cc1068b53c75f286e6d3e66797db3c0a07113 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon <49735945+NazarenoCavazzon@users.noreply.github.com> Date: Sat, 9 Jul 2022 17:46:16 -0300 Subject: [PATCH 09/36] Revert "Update go_router.dart" This reverts commit 06a2ae51845603360674fde97734b0b238b5481b. --- packages/go_router/lib/go_router.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/go_router/lib/go_router.dart b/packages/go_router/lib/go_router.dart index 8884997641c..a735a3cfc82 100644 --- a/packages/go_router/lib/go_router.dart +++ b/packages/go_router/lib/go_router.dart @@ -57,8 +57,8 @@ extension GoRouterHelper on BuildContext { GoRouter.of(this).push(location, extra: extra); /// Push a location onto the page stack with a promise. - Future pushAsync(String location, {Object? extra}) => - GoRouter.of(this).pushAsync(location, extra: extra) as Future; + Future pushAsync(String location, {Object? extra}) => + GoRouter.of(this).pushAsync(location, extra: extra); /// Navigate to a named route onto the page stack. void pushNamed( @@ -75,7 +75,7 @@ extension GoRouterHelper on BuildContext { ); /// Navigate to a named route onto the page stack. - Future pushNamedAsync( + Future pushNamedAsync( String name, { Map params = const {}, Map queryParams = const {}, @@ -86,7 +86,7 @@ extension GoRouterHelper on BuildContext { params: params, queryParams: queryParams, extra: extra, - ) as Future; + ); /// Returns `true` if there is more than 1 page on the stack. bool canPop() => GoRouter.of(this).canPop(); From a5a1df9ca892b08dfb6eed85ad7b7d79ddbac452 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon <49735945+NazarenoCavazzon@users.noreply.github.com> Date: Sat, 9 Jul 2022 17:57:23 -0300 Subject: [PATCH 10/36] CHANGELOG updated and version updated in the pubspec.yaml --- packages/go_router/CHANGELOG.md | 299 ++++++++++++++++---------------- packages/go_router/pubspec.yaml | 2 +- 2 files changed, 152 insertions(+), 149 deletions(-) diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index 463f23da4ff..6c674fd4cb6 100644 --- a/packages/go_router/CHANGELOG.md +++ b/packages/go_router/CHANGELOG.md @@ -1,3 +1,8 @@ +## 4.2.0 + +- Adds `pushAsync` and `pushNamedAsync` to `GoRouterHelper` making it posible to await results from a `pop`. +- Adds an optional parameter to the `pop` method, allowing to return values from a `pop. + ## 4.1.0 - Adds `bool canPop()` to `GoRouterDelegate`, `GoRouter` and `GoRouterHelper`. @@ -8,7 +13,7 @@ ## 4.0.2 -- Fixes a bug where initialLocation took precedence over deep-links +- Fixes a bug where initialLocation took precedence over deep-links. ## 4.0.1 @@ -21,7 +26,7 @@ ## 3.1.1 -- Uses first match if there are more than one route to match. [ [#99833](https://github.com/flutter/flutter/issues/99833) +- Uses first match if there are more than one route to match. [#99833](https://github.com/flutter/flutter/issues/99833) ## 3.1.0 @@ -37,8 +42,7 @@ ## 3.0.5 -- Add `dispatchNotification` method to `DummyBuildContext` in tests. (This - should be revisited when Flutter `2.11.0` becomes stable.) +- Add `dispatchNotification` method to `DummyBuildContext` in tests (this should be revisited when Flutter `2.11.0` becomes stable). - Improves code coverage. - `GoRoute` now warns about requiring either `pageBuilder`, `builder` or `redirect` at instantiation. @@ -57,57 +61,56 @@ ## 3.0.1 -- pass along the error to the `navigatorBuilder` to allow for different - implementations based on the presence of an error +- pass along the error to the `navigatorBuilder` to allow for different implementations based on the presence of an error. ## 3.0.0 -- breaking change: added `GoRouterState` to `navigatorBuilder` function +- breaking change: added `GoRouterState` to `navigatorBuilder` function. - breaking change: removed `BuildContext` from `GoRouter.pop()` to remove the need to use `context` parameter when calling the `GoRouter` API; this changes the behavior of `GoRouter.pop()` to only pop what's on the `GoRouter` page - stack and no longer calls `Navigator.pop()` + stack and no longer calls `Navigator.pop()`. - new [Migrating to 3.0 section](https://gorouter.dev/migrating-to-30) in the docs to describe the details of the breaking changes and how to update your - code + code. - added a new [shared scaffold](https://github.com/csells/go_router/blob/main/go_router/example/lib/shared_scaffold.dart) sample to show how to use the `navigatorBuilder` function to build a custom - shared scaffold outside of the animations provided by go_router + shared scaffold outside of the animations provided by go_router. ## 2.5.7 - [PR 262](https://github.com/csells/go_router/pull/262): add support for - `Router.neglect`; thanks to [nullrocket](https://github.com/nullrocket)! + `Router.neglect`; thanks to [nullrocket](https://github.com/nullrocket)!. - [PR 265](https://github.com/csells/go_router/pull/265): add Japanese translation of the docs; thanks to [toshi-kuji](https://github.com/toshi-kuji)! Unfortunately I don't yet know how to properly display them via docs.page, but [I'm working on - it](https://github.com/csells/go_router/issues/266) + it](https://github.com/csells/go_router/issues/266). - updated the examples using the `from` query parameter to be completely - self-contained in the `redirect` function, simplifying usage -- updated the async data example to be simpler -- added a new example to show how to implement a loading page + self-contained in the `redirect` function, simplifying usage. +- updated the async data example to be simpler. +- added a new example to show how to implement a loading page. - renamed the navigator_integration example to user_input and added an example - of `WillPopScope` for go_router apps + of `WillPopScope` for go_router apps. ## 2.5.6 - [PR 259](https://github.com/csells/go_router/pull/259): remove a hack for notifying the router of a route change that was no longer needed; thanks to - [nullrocket](https://github.com/nullrocket)! + [nullrocket](https://github.com/nullrocket)!. - improved async example to handle the case that the data has been returned but - the page is no longer there by checking the `mounted` property of the screen + the page is no longer there by checking the `mounted` property of the screen. ## 2.5.5 - updated implementation to use logging package for debug diagnostics; thanks - to [johnpryan](https://github.com/johnpryan) + to [johnpryan](https://github.com/johnpryan). ## 2.5.4 - fixed up the `GoRouterRefreshStream` implementation with an export, an example - and some docs + and some docs. ## 2.5.3 @@ -115,9 +118,9 @@ [jopmiddelkamp](https://github.com/jopmiddelkamp) to easily map from a `Stream` to a `Listenable` for use with `refreshListenable`; very useful when combined with stream-based state management like - [flutter_bloc](https://pub.dev/packages/flutter_bloc) -- dartdocs fixups from [mehade369](https://github.com/mehade369) -- example link fixes from [ben-milanko](https://github.com/ben-milanko) + [flutter_bloc](https://pub.dev/packages/flutter_bloc). +- dartdocs fixups from [mehade369](https://github.com/mehade369). +- example link fixes from [ben-milanko](https://github.com/ben-milanko). ## 2.5.2 @@ -128,339 +131,339 @@ - [fix 205](https://github.com/csells/go_router/issues/205): hack around a failed assertion in Flutter when using `Duration.zero` in the - `NoTransitionPage` + `NoTransitionPage`. ## 2.5.0 - provide default implementation of `GoRoute.pageBuilder` to provide a simpler - way to build pages via the `GoRouter.build` method + way to build pages via the `GoRouter.build` method. - provide default implementation of `GoRouter.errorPageBuilder` to provide a - simpler way to build error pages via the `GoRouter.errorBuilder` method + simpler way to build error pages via the `GoRouter.errorBuilder` method. - provide default implementation of `GoRouter.errorBuilder` to provide an error - page without the need to implement a custom error page builder + page without the need to implement a custom error page builder. - new [Migrating to 2.5 section](https://gorouter.dev/migrating-to-25) in the docs to show how to take advantage of the new `builder` and default error - page builder + page builder. - removed `launch.json` as VSCode-centric and unnecessary for discovery or easy - launching + launching. - added a [new custom error screen - sample](https://github.com/csells/go_router/blob/master/example/lib/error_screen.dart) + sample](https://github.com/csells/go_router/blob/master/example/lib/error_screen.dart). - added a [new WidgetsApp - sample](https://github.com/csells/go_router/blob/master/example/lib/widgets_app.dart) -- added a new `NoTransitionPage` class + sample](https://github.com/csells/go_router/blob/master/example/lib/widgets_app.dart). +- added a new `NoTransitionPage` class. - updated docs to explain why the browser's Back button doesn't work - with the `extra` param -- updated README to point to new docs site: [gorouter.dev](https://gorouter.dev) + with the `extra` param. +- updated README to point to new docs site: [gorouter.dev](https://gorouter.dev). ## 2.3.1 - [fix 191](https://github.com/csells/go_router/issues/191): handle several - kinds of trailing / in the location, e.g. `/foo/` should be the same as `/foo` + kinds of trailing / in the location, e.g. `/foo/` should be the same as `/foo`. ## 2.3.0 -- fix a misleading error message when using redirect functions with sub-routes +- fix a misleading error message when using redirect functions with sub-routes. ## 2.2.9 - [fix 182](https://github.com/csells/go_router/issues/182): fixes a regression in the nested navigation caused by the fix for [#163](https://github.com/csells/go_router/issues/163); thanks to - [lulupointu](https://github.com/lulupointu) for the fix! + [lulupointu](https://github.com/lulupointu) for the fix!. ## 2.2.8 - reformatted CHANGELOG file; lets see if pub.dev is still ok with it... -- staged an in-progress doc site at https://docs.page/csells/go_router -- tightened up a test that was silently failing -- fixed a bug that dropped parent params in sub-route redirects +- staged an in-progress doc site at https://docs.page/csells/go_router. +- tightened up a test that was silently failing. +- fixed a bug that dropped parent params in sub-route redirects. ## 2.2.7 - [fix 163](https://github.com/csells/go_router/issues/163): avoids unnecessary - page rebuilds + page rebuilds. - [fix 139](https://github.com/csells/go_router/issues/139): avoids unnecessary - page flashes on deep linking + page flashes on deep linking. - [fix 158](https://github.com/csells/go_router/issues/158): shows exception info in the debug output even during a top-level redirect coded w/ an - anonymous function, i.e. what the samples all use + anonymous function, i.e. what the samples all use. - [fix 151](https://github.com/csells/go_router/issues/151): exposes - `Navigator.pop()` via `GoRouter.pop()` to make it easy to find + `Navigator.pop()` via `GoRouter.pop()` to make it easy to find. ## 2.2.6 - [fix 127](https://github.com/csells/go_router/issues/127): updated the docs to add a video overview of the project for people that prefer that media style - over long-form text when approaching a new topic + over long-form text when approaching a new topic. - [fix 108](https://github.com/csells/go_router/issues/108): updated the description of the `state` parameter to clarfy that not all properties will be - set at every usage + set at every usage. ## 2.2.5 - [fix 120 again](https://github.com/csells/go_router/issues/120): found the bug in my tests that was masking the real bug; changed two characters to implement - the actual fix (sigh) + the actual fix (sigh). ## 2.2.4 - [fix 116](https://github.com/csells/go_router/issues/116): work-around for - auto-import of the `context.go` family of extension methods + auto-import of the `context.go` family of extension methods. ## 2.2.3 - [fix 132](https://github.com/csells/go_router/issues/132): route names are - stored as case insensitive and are now matched in a case insensitive manner + stored as case insensitive and are now matched in a case insensitive manner. ## 2.2.2 - [fix 120](https://github.com/csells/go_router/issues/120): encoding and - decoding of params and query params + decoding of params and query params. ## 2.2.1 - [fix 114](https://github.com/csells/go_router/issues/114): give a better error message when the `GoRouter` isn't found in the widget tree via `GoRouter.of(context)`; thanks [aoatmon](https://github.com/aoatmon) for the - [excellent bug report](https://github.com/csells/go_router/issues/114)! + [excellent bug report](https://github.com/csells/go_router/issues/114)!. ## 2.2.0 - added a new [`navigatorBuilder`](https://gorouter.dev/navigator-builder) argument to the - `GoRouter` constructor; thanks to [andyduke](https://github.com/andyduke)! + `GoRouter` constructor; thanks to [andyduke](https://github.com/andyduke)!. - also from [andyduke](https://github.com/andyduke) is an update to - improve state restoration -- refactor from [kevmoo](https://github.com/kevmoo) for easier maintenance + improve state restoration. +- refactor from [kevmoo](https://github.com/kevmoo) for easier maintenance. - added a new [Navigator Integration section of the - docs](https://gorouter.dev/navigator-integration) + docs](https://gorouter.dev/navigator-integration). ## 2.1.2 - [fix 61 again](https://github.com/csells/go_router/issues/61): enable images - and file links to work on pub.dev/documentation + and file links to work on pub.dev/documentation. - [fix 62](https://github.com/csells/go_router/issues/62) re-tested; fixed w/ - earlier Android system Back button fix (using navigation key) + earlier Android system Back button fix (using navigation key). - [fix 91](https://github.com/csells/go_router/issues/91): fix a regression w/ - the `errorPageBuilder` + the `errorPageBuilder`. - [fix 92](https://github.com/csells/go_router/issues/92): fix an edge case w/ - named sub-routes + named sub-routes. - [fix 89](https://github.com/csells/go_router/issues/89): enable queryParams - and extra object param w/ `push` -- refactored tests for greater coverage and fewer methods `@visibleForTesting` + and extra object param w/ `push`. +- refactored tests for greater coverage and fewer methods `@visibleForTesting`. ## 2.1.1 - [fix 86](https://github.com/csells/go_router/issues/86): add `name` to `GoRouterState` to complete support for URI-free navigation knowledge in your - code + code. - [fix 83](https://github.com/csells/go_router/issues/83): fix for `null` - `extra` object + `extra` object. ## 2.1.0 - [fix 80](https://github.com/csells/go_router/issues/80): adding a redirect - limit to catch too many redirects error + limit to catch too many redirects error. - [fix 81](https://github.com/csells/go_router/issues/81): allow an `extra` - object to pass through for navigation + object to pass through for navigation. ## 2.0.1 - add badges to the README and codecov to the GitHub commit action; thanks to - [rydmike](https://github.com/rydmike) for both + [rydmike](https://github.com/rydmike) for both. ## 2.0.0 - BREAKING CHANGE and [fix #50](https://github.com/csells/go_router/issues/50): split `params` into `params` and `queryParams`; see the [Migrating to 2.0 section of the docs](https://gorouter.dev/migrating-to-20) - for instructions on how to migrate your code from 1.x to 2.0 + for instructions on how to migrate your code from 1.x to 2.0. - [fix 69](https://github.com/csells/go_router/issues/69): exposed named - location lookup for redirection + location lookup for redirection. - [fix 57](https://github.com/csells/go_router/issues/57): enable the Android system Back button to behave exactly like the `AppBar` Back button; thanks to [SunlightBro](https://github.com/SunlightBro) for the one-line fix that I had - no idea about until he pointed it out + no idea about until he pointed it out. - [fix 59](https://github.com/csells/go_router/issues/59): add query params to - top-level redirect + top-level redirect. - [fix 44](https://github.com/csells/go_router/issues/44): show how to use the `AutomaticKeepAliveClientMixin` with nested navigation to keep widget state between navigations; thanks to [rydmike](https://github.com/rydmike) for this - update + update. ## 1.1.3 - enable case-insensitive path matching while still preserving path and query - parameter cases + parameter cases. - change a lifetime of habit to sort constructors first as per [sort_constructors_first](https://dart-lang.github.io/linter/lints/sort_constructors_first.html). - Thanks for the PR, [Abhishek01039](https://github.com/Abhishek01039)! + Thanks for the PR, [Abhishek01039](https://github.com/Abhishek01039)!. - set the initial transition example route to `/none` to make pushing the 'fade - transition' button on the first run through more fun -- fixed an error in the async data example + transition' button on the first run through more fun. +- fixed an error in the async data example. ## 1.1.2 - Thanks, Mikes! - - updated dartdocs from [rydmike](https://github.com/rydmike) + - updated dartdocs from [rydmike](https://github.com/rydmike). - also shoutout to [https://github.com/Salakar](https://github.com/Salakar) - for the CI action on GitHub + for the CI action on GitHub. - this is turning into a real community effort... ## 1.1.1 -- now showing routing exceptions in the debug log +- now showing routing exceptions in the debug log. - updated the docs to make it clear that it will be called until it returns - `null` + `null`. ## 1.1.0 -- added support `NavigatorObserver` objects to receive change notifications +- added support `NavigatorObserver` objects to receive change notifications. ## 1.0.1 -- docs updates based on user feedback for clarity -- fix for setting URL path strategy in `main()` -- fix for `push()` disables `AppBar` Back button +- docs updates based on user feedback for clarity. +- fix for setting URL path strategy in `main()`. +- fix for `push()` disables `AppBar` Back button. ## 1.0.0 -- updated version for initial release +- updated version for initial release. - some renaming for clarify and consistency with transitions - `GoRoute.builder` => `GoRoute.pageBuilder` - `GoRoute.error` => `GoRoute.errorPageBuilder` -- added diagnostic logging for `push` and `pushNamed` +- added diagnostic logging for `push` and `pushNamed`. ## 0.9.6 -- added support for `push` as well as `go` -- added 'none' to transitions example app +- added support for `push` as well as `go`. +- added 'none' to transitions example app. - updated animation example to use no transition and added an animated gif to - the docs + the docs. ## 0.9.5 -- added support for custom transitions between routes +- added support for custom transitions between routes. ## 0.9.4 -- updated API docs -- updated docs for `GoRouterState` +- updated API docs. +- updated docs for `GoRouterState`. ## 0.9.3 -- updated API docs +- updated API docs. ## 0.9.2 -- updated named route lookup to O(1) -- updated diagnostics output to show known named routes +- updated named route lookup to O(1). +- updated diagnostics output to show known named routes. ## 0.9.1 -- updated diagnostics output to show named route lookup -- docs updates +- updated diagnostics output to show named route lookup. +- docs updates. ## 0.9.0 -- added support for named routes +- added support for named routes. ## 0.8.8 -- fix to make `GoRouter` notify on pop +- fix to make `GoRouter` notify on pop. ## 0.8.7 -- made `GoRouter` a `ChangeNotifier` so you can listen for `location` changes +- made `GoRouter` a `ChangeNotifier` so you can listen for `location` changes. ## 0.8.6 -- books sample bug fix +- books sample bug fix. ## 0.8.5 -- added Cupertino sample -- added example of async data lookup +- added Cupertino sample. +- added example of async data lookup. ## 0.8.4 -- added state restoration sample +- added state restoration sample. ## 0.8.3 - changed `debugOutputFullPaths` to `debugLogDiagnostics` and added add'l - debugging logging -- parameterized redirect + debugging logging. +- parameterized redirect. ## 0.8.2 -- updated docs for `Link` widget support +- updated docs for `Link` widget support. ## 0.8.1 -- added Books sample; fixed some issues it revealed +- added Books sample; fixed some issues it revealed. ## 0.8.0 -- breaking build to refactor the API for simplicity and capability +- breaking build to refactor the API for simplicity and capability. - move to fixed routing from conditional routing; simplies API, allows for - redirection at the route level and there scenario was sketchy anyway -- add redirection at the route level -- replace guard objects w/ redirect functions -- add `refresh` method and `refreshListener` -- removed `.builder` ctor from `GoRouter` (not reasonable to implement) -- add Dynamic linking section to the docs -- replaced Books sample with Nested Navigation sample -- add ability to dump the known full paths to your routes to debug output + redirection at the route level and there scenario was sketchy anyway. +- add redirection at the route level. +- replace guard objects w/ redirect functions. +- add `refresh` method and `refreshListener`. +- removed `.builder` ctor from `GoRouter` (not reasonable to implement). +- add Dynamic linking section to the docs. +- replaced Books sample with Nested Navigation sample. +- add ability to dump the known full paths to your routes to debug output. ## 0.7.1 -- update to pageKey to take sub-routes into account +- update to pageKey to take sub-routes into account. ## 0.7.0 - BREAK: rename `pattern` to `path` for consistency w/ other routers in the - world -- added the `GoRouterLoginGuard` for the common redirect-to-login-page pattern + world. +- added the `GoRouterLoginGuard` for the common redirect-to-login-page pattern. ## 0.6.2 -- fixed issue showing home page for a second before redirecting (if needed) +- fixed issue showing home page for a second before redirecting (if needed). ## 0.6.1 -- added `GoRouterState.pageKey` -- removed `cupertino_icons` from main `pubspec.yaml` +- added `GoRouterState.pageKey`. +- removed `cupertino_icons` from main `pubspec.yaml`. ## 0.6.0 - refactor to support sub-routes to build a stack of pages instead of matching - multiple routes -- added unit tests for building the stack of pages + multiple routes. +- added unit tests for building the stack of pages. - some renaming of the types, e.g. `Four04Page` and `FamiliesPage` to - `ErrorPage` and `HomePage` respectively -- fix a redirection error shown in the debug output + `ErrorPage` and `HomePage` respectively. +- fix a redirection error shown in the debug output. ## 0.5.2 -- add `urlPathStrategy` argument to `GoRouter` ctor +- add `urlPathStrategy` argument to `GoRouter` ctor. ## 0.5.1 -- docs and description updates +- docs and description updates. ## 0.5.0 -- moved redirect to top-level instead of per route for simplicity +- moved redirect to top-level instead of per route for simplicity. ## 0.4.1 -- fixed CHANGELOG formatting +- fixed CHANGELOG formatting. ## 0.4.0 - bundled various useful route handling variables into the `GoRouterState` for - use when building pages and error pages -- updated URL Strategy section of docs to reference `flutter run` + use when building pages and error pages. +- updated URL Strategy section of docs to reference `flutter run`. ## 0.3.2 @@ -468,39 +471,39 @@ ## 0.3.1 -- updated the CHANGELOG +- updated the CHANGELOG. ## 0.3.0 -- moved redirection into a `GoRoute` ctor arg -- forgot to update the CHANGELOG +- moved redirection into a `GoRoute` ctor arg. +- forgot to update the CHANGELOG. ## 0.2.3 - move outstanding issues to [issue - tracker](https://github.com/csells/go_router/issues) -- added explanation of Deep Linking to docs -- reformatting to meet pub.dev scoring guidelines + tracker](https://github.com/csells/go_router/issues). +- added explanation of Deep Linking to docs. +- reformatting to meet pub.dev scoring guidelines. ## 0.2.2 -- docs updates +- docs updates. ## 0.2.1 -- messing with the CHANGELOG formatting +- messing with the CHANGELOG formatting. ## 0.2.0 -- initial useful release -- added support for declarative routes via `GoRoute` instances -- added support for imperative routing via `GoRoute.builder` -- added support for setting the URL path strategy -- added support for conditional routing -- added support for redirection +- initial useful release. +- added support for declarative routes via `GoRoute` instances. +- added support for imperative routing via `GoRoute.builder`. +- added support for setting the URL path strategy. +- added support for conditional routing. +- added support for redirection. - added support for optional query parameters as well as positional parameters - in route names + in route names. ## 0.1.0 -- squatting on the package name (I'm not too proud to admit it) +- squatting on the package name (I'm not too proud to admit it). diff --git a/packages/go_router/pubspec.yaml b/packages/go_router/pubspec.yaml index f122200e755..ec58f361a91 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: 4.1.0 +version: 4.2.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 From 977606e3d7a2ecccfa05feae2114a025e2480f37 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon <49735945+NazarenoCavazzon@users.noreply.github.com> Date: Sat, 9 Jul 2022 18:26:58 -0300 Subject: [PATCH 11/36] Added a space --- packages/go_router/lib/src/go_router_delegate.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/go_router/lib/src/go_router_delegate.dart b/packages/go_router/lib/src/go_router_delegate.dart index bccaa410ae1..031f5d88a8b 100644 --- a/packages/go_router/lib/src/go_router_delegate.dart +++ b/packages/go_router/lib/src/go_router_delegate.dart @@ -91,6 +91,7 @@ class GoRouterDelegate extends RouterDelegate> if (completer != null) { completer.complete(result); } + _completers.remove(last.fullpath); _matches.remove(_matches.last); assert(_matches.isNotEmpty, From f1bfddd2267a9c9cfcf3fc391a4f10503d7c21e7 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Thu, 4 Aug 2022 17:54:38 -0300 Subject: [PATCH 12/36] Test --- packages/go_router/lib/src/delegate.dart | 36 ++++++++++++++++++++++- packages/go_router/lib/src/router.dart | 11 +++---- packages/go_router/test/test_helpers.dart | 2 +- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/packages/go_router/lib/src/delegate.dart b/packages/go_router/lib/src/delegate.dart index 29f0f251f33..201974e12ff 100644 --- a/packages/go_router/lib/src/delegate.dart +++ b/packages/go_router/lib/src/delegate.dart @@ -44,6 +44,9 @@ class GoRouterDelegate extends RouterDelegate final GlobalKey _key = GlobalKey(); + /// The list of completers for the promises when pushing asynchronous routes. + final Map> _completers = + >{}; RouteMatchList _matches = RouteMatchList.empty(); final Map _pushCounts = {}; @@ -69,13 +72,44 @@ class GoRouterDelegate extends RouterDelegate notifyListeners(); } + /// Pushes the given location onto the page stack + Future pushAsync(RouteMatch match) { + // Remap the pageKey to allow any number of the same page on the stack + final String fullPath = match.fullpath; + final Completer completer = Completer(); + _completers[fullPath] = completer; + final int count = (_pushCounts[fullPath] ?? 0) + 1; + _pushCounts[fullPath] = count; + final ValueKey pageKey = ValueKey('$fullPath-p$count'); + final RouteMatch newPageKeyMatch = RouteMatch( + route: match.route, + subloc: match.subloc, + fullpath: match.fullpath, + encodedParams: match.encodedParams, + queryParams: match.queryParams, + extra: match.extra, + error: match.error, + pageKey: pageKey, + ); + + _matches.push(newPageKeyMatch); + notifyListeners(); + return completer.future; + } + /// Returns `true` if there is more than 1 page on the stack. bool canPop() { return _matches.canPop(); } /// Pop the top page off the GoRouter's page stack. - void pop() { + void pop([dynamic value]) { + final RouteMatch last = _matches.last; + final Completer? completer = _completers[last.fullpath]; + if (completer != null) { + completer.complete(value); + } + _completers.remove(last.fullpath); _matches.pop(); notifyListeners(); } diff --git a/packages/go_router/lib/src/router.dart b/packages/go_router/lib/src/router.dart index 8c980e1901d..ad772634fad 100644 --- a/packages/go_router/lib/src/router.dart +++ b/packages/go_router/lib/src/router.dart @@ -198,11 +198,12 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { log.info('pushing $location'); return true; }()); - final List matches = - await routeInformationParser.parseRouteInformation( - DebugGoRouteInformation(location: location, state: extra), - ); - return routerDelegate.pushAsync(matches.last); + _routeInformationParser + .parseRouteInformation( + DebugGoRouteInformation(location: location, state: extra)) + .then((RouteMatchList matches) { + _routerDelegate.pushAsync(matches.last); + }); } /// Push a named route onto the page stack w/ optional parameters, e.g. diff --git a/packages/go_router/test/test_helpers.dart b/packages/go_router/test/test_helpers.dart index 5361ceff76f..0ea28aced0e 100644 --- a/packages/go_router/test/test_helpers.dart +++ b/packages/go_router/test/test_helpers.dart @@ -139,7 +139,7 @@ class GoRouterPopSpy extends GoRouter { bool popped = false; @override - void pop() { + void pop([dynamic value]) { popped = true; } } From 46d5899884e9dc96dd1ef4251df74fad7e16aebd Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Thu, 4 Aug 2022 18:02:02 -0300 Subject: [PATCH 13/36] Extension update --- .../go_router/lib/src/misc/extensions.dart | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/go_router/lib/src/misc/extensions.dart b/packages/go_router/lib/src/misc/extensions.dart index c818c2cd570..3b5d1f287f2 100644 --- a/packages/go_router/lib/src/misc/extensions.dart +++ b/packages/go_router/lib/src/misc/extensions.dart @@ -40,6 +40,10 @@ extension GoRouterHelper on BuildContext { void push(String location, {Object? extra}) => GoRouter.of(this).push(location, extra: extra); + /// Push a location onto the page stack. + void pushAsync(String location, {Object? extra}) => + GoRouter.of(this).pushAsync(location, extra: extra); + /// Navigate to a named route onto the page stack. void pushNamed( String name, { @@ -54,6 +58,20 @@ extension GoRouterHelper on BuildContext { extra: extra, ); + /// Navigate to a named route onto the page stack. + Future pushNamedAsync( + String name, { + Map params = const {}, + Map queryParams = const {}, + Object? extra, + }) => + GoRouter.of(this).pushNamedAsync( + name, + params: params, + queryParams: queryParams, + extra: extra, + ); + /// Returns `true` if there is more than 1 page on the stack. bool canPop() => GoRouter.of(this).canPop(); From 38814a8d0a582cc0c91a7e1b4ec4c4033e3291b0 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Thu, 4 Aug 2022 18:04:48 -0300 Subject: [PATCH 14/36] Update extensions.dart --- packages/go_router/lib/src/misc/extensions.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/go_router/lib/src/misc/extensions.dart b/packages/go_router/lib/src/misc/extensions.dart index 3b5d1f287f2..e53ae5200ee 100644 --- a/packages/go_router/lib/src/misc/extensions.dart +++ b/packages/go_router/lib/src/misc/extensions.dart @@ -41,7 +41,7 @@ extension GoRouterHelper on BuildContext { GoRouter.of(this).push(location, extra: extra); /// Push a location onto the page stack. - void pushAsync(String location, {Object? extra}) => + Future pushAsync(String location, {Object? extra}) => GoRouter.of(this).pushAsync(location, extra: extra); /// Navigate to a named route onto the page stack. From 8e993768066179aff8f3bc7739fe0788352e45d0 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Thu, 4 Aug 2022 18:06:22 -0300 Subject: [PATCH 15/36] Update extensions.dart --- packages/go_router/lib/src/misc/extensions.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/go_router/lib/src/misc/extensions.dart b/packages/go_router/lib/src/misc/extensions.dart index e53ae5200ee..4fceea2f739 100644 --- a/packages/go_router/lib/src/misc/extensions.dart +++ b/packages/go_router/lib/src/misc/extensions.dart @@ -77,7 +77,7 @@ extension GoRouterHelper on BuildContext { /// Pop the top page off the Navigator's page stack by calling /// [Navigator.pop]. - void pop() => GoRouter.of(this).pop(); + void pop([dynamic value]) => GoRouter.of(this).pop(value); /// Replaces the top-most page of the page stack with the given URL location /// w/ optional query parameters, e.g. `/family/f2/person/p1?color=blue`. From 1e6abfeb83ac4c1ec2523c3e2e394b03ea8ef06e Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Thu, 4 Aug 2022 18:40:58 -0300 Subject: [PATCH 16/36] Test working --- packages/go_router/test/go_router_test.dart | 45 +++++++++++++++++++++ packages/go_router/test/test_helpers.dart | 38 +++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/packages/go_router/test/go_router_test.dart b/packages/go_router/test/go_router_test.dart index 5758a580aa4..ba8984f42e7 100644 --- a/packages/go_router/test/go_router_test.dart +++ b/packages/go_router/test/go_router_test.dart @@ -1746,6 +1746,26 @@ void main() { expect(router.extra, extra); }); + testWidgets('calls [pushAsync] on closest GoRouter', + (WidgetTester tester) async { + final GoRouterPushAsyncSpy router = GoRouterPushAsyncSpy(routes: routes); + await tester.pumpWidget( + MaterialApp.router( + routeInformationProvider: router.routeInformationProvider, + routeInformationParser: router.routeInformationParser, + routerDelegate: router.routerDelegate, + title: 'GoRouter Example', + ), + ); + final bool? result = await key.currentContext!.pushAsync( + location, + extra: extra, + ) as bool?; + expect(result, true); + expect(router.myLocation, location); + expect(router.extra, extra); + }); + testWidgets('calls [pushNamed] on closest GoRouter', (WidgetTester tester) async { final GoRouterPushNamedSpy router = GoRouterPushNamedSpy(routes: routes); @@ -1769,6 +1789,31 @@ void main() { expect(router.extra, extra); }); + testWidgets('calls [pushNamedAsync] on closest GoRouter', + (WidgetTester tester) async { + final GoRouterPushNamedAsyncSpy router = + GoRouterPushNamedAsyncSpy(routes: routes); + await tester.pumpWidget( + MaterialApp.router( + routeInformationProvider: router.routeInformationProvider, + routeInformationParser: router.routeInformationParser, + routerDelegate: router.routerDelegate, + title: 'GoRouter Example', + ), + ); + final bool? result = await key.currentContext!.pushNamedAsync( + name, + params: params, + queryParams: queryParams, + extra: extra, + ) as bool?; + expect(result, true); + expect(router.name, name); + expect(router.params, params); + expect(router.queryParams, queryParams); + expect(router.extra, extra); + }); + testWidgets('calls [pop] on closest GoRouter', (WidgetTester tester) async { final GoRouterPopSpy router = GoRouterPopSpy(routes: routes); await tester.pumpWidget( diff --git a/packages/go_router/test/test_helpers.dart b/packages/go_router/test/test_helpers.dart index 0ea28aced0e..bf17a7827f7 100644 --- a/packages/go_router/test/test_helpers.dart +++ b/packages/go_router/test/test_helpers.dart @@ -133,6 +133,44 @@ class GoRouterPushNamedSpy extends GoRouter { } } +class GoRouterPushAsyncSpy extends GoRouter { + GoRouterPushAsyncSpy({required List routes}) : super(routes: routes); + + String? myLocation; + Object? extra; + + @override + Future pushAsync(String location, {Object? extra}) { + myLocation = location; + this.extra = extra; + return Future.value(true); + } +} + +class GoRouterPushNamedAsyncSpy extends GoRouter { + GoRouterPushNamedAsyncSpy({required List routes}) + : super(routes: routes); + + String? name; + Map? params; + Map? queryParams; + Object? extra; + + @override + Future pushNamedAsync( + String name, { + Map params = const {}, + Map queryParams = const {}, + Object? extra, + }) { + this.name = name; + this.params = params; + this.queryParams = queryParams; + this.extra = extra; + return Future.value(true); + } +} + class GoRouterPopSpy extends GoRouter { GoRouterPopSpy({required List routes}) : super(routes: routes); From 87818e23f4ad6eab9c96cf8ce8b5a3f73a80cfbd Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Thu, 4 Aug 2022 18:44:13 -0300 Subject: [PATCH 17/36] Pop with result working --- packages/go_router/lib/src/delegate.dart | 36 ++++++++++++- .../go_router/lib/src/misc/extensions.dart | 20 ++++++- packages/go_router/lib/src/router.dart | 54 ++++++++++++++----- packages/go_router/test/test_helpers.dart | 2 +- 4 files changed, 97 insertions(+), 15 deletions(-) diff --git a/packages/go_router/lib/src/delegate.dart b/packages/go_router/lib/src/delegate.dart index 29f0f251f33..201974e12ff 100644 --- a/packages/go_router/lib/src/delegate.dart +++ b/packages/go_router/lib/src/delegate.dart @@ -44,6 +44,9 @@ class GoRouterDelegate extends RouterDelegate final GlobalKey _key = GlobalKey(); + /// The list of completers for the promises when pushing asynchronous routes. + final Map> _completers = + >{}; RouteMatchList _matches = RouteMatchList.empty(); final Map _pushCounts = {}; @@ -69,13 +72,44 @@ class GoRouterDelegate extends RouterDelegate notifyListeners(); } + /// Pushes the given location onto the page stack + Future pushAsync(RouteMatch match) { + // Remap the pageKey to allow any number of the same page on the stack + final String fullPath = match.fullpath; + final Completer completer = Completer(); + _completers[fullPath] = completer; + final int count = (_pushCounts[fullPath] ?? 0) + 1; + _pushCounts[fullPath] = count; + final ValueKey pageKey = ValueKey('$fullPath-p$count'); + final RouteMatch newPageKeyMatch = RouteMatch( + route: match.route, + subloc: match.subloc, + fullpath: match.fullpath, + encodedParams: match.encodedParams, + queryParams: match.queryParams, + extra: match.extra, + error: match.error, + pageKey: pageKey, + ); + + _matches.push(newPageKeyMatch); + notifyListeners(); + return completer.future; + } + /// Returns `true` if there is more than 1 page on the stack. bool canPop() { return _matches.canPop(); } /// Pop the top page off the GoRouter's page stack. - void pop() { + void pop([dynamic value]) { + final RouteMatch last = _matches.last; + final Completer? completer = _completers[last.fullpath]; + if (completer != null) { + completer.complete(value); + } + _completers.remove(last.fullpath); _matches.pop(); notifyListeners(); } diff --git a/packages/go_router/lib/src/misc/extensions.dart b/packages/go_router/lib/src/misc/extensions.dart index c818c2cd570..4fceea2f739 100644 --- a/packages/go_router/lib/src/misc/extensions.dart +++ b/packages/go_router/lib/src/misc/extensions.dart @@ -40,6 +40,10 @@ extension GoRouterHelper on BuildContext { void push(String location, {Object? extra}) => GoRouter.of(this).push(location, extra: extra); + /// Push a location onto the page stack. + Future pushAsync(String location, {Object? extra}) => + GoRouter.of(this).pushAsync(location, extra: extra); + /// Navigate to a named route onto the page stack. void pushNamed( String name, { @@ -54,12 +58,26 @@ extension GoRouterHelper on BuildContext { extra: extra, ); + /// Navigate to a named route onto the page stack. + Future pushNamedAsync( + String name, { + Map params = const {}, + Map queryParams = const {}, + Object? extra, + }) => + GoRouter.of(this).pushNamedAsync( + name, + params: params, + queryParams: queryParams, + extra: extra, + ); + /// Returns `true` if there is more than 1 page on the stack. bool canPop() => GoRouter.of(this).canPop(); /// Pop the top page off the Navigator's page stack by calling /// [Navigator.pop]. - void pop() => GoRouter.of(this).pop(); + void pop([dynamic value]) => GoRouter.of(this).pop(value); /// Replaces the top-most page of the page stack with the given URL location /// w/ optional query parameters, e.g. `/family/f2/person/p1?color=blue`. diff --git a/packages/go_router/lib/src/router.dart b/packages/go_router/lib/src/router.dart index 644480fe656..ad772634fad 100644 --- a/packages/go_router/lib/src/router.dart +++ b/packages/go_router/lib/src/router.dart @@ -190,6 +190,22 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { }); } + /// Push a URI location onto the page stack w/ optional query parameters and + /// a promise, e.g. + /// `/family/f2/person/p1?color=blue` + Future pushAsync(String location, {Object? extra}) async { + assert(() { + log.info('pushing $location'); + return true; + }()); + _routeInformationParser + .parseRouteInformation( + DebugGoRouteInformation(location: location, state: extra)) + .then((RouteMatchList matches) { + _routerDelegate.pushAsync(matches.last); + }); + } + /// Push a named route onto the page stack w/ optional parameters, e.g. /// `name='person', params={'fid': 'f2', 'pid': 'p1'}` void pushNamed( @@ -203,6 +219,32 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { extra: extra, ); + /// Push a named route onto the page stack w/ optional parameters and a + /// promise, e.g. + /// `name='person', params={'fid': 'f2', 'pid': 'p1'}` + Future pushNamedAsync( + String name, { + Map params = const {}, + Map queryParams = const {}, + Object? extra, + }) => + pushAsync( + namedLocation(name, params: params, queryParams: queryParams), + extra: extra, + ); + + /// Returns `true` if there is more than 1 page on the stack. + bool canPop() => _routerDelegate.canPop(); + + /// Pop the top page off the GoRouter's page stack. + void pop([dynamic result]) { + assert(() { + log.info('popping $location'); + return true; + }()); + routerDelegate.pop(result); + } + /// Replaces the top-most page of the page stack with the given URL location /// w/ optional query parameters, e.g. `/family/f2/person/p1?color=blue`. /// @@ -238,18 +280,6 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { ); } - /// Returns `true` if there is more than 1 page on the stack. - bool canPop() => _routerDelegate.canPop(); - - /// Pop the top page off the GoRouter's page stack. - void pop() { - assert(() { - log.info('popping $location'); - return true; - }()); - _routerDelegate.pop(); - } - /// Refresh the route. void refresh() { assert(() { diff --git a/packages/go_router/test/test_helpers.dart b/packages/go_router/test/test_helpers.dart index 5361ceff76f..0ea28aced0e 100644 --- a/packages/go_router/test/test_helpers.dart +++ b/packages/go_router/test/test_helpers.dart @@ -139,7 +139,7 @@ class GoRouterPopSpy extends GoRouter { bool popped = false; @override - void pop() { + void pop([dynamic value]) { popped = true; } } From 6de9f2afc5d55152c1429ef1a41d6c3369a36d74 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Thu, 4 Aug 2022 18:53:55 -0300 Subject: [PATCH 18/36] Test Made --- packages/go_router/test/go_router_test.dart | 45 +++++++++++++++++++++ packages/go_router/test/test_helpers.dart | 38 +++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/packages/go_router/test/go_router_test.dart b/packages/go_router/test/go_router_test.dart index 5758a580aa4..ba8984f42e7 100644 --- a/packages/go_router/test/go_router_test.dart +++ b/packages/go_router/test/go_router_test.dart @@ -1746,6 +1746,26 @@ void main() { expect(router.extra, extra); }); + testWidgets('calls [pushAsync] on closest GoRouter', + (WidgetTester tester) async { + final GoRouterPushAsyncSpy router = GoRouterPushAsyncSpy(routes: routes); + await tester.pumpWidget( + MaterialApp.router( + routeInformationProvider: router.routeInformationProvider, + routeInformationParser: router.routeInformationParser, + routerDelegate: router.routerDelegate, + title: 'GoRouter Example', + ), + ); + final bool? result = await key.currentContext!.pushAsync( + location, + extra: extra, + ) as bool?; + expect(result, true); + expect(router.myLocation, location); + expect(router.extra, extra); + }); + testWidgets('calls [pushNamed] on closest GoRouter', (WidgetTester tester) async { final GoRouterPushNamedSpy router = GoRouterPushNamedSpy(routes: routes); @@ -1769,6 +1789,31 @@ void main() { expect(router.extra, extra); }); + testWidgets('calls [pushNamedAsync] on closest GoRouter', + (WidgetTester tester) async { + final GoRouterPushNamedAsyncSpy router = + GoRouterPushNamedAsyncSpy(routes: routes); + await tester.pumpWidget( + MaterialApp.router( + routeInformationProvider: router.routeInformationProvider, + routeInformationParser: router.routeInformationParser, + routerDelegate: router.routerDelegate, + title: 'GoRouter Example', + ), + ); + final bool? result = await key.currentContext!.pushNamedAsync( + name, + params: params, + queryParams: queryParams, + extra: extra, + ) as bool?; + expect(result, true); + expect(router.name, name); + expect(router.params, params); + expect(router.queryParams, queryParams); + expect(router.extra, extra); + }); + testWidgets('calls [pop] on closest GoRouter', (WidgetTester tester) async { final GoRouterPopSpy router = GoRouterPopSpy(routes: routes); await tester.pumpWidget( diff --git a/packages/go_router/test/test_helpers.dart b/packages/go_router/test/test_helpers.dart index 0ea28aced0e..cd630b08b5e 100644 --- a/packages/go_router/test/test_helpers.dart +++ b/packages/go_router/test/test_helpers.dart @@ -111,6 +111,20 @@ class GoRouterPushSpy extends GoRouter { } } +class GoRouterPushAsyncSpy extends GoRouter { + GoRouterPushAsyncSpy({required List routes}) : super(routes: routes); + + String? myLocation; + Object? extra; + + @override + Future pushAsync(String location, {Object? extra}) { + myLocation = location; + this.extra = extra; + return Future.value(true); + } +} + class GoRouterPushNamedSpy extends GoRouter { GoRouterPushNamedSpy({required List routes}) : super(routes: routes); @@ -133,6 +147,30 @@ class GoRouterPushNamedSpy extends GoRouter { } } +class GoRouterPushNamedAsyncSpy extends GoRouter { + GoRouterPushNamedAsyncSpy({required List routes}) + : super(routes: routes); + + String? name; + Map? params; + Map? queryParams; + Object? extra; + + @override + Future pushNamedAsync( + String name, { + Map params = const {}, + Map queryParams = const {}, + Object? extra, + }) { + this.name = name; + this.params = params; + this.queryParams = queryParams; + this.extra = extra; + return Future.value(true); + } +} + class GoRouterPopSpy extends GoRouter { GoRouterPopSpy({required List routes}) : super(routes: routes); From 121c560bbcf3e22ce1811cf5e99d03968d52c240 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Thu, 4 Aug 2022 18:54:46 -0300 Subject: [PATCH 19/36] Changelog and version updated --- packages/go_router/CHANGELOG.md | 5 +++++ packages/go_router/pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index 3e73bd13001..247212a818c 100644 --- a/packages/go_router/CHANGELOG.md +++ b/packages/go_router/CHANGELOG.md @@ -1,3 +1,8 @@ +## 4.3.0 + +- Adds `pushAsync` and `pushNamedAsync` to `GoRouterHelper` making it posible to await results from a `pop`. +- Adds an optional parameter to the `pop` method, allowing to return values from a `pop. + ## 4.2.7 - Update README diff --git a/packages/go_router/pubspec.yaml b/packages/go_router/pubspec.yaml index 6f6a2dbfbdb..5a72446104d 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: 4.2.7 +version: 4.3.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 From 63057b5b57ab7c7bd2c72708d802e3e2791c5d33 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Thu, 4 Aug 2022 20:16:41 -0300 Subject: [PATCH 20/36] Changed dynamic to T To make it easier to use, and also more like Navigator 1.0, I changed the dynamic value to T, T extends Object? so in that way we will always expect a nullable value from a pushAsync or pushNamedAsync. The tests has been updated. --- packages/go_router/lib/src/delegate.dart | 8 +++--- .../go_router/lib/src/misc/extensions.dart | 6 ++--- packages/go_router/lib/src/router.dart | 17 ++++++------ packages/go_router/test/go_router_test.dart | 26 +++++++++---------- packages/go_router/test/test_helpers.dart | 20 +++++++------- 5 files changed, 38 insertions(+), 39 deletions(-) diff --git a/packages/go_router/lib/src/delegate.dart b/packages/go_router/lib/src/delegate.dart index 201974e12ff..84359e12822 100644 --- a/packages/go_router/lib/src/delegate.dart +++ b/packages/go_router/lib/src/delegate.dart @@ -73,10 +73,10 @@ class GoRouterDelegate extends RouterDelegate } /// Pushes the given location onto the page stack - Future pushAsync(RouteMatch match) { + Future pushAsync(RouteMatch match) { // Remap the pageKey to allow any number of the same page on the stack final String fullPath = match.fullpath; - final Completer completer = Completer(); + final Completer completer = Completer(); _completers[fullPath] = completer; final int count = (_pushCounts[fullPath] ?? 0) + 1; _pushCounts[fullPath] = count; @@ -103,9 +103,9 @@ class GoRouterDelegate extends RouterDelegate } /// Pop the top page off the GoRouter's page stack. - void pop([dynamic value]) { + void pop([T? value]) { final RouteMatch last = _matches.last; - final Completer? completer = _completers[last.fullpath]; + final Completer? completer = _completers[last.fullpath] as Completer?; if (completer != null) { completer.complete(value); } diff --git a/packages/go_router/lib/src/misc/extensions.dart b/packages/go_router/lib/src/misc/extensions.dart index 4fceea2f739..84b8636907c 100644 --- a/packages/go_router/lib/src/misc/extensions.dart +++ b/packages/go_router/lib/src/misc/extensions.dart @@ -41,7 +41,7 @@ extension GoRouterHelper on BuildContext { GoRouter.of(this).push(location, extra: extra); /// Push a location onto the page stack. - Future pushAsync(String location, {Object? extra}) => + Future pushAsync(String location, {Object? extra}) => GoRouter.of(this).pushAsync(location, extra: extra); /// Navigate to a named route onto the page stack. @@ -59,13 +59,13 @@ extension GoRouterHelper on BuildContext { ); /// Navigate to a named route onto the page stack. - Future pushNamedAsync( + Future pushNamedAsync( String name, { Map params = const {}, Map queryParams = const {}, Object? extra, }) => - GoRouter.of(this).pushNamedAsync( + GoRouter.of(this).pushNamedAsync( name, params: params, queryParams: queryParams, diff --git a/packages/go_router/lib/src/router.dart b/packages/go_router/lib/src/router.dart index ad772634fad..c8cf736ec5e 100644 --- a/packages/go_router/lib/src/router.dart +++ b/packages/go_router/lib/src/router.dart @@ -193,17 +193,16 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { /// Push a URI location onto the page stack w/ optional query parameters and /// a promise, e.g. /// `/family/f2/person/p1?color=blue` - Future pushAsync(String location, {Object? extra}) async { + Future pushAsync(String location, + {Object? extra}) async { assert(() { log.info('pushing $location'); return true; }()); - _routeInformationParser - .parseRouteInformation( - DebugGoRouteInformation(location: location, state: extra)) - .then((RouteMatchList matches) { - _routerDelegate.pushAsync(matches.last); - }); + final RouteMatchList matches = + await _routeInformationParser.parseRouteInformation( + DebugGoRouteInformation(location: location, state: extra)); + return _routerDelegate.pushAsync(matches.last); } /// Push a named route onto the page stack w/ optional parameters, e.g. @@ -222,13 +221,13 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { /// Push a named route onto the page stack w/ optional parameters and a /// promise, e.g. /// `name='person', params={'fid': 'f2', 'pid': 'p1'}` - Future pushNamedAsync( + Future pushNamedAsync( String name, { Map params = const {}, Map queryParams = const {}, Object? extra, }) => - pushAsync( + pushAsync( namedLocation(name, params: params, queryParams: queryParams), extra: extra, ); diff --git a/packages/go_router/test/go_router_test.dart b/packages/go_router/test/go_router_test.dart index ba8984f42e7..3b4dd086afe 100644 --- a/packages/go_router/test/go_router_test.dart +++ b/packages/go_router/test/go_router_test.dart @@ -1676,7 +1676,7 @@ void main() { title: 'GoRouter Example', ), ); - key.currentContext!.namedLocation( + key.currentContext?.namedLocation( name, params: params, queryParams: queryParams, @@ -1696,7 +1696,7 @@ void main() { title: 'GoRouter Example', ), ); - key.currentContext!.go( + key.currentContext?.go( location, extra: extra, ); @@ -1715,7 +1715,7 @@ void main() { title: 'GoRouter Example', ), ); - key.currentContext!.goNamed( + key.currentContext?.goNamed( name, params: params, queryParams: queryParams, @@ -1738,7 +1738,7 @@ void main() { title: 'GoRouter Example', ), ); - key.currentContext!.push( + key.currentContext?.push( location, extra: extra, ); @@ -1757,11 +1757,11 @@ void main() { title: 'GoRouter Example', ), ); - final bool? result = await key.currentContext!.pushAsync( + final String? result = await key.currentContext?.pushAsync( location, extra: extra, - ) as bool?; - expect(result, true); + ); + expect(result, extra); expect(router.myLocation, location); expect(router.extra, extra); }); @@ -1777,7 +1777,7 @@ void main() { title: 'GoRouter Example', ), ); - key.currentContext!.pushNamed( + key.currentContext?.pushNamed( name, params: params, queryParams: queryParams, @@ -1801,17 +1801,17 @@ void main() { title: 'GoRouter Example', ), ); - final bool? result = await key.currentContext!.pushNamedAsync( + final String? result = await key.currentContext?.pushNamedAsync( name, params: params, queryParams: queryParams, extra: extra, - ) as bool?; - expect(result, true); + ); + expect(result, extra); + expect(router.extra, extra); expect(router.name, name); expect(router.params, params); expect(router.queryParams, queryParams); - expect(router.extra, extra); }); testWidgets('calls [pop] on closest GoRouter', (WidgetTester tester) async { @@ -1824,7 +1824,7 @@ void main() { title: 'GoRouter Example', ), ); - key.currentContext!.pop(); + key.currentContext?.pop(); expect(router.popped, true); }); }); diff --git a/packages/go_router/test/test_helpers.dart b/packages/go_router/test/test_helpers.dart index cd630b08b5e..5eb19e84b42 100644 --- a/packages/go_router/test/test_helpers.dart +++ b/packages/go_router/test/test_helpers.dart @@ -118,10 +118,10 @@ class GoRouterPushAsyncSpy extends GoRouter { Object? extra; @override - Future pushAsync(String location, {Object? extra}) { + Future pushAsync(String location, {Object? extra}) { myLocation = location; this.extra = extra; - return Future.value(true); + return Future.value(extra as T); } } @@ -157,7 +157,7 @@ class GoRouterPushNamedAsyncSpy extends GoRouter { Object? extra; @override - Future pushNamedAsync( + Future pushNamedAsync( String name, { Map params = const {}, Map queryParams = const {}, @@ -167,7 +167,7 @@ class GoRouterPushNamedAsyncSpy extends GoRouter { this.params = params; this.queryParams = queryParams; this.extra = extra; - return Future.value(true); + return Future.value(extra as T); } } @@ -229,19 +229,19 @@ class TestErrorScreen extends DummyScreen { } class HomeScreen extends DummyScreen { - const HomeScreen({Key? key}) : super(key: key); + const HomeScreen({super.key}); } class Page1Screen extends DummyScreen { - const Page1Screen({Key? key}) : super(key: key); + const Page1Screen({super.key}); } class Page2Screen extends DummyScreen { - const Page2Screen({Key? key}) : super(key: key); + const Page2Screen({super.key}); } class LoginScreen extends DummyScreen { - const LoginScreen({Key? key}) : super(key: key); + const LoginScreen({super.key}); } class FamilyScreen extends DummyScreen { @@ -261,7 +261,7 @@ class PersonScreen extends DummyScreen { } class DummyScreen extends StatelessWidget { - const DummyScreen({Key? key}) : super(key: key); + const DummyScreen({super.key}); @override Widget build(BuildContext context) => const Placeholder(); @@ -374,7 +374,7 @@ class DummyBuildContext implements BuildContext { } class DummyStatefulWidget extends StatefulWidget { - const DummyStatefulWidget({Key? key}) : super(key: key); + const DummyStatefulWidget({super.key}); @override State createState() => DummyStatefulWidgetState(); From 2c56459b20a4597832c708c36990305ee7db11a3 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Thu, 4 Aug 2022 20:31:14 -0300 Subject: [PATCH 21/36] Pop updated to T --- packages/go_router/lib/src/router.dart | 2 +- packages/go_router/test/test_helpers.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/go_router/lib/src/router.dart b/packages/go_router/lib/src/router.dart index c8cf736ec5e..9fc24858386 100644 --- a/packages/go_router/lib/src/router.dart +++ b/packages/go_router/lib/src/router.dart @@ -236,7 +236,7 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { bool canPop() => _routerDelegate.canPop(); /// Pop the top page off the GoRouter's page stack. - void pop([dynamic result]) { + void pop([T? result]) { assert(() { log.info('popping $location'); return true; diff --git a/packages/go_router/test/test_helpers.dart b/packages/go_router/test/test_helpers.dart index 5eb19e84b42..39c7c20ef52 100644 --- a/packages/go_router/test/test_helpers.dart +++ b/packages/go_router/test/test_helpers.dart @@ -177,7 +177,7 @@ class GoRouterPopSpy extends GoRouter { bool popped = false; @override - void pop([dynamic value]) { + void pop([T? value]) { popped = true; } } From 5b94f01ec9b01d3e753aa29e0d1ca3acbcda277f Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Thu, 4 Aug 2022 21:38:48 -0300 Subject: [PATCH 22/36] Updated pop in extensions :) --- packages/go_router/lib/src/misc/extensions.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/go_router/lib/src/misc/extensions.dart b/packages/go_router/lib/src/misc/extensions.dart index 84b8636907c..db010d94029 100644 --- a/packages/go_router/lib/src/misc/extensions.dart +++ b/packages/go_router/lib/src/misc/extensions.dart @@ -77,7 +77,7 @@ extension GoRouterHelper on BuildContext { /// Pop the top page off the Navigator's page stack by calling /// [Navigator.pop]. - void pop([dynamic value]) => GoRouter.of(this).pop(value); + void pop([T? value]) => GoRouter.of(this).pop(value); /// Replaces the top-most page of the page stack with the given URL location /// w/ optional query parameters, e.g. `/family/f2/person/p1?color=blue`. From dd059596dfe82d28b21d8b2048f4ac75bf854cf8 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Thu, 4 Aug 2022 21:47:05 -0300 Subject: [PATCH 23/36] Update readme --- packages/go_router/CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index 247212a818c..a1ec627c8ec 100644 --- a/packages/go_router/CHANGELOG.md +++ b/packages/go_router/CHANGELOG.md @@ -1,7 +1,7 @@ ## 4.3.0 -- Adds `pushAsync` and `pushNamedAsync` to `GoRouterHelper` making it posible to await results from a `pop`. -- Adds an optional parameter to the `pop` method, allowing to return values from a `pop. +- Adds `pushAsync` and `pushNamedAsync` to `go_router` making it posible to await results from a `pop`. +- Adds an optional parameter to the `pop` method, allowing to return values from a `pop`. ## 4.2.7 From 5e27ae35ca339728ff1488de7e14c745b302c419 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Thu, 4 Aug 2022 22:17:01 -0300 Subject: [PATCH 24/36] Updated comments and also added documentation for this in the readme --- packages/go_router/README.md | 14 ++++++++++++++ packages/go_router/lib/src/delegate.dart | 14 +++++++++++--- packages/go_router/lib/src/misc/extensions.dart | 4 ++-- packages/go_router/lib/src/router.dart | 10 ++++------ 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/packages/go_router/README.md b/packages/go_router/README.md index edd832b3aa8..f130aa12fc3 100644 --- a/packages/go_router/README.md +++ b/packages/go_router/README.md @@ -134,6 +134,20 @@ methods: onTap: () => context.go('/page2') ``` + +To wait for values when the screen pops, you can use the `pushAsync` or `pushNamedAsync` methods: + +```dart +onTap: () { + // In the new page you can do 'context.pop(someValue)' to return a value. + final result = await context.pushAsync('/page2'); + + WidgetsBinding.instance.addPostFrameCallback((_) { + if(result ?? false)... + }); +} +``` + ### Still not sure how to proceed? See [examples](https://github.com/flutter/packages/tree/main/packages/go_router/example) for complete runnable examples or visit [API documentation](https://pub.dev/documentation/go_router/latest/go_router/go_router-library.html) diff --git a/packages/go_router/lib/src/delegate.dart b/packages/go_router/lib/src/delegate.dart index 84359e12822..448614fb69f 100644 --- a/packages/go_router/lib/src/delegate.dart +++ b/packages/go_router/lib/src/delegate.dart @@ -72,12 +72,15 @@ class GoRouterDelegate extends RouterDelegate notifyListeners(); } - /// Pushes the given location onto the page stack + /// Pushes the given location asynchronously onto the page stack with a promise. Future pushAsync(RouteMatch match) { - // Remap the pageKey to allow any number of the same page on the stack + // Remap the pageKey to allow any number of the same page on the stack. final String fullPath = match.fullpath; + + // Create a completer for the promise and store it in the completers map. final Completer completer = Completer(); _completers[fullPath] = completer; + final int count = (_pushCounts[fullPath] ?? 0) + 1; _pushCounts[fullPath] = count; final ValueKey pageKey = ValueKey('$fullPath-p$count'); @@ -102,13 +105,18 @@ class GoRouterDelegate extends RouterDelegate return _matches.canPop(); } - /// Pop the top page off the GoRouter's page stack. + /// Pop the top page off the GoRouter's page stack and complete a promise if + /// there is one. void pop([T? value]) { final RouteMatch last = _matches.last; + + // If there is a promise for this page, complete it. final Completer? completer = _completers[last.fullpath] as Completer?; if (completer != null) { completer.complete(value); } + + // Remove promise from completers map. _completers.remove(last.fullpath); _matches.pop(); notifyListeners(); diff --git a/packages/go_router/lib/src/misc/extensions.dart b/packages/go_router/lib/src/misc/extensions.dart index db010d94029..8810f20f595 100644 --- a/packages/go_router/lib/src/misc/extensions.dart +++ b/packages/go_router/lib/src/misc/extensions.dart @@ -40,7 +40,7 @@ extension GoRouterHelper on BuildContext { void push(String location, {Object? extra}) => GoRouter.of(this).push(location, extra: extra); - /// Push a location onto the page stack. + /// Push a location asynchronously onto the page stack with a promise. Future pushAsync(String location, {Object? extra}) => GoRouter.of(this).pushAsync(location, extra: extra); @@ -58,7 +58,7 @@ extension GoRouterHelper on BuildContext { extra: extra, ); - /// Navigate to a named route onto the page stack. + /// Navigate to a named route asynchronously onto the page stack with a promise. Future pushNamedAsync( String name, { Map params = const {}, diff --git a/packages/go_router/lib/src/router.dart b/packages/go_router/lib/src/router.dart index 9fc24858386..8a4fff7d751 100644 --- a/packages/go_router/lib/src/router.dart +++ b/packages/go_router/lib/src/router.dart @@ -190,9 +190,8 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { }); } - /// Push a URI location onto the page stack w/ optional query parameters and - /// a promise, e.g. - /// `/family/f2/person/p1?color=blue` + /// Push a URI location asynchronously onto the page stack w/ optional query + /// parameters and a promise. Future pushAsync(String location, {Object? extra}) async { assert(() { @@ -218,9 +217,8 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { extra: extra, ); - /// Push a named route onto the page stack w/ optional parameters and a - /// promise, e.g. - /// `name='person', params={'fid': 'f2', 'pid': 'p1'}` + /// Push a named route asynchronously onto the page stack w/ optional + /// parameters and a promise. Future pushNamedAsync( String name, { Map params = const {}, From 0488a2e5ae4b3ed723a8342b05014c412815e0a1 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Fri, 5 Aug 2022 12:02:47 -0300 Subject: [PATCH 25/36] Changed sync methods to the async ones After some tests replacing push to pushAsync, it seems that you can safely use pushAsync to make normal pushes with no problem, like in navigator 1.0, so I changed the methods and made test for each case, when you wait for a promise and when you just wanna push a route --- packages/go_router/CHANGELOG.md | 2 +- packages/go_router/README.md | 4 +- packages/go_router/lib/src/delegate.dart | 26 +---------- .../go_router/lib/src/misc/extensions.dart | 28 +++--------- packages/go_router/lib/src/router.dart | 43 +++---------------- packages/go_router/test/go_router_test.dart | 14 +++--- packages/go_router/test/inherited_test.dart | 3 +- packages/go_router/test/test_helpers.dart | 10 +++-- 8 files changed, 32 insertions(+), 98 deletions(-) diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index a1ec627c8ec..34b989418f8 100644 --- a/packages/go_router/CHANGELOG.md +++ b/packages/go_router/CHANGELOG.md @@ -1,6 +1,6 @@ ## 4.3.0 -- Adds `pushAsync` and `pushNamedAsync` to `go_router` making it posible to await results from a `pop`. +- Adds a promise option to `push` and `pushNamed` making it posible to await results from a `pop`. - Adds an optional parameter to the `pop` method, allowing to return values from a `pop`. ## 4.2.7 diff --git a/packages/go_router/README.md b/packages/go_router/README.md index f130aa12fc3..ea90f9f7630 100644 --- a/packages/go_router/README.md +++ b/packages/go_router/README.md @@ -135,12 +135,12 @@ onTap: () => context.go('/page2') ``` -To wait for values when the screen pops, you can use the `pushAsync` or `pushNamedAsync` methods: +To wait for values when the screen pops: ```dart onTap: () { // In the new page you can do 'context.pop(someValue)' to return a value. - final result = await context.pushAsync('/page2'); + final bool? result = await context.push('/page2'); WidgetsBinding.instance.addPostFrameCallback((_) { if(result ?? false)... diff --git a/packages/go_router/lib/src/delegate.dart b/packages/go_router/lib/src/delegate.dart index 448614fb69f..25efe140062 100644 --- a/packages/go_router/lib/src/delegate.dart +++ b/packages/go_router/lib/src/delegate.dart @@ -50,30 +50,8 @@ class GoRouterDelegate extends RouterDelegate RouteMatchList _matches = RouteMatchList.empty(); final Map _pushCounts = {}; - /// Pushes the given location onto the page stack - void push(RouteMatch match) { - // Remap the pageKey to allow any number of the same page on the stack - final String fullPath = match.fullpath; - final int count = (_pushCounts[fullPath] ?? 0) + 1; - _pushCounts[fullPath] = count; - final ValueKey pageKey = ValueKey('$fullPath-p$count'); - final RouteMatch newPageKeyMatch = RouteMatch( - route: match.route, - subloc: match.subloc, - fullpath: match.fullpath, - encodedParams: match.encodedParams, - queryParams: match.queryParams, - extra: match.extra, - error: match.error, - pageKey: pageKey, - ); - - _matches.push(newPageKeyMatch); - notifyListeners(); - } - - /// Pushes the given location asynchronously onto the page stack with a promise. - Future pushAsync(RouteMatch match) { + /// Pushes the given location onto the page stack with an optional promise. + Future push(RouteMatch match) { // Remap the pageKey to allow any number of the same page on the stack. final String fullPath = match.fullpath; diff --git a/packages/go_router/lib/src/misc/extensions.dart b/packages/go_router/lib/src/misc/extensions.dart index 8810f20f595..9549617aaaf 100644 --- a/packages/go_router/lib/src/misc/extensions.dart +++ b/packages/go_router/lib/src/misc/extensions.dart @@ -36,36 +36,18 @@ extension GoRouterHelper on BuildContext { extra: extra, ); - /// Push a location onto the page stack. - void push(String location, {Object? extra}) => + /// Push a location onto the page stack with an optional promise. + Future push(String location, {Object? extra}) => GoRouter.of(this).push(location, extra: extra); - /// Push a location asynchronously onto the page stack with a promise. - Future pushAsync(String location, {Object? extra}) => - GoRouter.of(this).pushAsync(location, extra: extra); - - /// Navigate to a named route onto the page stack. - void pushNamed( - String name, { - Map params = const {}, - Map queryParams = const {}, - Object? extra, - }) => - GoRouter.of(this).pushNamed( - name, - params: params, - queryParams: queryParams, - extra: extra, - ); - - /// Navigate to a named route asynchronously onto the page stack with a promise. - Future pushNamedAsync( + /// Navigate to a named route onto the page stack with an optional promise. + Future pushNamed( String name, { Map params = const {}, Map queryParams = const {}, Object? extra, }) => - GoRouter.of(this).pushNamedAsync( + GoRouter.of(this).pushNamed( name, params: params, queryParams: queryParams, diff --git a/packages/go_router/lib/src/router.dart b/packages/go_router/lib/src/router.dart index 8a4fff7d751..a980015c001 100644 --- a/packages/go_router/lib/src/router.dart +++ b/packages/go_router/lib/src/router.dart @@ -175,25 +175,9 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { extra: extra, ); - /// Push a URI location onto the page stack w/ optional query parameters, e.g. - /// `/family/f2/person/p1?color=blue` - void push(String location, {Object? extra}) { - assert(() { - log.info('pushing $location'); - return true; - }()); - _routeInformationParser - .parseRouteInformation( - DebugGoRouteInformation(location: location, state: extra)) - .then((RouteMatchList matches) { - _routerDelegate.push(matches.last); - }); - } - - /// Push a URI location asynchronously onto the page stack w/ optional query - /// parameters and a promise. - Future pushAsync(String location, - {Object? extra}) async { + /// Push a URI location onto the page stack w/ optional query parameters + /// and promise, e.g. `/family/f2/person/p1?color=blue`. + Future push(String location, {Object? extra}) async { assert(() { log.info('pushing $location'); return true; @@ -201,31 +185,18 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { final RouteMatchList matches = await _routeInformationParser.parseRouteInformation( DebugGoRouteInformation(location: location, state: extra)); - return _routerDelegate.pushAsync(matches.last); + return _routerDelegate.push(matches.last); } - /// Push a named route onto the page stack w/ optional parameters, e.g. - /// `name='person', params={'fid': 'f2', 'pid': 'p1'}` - void pushNamed( - String name, { - Map params = const {}, - Map queryParams = const {}, - Object? extra, - }) => - push( - namedLocation(name, params: params, queryParams: queryParams), - extra: extra, - ); - /// Push a named route asynchronously onto the page stack w/ optional - /// parameters and a promise. - Future pushNamedAsync( + /// parameters and promise. + Future pushNamed( String name, { Map params = const {}, Map queryParams = const {}, Object? extra, }) => - pushAsync( + push( namedLocation(name, params: params, queryParams: queryParams), extra: extra, ); diff --git a/packages/go_router/test/go_router_test.dart b/packages/go_router/test/go_router_test.dart index 3b4dd086afe..e389fcb740d 100644 --- a/packages/go_router/test/go_router_test.dart +++ b/packages/go_router/test/go_router_test.dart @@ -1738,7 +1738,7 @@ void main() { title: 'GoRouter Example', ), ); - key.currentContext?.push( + await key.currentContext?.push( location, extra: extra, ); @@ -1746,7 +1746,7 @@ void main() { expect(router.extra, extra); }); - testWidgets('calls [pushAsync] on closest GoRouter', + testWidgets('calls [push] on closest GoRouter with a promise', (WidgetTester tester) async { final GoRouterPushAsyncSpy router = GoRouterPushAsyncSpy(routes: routes); await tester.pumpWidget( @@ -1757,7 +1757,7 @@ void main() { title: 'GoRouter Example', ), ); - final String? result = await key.currentContext?.pushAsync( + final String? result = await key.currentContext?.push( location, extra: extra, ); @@ -1777,19 +1777,19 @@ void main() { title: 'GoRouter Example', ), ); - key.currentContext?.pushNamed( + await key.currentContext?.pushNamed( name, params: params, queryParams: queryParams, extra: extra, ); + expect(router.extra, extra); expect(router.name, name); expect(router.params, params); expect(router.queryParams, queryParams); - expect(router.extra, extra); }); - testWidgets('calls [pushNamedAsync] on closest GoRouter', + testWidgets('calls [pushNamed] on closest GoRouter with a promise', (WidgetTester tester) async { final GoRouterPushNamedAsyncSpy router = GoRouterPushNamedAsyncSpy(routes: routes); @@ -1801,7 +1801,7 @@ void main() { title: 'GoRouter Example', ), ); - final String? result = await key.currentContext?.pushNamedAsync( + final String? result = await key.currentContext?.pushNamed( name, params: params, queryParams: queryParams, diff --git a/packages/go_router/test/inherited_test.dart b/packages/go_router/test/inherited_test.dart index 216b93cfe32..a6ac293519c 100644 --- a/packages/go_router/test/inherited_test.dart +++ b/packages/go_router/test/inherited_test.dart @@ -129,10 +129,11 @@ class MockGoRouter extends GoRouter { late String latestPushedName; @override - void pushNamed(String name, + Future pushNamed(String name, {Map params = const {}, Map queryParams = const {}, Object? extra}) { latestPushedName = name; + return Future.value(); } } diff --git a/packages/go_router/test/test_helpers.dart b/packages/go_router/test/test_helpers.dart index 39c7c20ef52..6249f45e472 100644 --- a/packages/go_router/test/test_helpers.dart +++ b/packages/go_router/test/test_helpers.dart @@ -105,9 +105,10 @@ class GoRouterPushSpy extends GoRouter { Object? extra; @override - void push(String location, {Object? extra}) { + Future push(String location, {Object? extra}) { myLocation = location; this.extra = extra; + return Future.value(); } } @@ -118,7 +119,7 @@ class GoRouterPushAsyncSpy extends GoRouter { Object? extra; @override - Future pushAsync(String location, {Object? extra}) { + Future push(String location, {Object? extra}) { myLocation = location; this.extra = extra; return Future.value(extra as T); @@ -134,7 +135,7 @@ class GoRouterPushNamedSpy extends GoRouter { Object? extra; @override - void pushNamed( + Future pushNamed( String name, { Map params = const {}, Map queryParams = const {}, @@ -144,6 +145,7 @@ class GoRouterPushNamedSpy extends GoRouter { this.params = params; this.queryParams = queryParams; this.extra = extra; + return Future.value(); } } @@ -157,7 +159,7 @@ class GoRouterPushNamedAsyncSpy extends GoRouter { Object? extra; @override - Future pushNamedAsync( + Future pushNamed( String name, { Map params = const {}, Map queryParams = const {}, From b7431c8939848706bc578411699f428fb5a0b189 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Mon, 8 Aug 2022 10:49:56 -0300 Subject: [PATCH 26/36] Update Replace --- packages/go_router/lib/src/delegate.dart | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/go_router/lib/src/delegate.dart b/packages/go_router/lib/src/delegate.dart index 25efe140062..32fdfe2595d 100644 --- a/packages/go_router/lib/src/delegate.dart +++ b/packages/go_router/lib/src/delegate.dart @@ -105,7 +105,17 @@ class GoRouterDelegate extends RouterDelegate /// See also: /// * [push] which pushes the given location onto the page stack. void replace(RouteMatch match) { + final String lastPath = _matches.last.fullpath; + final Completer? completer = _completers[lastPath]; + + // If there's a promise for the last page, we update it to make it point to + // the new page. + if (completer != null) { + _completers[match.fullpath] = completer; + _completers.remove(lastPath); + } _matches.matches.last = match; + notifyListeners(); } From 3fb8ccd35aeb26155f20416200faaad19b8c832b Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Mon, 8 Aug 2022 11:31:27 -0300 Subject: [PATCH 27/36] Update on how we handle replace --- packages/go_router/lib/src/delegate.dart | 25 ++++++++++--------- .../go_router/lib/src/misc/extensions.dart | 4 +-- packages/go_router/lib/src/router.dart | 13 +++++----- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/packages/go_router/lib/src/delegate.dart b/packages/go_router/lib/src/delegate.dart index 32fdfe2595d..c4e40499e5e 100644 --- a/packages/go_router/lib/src/delegate.dart +++ b/packages/go_router/lib/src/delegate.dart @@ -56,7 +56,7 @@ class GoRouterDelegate extends RouterDelegate final String fullPath = match.fullpath; // Create a completer for the promise and store it in the completers map. - final Completer completer = Completer(); + final Completer completer = Completer(); _completers[fullPath] = completer; final int count = (_pushCounts[fullPath] ?? 0) + 1; @@ -89,7 +89,8 @@ class GoRouterDelegate extends RouterDelegate final RouteMatch last = _matches.last; // If there is a promise for this page, complete it. - final Completer? completer = _completers[last.fullpath] as Completer?; + final Completer? completer = + _completers[last.fullpath] as Completer?; if (completer != null) { completer.complete(value); } @@ -104,19 +105,19 @@ class GoRouterDelegate extends RouterDelegate /// /// See also: /// * [push] which pushes the given location onto the page stack. - void replace(RouteMatch match) { - final String lastPath = _matches.last.fullpath; - final Completer? completer = _completers[lastPath]; + Future replace(RouteMatch match) { + final String lastPath = _matches.matches.last.fullpath; - // If there's a promise for the last page, we update it to make it point to - // the new page. - if (completer != null) { - _completers[match.fullpath] = completer; - _completers.remove(lastPath); - } - _matches.matches.last = match; + // Create a completer for the promise and store it in the completers map. + final Completer completer = Completer(); + _completers[match.fullpath] = completer; + // Remove the old promise from the completers map. + _completers.remove(lastPath); + + _matches.matches.last = match; notifyListeners(); + return completer.future; } /// For internal use; visible for testing only. diff --git a/packages/go_router/lib/src/misc/extensions.dart b/packages/go_router/lib/src/misc/extensions.dart index 9549617aaaf..f57c057a5a8 100644 --- a/packages/go_router/lib/src/misc/extensions.dart +++ b/packages/go_router/lib/src/misc/extensions.dart @@ -67,8 +67,8 @@ extension GoRouterHelper on BuildContext { /// See also: /// * [go] which navigates to the location. /// * [push] which pushes the location onto the page stack. - void replace(String location, {Object? extra}) => - GoRouter.of(this).replace(location, extra: extra); + Future replace(String location, {Object? extra}) => + GoRouter.of(this).replace(location, extra: extra); /// Replaces the top-most page of the page stack with the named route w/ /// optional parameters, e.g. `name='person', params={'fid': 'f2', 'pid': diff --git a/packages/go_router/lib/src/router.dart b/packages/go_router/lib/src/router.dart index a980015c001..91d9596cb68 100644 --- a/packages/go_router/lib/src/router.dart +++ b/packages/go_router/lib/src/router.dart @@ -219,14 +219,13 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { /// See also: /// * [go] which navigates to the location. /// * [push] which pushes the location onto the page stack. - void replace(String location, {Object? extra}) { - routeInformationParser - .parseRouteInformation( + Future replace(String location, + {Object? extra}) async { + final RouteMatchList matchList = + await routeInformationParser.parseRouteInformation( DebugGoRouteInformation(location: location, state: extra), - ) - .then((RouteMatchList matchList) { - routerDelegate.replace(matchList.matches.last); - }); + ); + return routerDelegate.replace(matchList.matches.last); } /// Replaces the top-most page of the page stack with the named route w/ From 0061c32e1964b73b6a6b5a5e209e2a588dbba046 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Mon, 8 Aug 2022 12:02:20 -0300 Subject: [PATCH 28/36] element updated to element2 --- .../lib/src/go_router_generator.dart | 2 +- packages/go_router_builder/lib/src/route_config.dart | 12 ++++++------ packages/go_router_builder/lib/src/type_helpers.dart | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/go_router_builder/lib/src/go_router_generator.dart b/packages/go_router_builder/lib/src/go_router_generator.dart index 42ef4ca343c..3099b4a9e29 100644 --- a/packages/go_router_builder/lib/src/go_router_generator.dart +++ b/packages/go_router_builder/lib/src/go_router_generator.dart @@ -61,7 +61,7 @@ ${getters.map((String e) => "$e,").join('\n')} ConstantReader annotation, BuildStep buildStep, ) { - if (element is! ClassElement) { + if (element is! InterfaceElement) { throw InvalidGenerationSourceError( 'The @TypedGoRoute annotation can only be applied to classes.', element: element, diff --git a/packages/go_router_builder/lib/src/route_config.dart b/packages/go_router_builder/lib/src/route_config.dart index 76aa51579dc..47e1b524112 100644 --- a/packages/go_router_builder/lib/src/route_config.dart +++ b/packages/go_router_builder/lib/src/route_config.dart @@ -44,7 +44,7 @@ class RouteConfig { /// Creates a new [RouteConfig] represented the annotation data in [reader]. factory RouteConfig.fromAnnotation( ConstantReader reader, - ClassElement element, + InterfaceElement element, ) { final RouteConfig definition = RouteConfig._fromAnnotation(reader, element, null); @@ -62,7 +62,7 @@ class RouteConfig { factory RouteConfig._fromAnnotation( ConstantReader reader, - ClassElement element, + InterfaceElement element, RouteConfig? parent, ) { assert(!reader.isNull, 'reader should not be null'); @@ -88,7 +88,7 @@ class RouteConfig { } // TODO(kevmoo): validate that this MUST be a subtype of `GoRouteData` - final ClassElement classElement = typeParamType.element; + final InterfaceElement classElement = typeParamType.element2; final RouteConfig value = RouteConfig._(path, classElement, parent); @@ -100,7 +100,7 @@ class RouteConfig { final List _children = []; final String _path; - final ClassElement _routeDataClass; + final InterfaceElement _routeDataClass; final RouteConfig? _parent; /// Generates all of the members that correspond to `this`. @@ -363,11 +363,11 @@ GoRouteData.\$route( String _enumMapConst(InterfaceType type) { assert(type.isEnum); - final String enumName = type.element.name; + final String enumName = type.element2.name; final StringBuffer buffer = StringBuffer('const ${enumMapName(type)} = {'); - for (final FieldElement enumField in type.element.fields + for (final FieldElement enumField in type.element2.fields .where((FieldElement element) => !element.isSynthetic)) { buffer.writeln( '$enumName.${enumField.name}: ${escapeDartString(enumField.name.kebab)},', diff --git a/packages/go_router_builder/lib/src/type_helpers.dart b/packages/go_router_builder/lib/src/type_helpers.dart index 35568e78f50..8df633d5bb1 100644 --- a/packages/go_router_builder/lib/src/type_helpers.dart +++ b/packages/go_router_builder/lib/src/type_helpers.dart @@ -79,7 +79,7 @@ String encodeField(PropertyAccessorElement element) { } /// Gets the name of the `const` map generated to help encode [Enum] types. -String enumMapName(InterfaceType type) => '_\$${type.element.name}EnumMap'; +String enumMapName(InterfaceType type) => '_\$${type.element2.name}EnumMap'; String _stateValueAccess(ParameterElement element) { if (element.isRequired) { From 5fffdf30e86d71f76025542eade78b3e263a520d Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Mon, 8 Aug 2022 13:20:19 -0300 Subject: [PATCH 29/36] go_router_builder version updated --- packages/go_router_builder/CHANGELOG.md | 4 ++++ packages/go_router_builder/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/go_router_builder/CHANGELOG.md b/packages/go_router_builder/CHANGELOG.md index f953fc04641..9f3dfc056c2 100644 --- a/packages/go_router_builder/CHANGELOG.md +++ b/packages/go_router_builder/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.8 + +* Updated to element2 + ## 1.0.7 * Supports newer versions of `analyzer`. diff --git a/packages/go_router_builder/pubspec.yaml b/packages/go_router_builder/pubspec.yaml index 70d8a4303ef..976abd63aef 100644 --- a/packages/go_router_builder/pubspec.yaml +++ b/packages/go_router_builder/pubspec.yaml @@ -2,7 +2,7 @@ name: go_router_builder description: >- A builder that supports generated strongly-typed route helpers for package:go_router -version: 1.0.7 +version: 1.0.8 repository: https://github.com/flutter/packages/tree/main/packages/go_router_builder issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router_builder%22 From 12eef5e55425ba2b8aebd0754e643a330a00b9cc Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Thu, 11 Aug 2022 21:41:25 -0300 Subject: [PATCH 30/36] go and go named async --- packages/go_router/lib/src/delegate.dart | 12 +++---- .../go_router/lib/src/misc/extensions.dart | 12 +++---- packages/go_router/lib/src/router.dart | 33 +++++++++++-------- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/packages/go_router/lib/src/delegate.dart b/packages/go_router/lib/src/delegate.dart index c4e40499e5e..5addda4905d 100644 --- a/packages/go_router/lib/src/delegate.dart +++ b/packages/go_router/lib/src/delegate.dart @@ -45,7 +45,7 @@ class GoRouterDelegate extends RouterDelegate final GlobalKey _key = GlobalKey(); /// The list of completers for the promises when pushing asynchronous routes. - final Map> _completers = + final Map> completers = >{}; RouteMatchList _matches = RouteMatchList.empty(); final Map _pushCounts = {}; @@ -57,7 +57,7 @@ class GoRouterDelegate extends RouterDelegate // Create a completer for the promise and store it in the completers map. final Completer completer = Completer(); - _completers[fullPath] = completer; + completers[fullPath] = completer; final int count = (_pushCounts[fullPath] ?? 0) + 1; _pushCounts[fullPath] = count; @@ -90,13 +90,13 @@ class GoRouterDelegate extends RouterDelegate // If there is a promise for this page, complete it. final Completer? completer = - _completers[last.fullpath] as Completer?; + completers[last.fullpath] as Completer?; if (completer != null) { completer.complete(value); } // Remove promise from completers map. - _completers.remove(last.fullpath); + completers.remove(last.fullpath); _matches.pop(); notifyListeners(); } @@ -110,10 +110,10 @@ class GoRouterDelegate extends RouterDelegate // Create a completer for the promise and store it in the completers map. final Completer completer = Completer(); - _completers[match.fullpath] = completer; + completers[match.fullpath] = completer; // Remove the old promise from the completers map. - _completers.remove(lastPath); + completers.remove(lastPath); _matches.matches.last = match; notifyListeners(); diff --git a/packages/go_router/lib/src/misc/extensions.dart b/packages/go_router/lib/src/misc/extensions.dart index f57c057a5a8..9536107f36d 100644 --- a/packages/go_router/lib/src/misc/extensions.dart +++ b/packages/go_router/lib/src/misc/extensions.dart @@ -19,16 +19,16 @@ extension GoRouterHelper on BuildContext { .namedLocation(name, params: params, queryParams: queryParams); /// Navigate to a location. - void go(String location, {Object? extra}) => - GoRouter.of(this).go(location, extra: extra); + Future go(String location, {Object? extra}) async => + GoRouter.of(this).go(location, extra: extra); /// Navigate to a named route. - void goNamed( + Future goNamed( String name, { Map params = const {}, Map queryParams = const {}, Object? extra, - }) => + }) async => GoRouter.of(this).goNamed( name, params: params, @@ -77,13 +77,13 @@ extension GoRouterHelper on BuildContext { /// See also: /// * [goNamed] which navigates a named route. /// * [pushNamed] which pushes a named route onto the page stack. - void replaceNamed( + Future replaceNamed( String name, { Map params = const {}, Map queryParams = const {}, Object? extra, }) => - GoRouter.of(this).replaceNamed( + GoRouter.of(this).replaceNamed( name, params: params, queryParams: queryParams, diff --git a/packages/go_router/lib/src/router.dart b/packages/go_router/lib/src/router.dart index 91d9596cb68..ebeb2be5ce5 100644 --- a/packages/go_router/lib/src/router.dart +++ b/packages/go_router/lib/src/router.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:async'; + import 'package:flutter/widgets.dart'; import 'configuration.dart'; @@ -152,25 +154,29 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { /// Navigate to a URI location w/ optional query parameters, e.g. /// `/family/f2/person/p1?color=blue` - void go(String location, {Object? extra}) { + Future go(String location, {Object? extra}) async { assert(() { log.info('going to $location'); return true; }()); _routeInformationProvider.value = RouteInformation(location: location, state: extra); + // Create a completer for the promise and store it in the completers map. + final Completer completer = Completer(); + _routerDelegate.completers[location] = completer; + return completer.future; } /// Navigate to a named route w/ optional parameters, e.g. /// `name='person', params={'fid': 'f2', 'pid': 'p1'}` /// Navigate to the named route. - void goNamed( + Future goNamed( String name, { Map params = const {}, Map queryParams = const {}, Object? extra, - }) => - go( + }) async => + go( namedLocation(name, params: params, queryParams: queryParams), extra: extra, ); @@ -185,7 +191,7 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { final RouteMatchList matches = await _routeInformationParser.parseRouteInformation( DebugGoRouteInformation(location: location, state: extra)); - return _routerDelegate.push(matches.last); + return _routerDelegate.push(matches.last); } /// Push a named route asynchronously onto the page stack w/ optional @@ -196,7 +202,7 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { Map queryParams = const {}, Object? extra, }) => - push( + push( namedLocation(name, params: params, queryParams: queryParams), extra: extra, ); @@ -225,7 +231,7 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { await routeInformationParser.parseRouteInformation( DebugGoRouteInformation(location: location, state: extra), ); - return routerDelegate.replace(matchList.matches.last); + return routerDelegate.replace(matchList.matches.last); } /// Replaces the top-most page of the page stack with the named route w/ @@ -235,17 +241,16 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { /// See also: /// * [goNamed] which navigates a named route. /// * [pushNamed] which pushes a named route onto the page stack. - void replaceNamed( + Future replaceNamed( String name, { Map params = const {}, Map queryParams = const {}, Object? extra, - }) { - replace( - namedLocation(name, params: params, queryParams: queryParams), - extra: extra, - ); - } + }) => + replace( + namedLocation(name, params: params, queryParams: queryParams), + extra: extra, + ); /// Refresh the route. void refresh() { From 30449efe0be25865c907281b4d8860deed21a113 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Thu, 11 Aug 2022 21:49:28 -0300 Subject: [PATCH 31/36] Test updated for go and goNamed --- packages/go_router/test/go_router_test.dart | 45 ++++++++++++++++++ packages/go_router/test/test_helpers.dart | 52 ++++++++++++++++++--- 2 files changed, 91 insertions(+), 6 deletions(-) diff --git a/packages/go_router/test/go_router_test.dart b/packages/go_router/test/go_router_test.dart index e389fcb740d..2b1b6af0fff 100644 --- a/packages/go_router/test/go_router_test.dart +++ b/packages/go_router/test/go_router_test.dart @@ -1704,6 +1704,26 @@ void main() { expect(router.extra, extra); }); + testWidgets('calls [go] on closest GoRouter with a promise', + (WidgetTester tester) async { + final GoRouterGoAsyncSpy router = GoRouterGoAsyncSpy(routes: routes); + await tester.pumpWidget( + MaterialApp.router( + routeInformationProvider: router.routeInformationProvider, + routeInformationParser: router.routeInformationParser, + routerDelegate: router.routerDelegate, + title: 'GoRouter Example', + ), + ); + final String? result = await key.currentContext?.go( + location, + extra: extra, + ); + expect(result, extra); + expect(router.myLocation, location); + expect(router.extra, extra); + }); + testWidgets('calls [goNamed] on closest GoRouter', (WidgetTester tester) async { final GoRouterGoNamedSpy router = GoRouterGoNamedSpy(routes: routes); @@ -1727,6 +1747,31 @@ void main() { expect(router.extra, extra); }); + testWidgets('calls [goNamed] on closest GoRouter with a promise', + (WidgetTester tester) async { + final GoRouterGoNamedAsyncSpy router = + GoRouterGoNamedAsyncSpy(routes: routes); + await tester.pumpWidget( + MaterialApp.router( + routeInformationProvider: router.routeInformationProvider, + routeInformationParser: router.routeInformationParser, + routerDelegate: router.routerDelegate, + title: 'GoRouter Example', + ), + ); + final String? result = await key.currentContext?.goNamed( + name, + params: params, + queryParams: queryParams, + extra: extra, + ); + expect(result, extra); + expect(router.name, name); + expect(router.params, params); + expect(router.queryParams, queryParams); + expect(router.extra, extra); + }); + testWidgets('calls [push] on closest GoRouter', (WidgetTester tester) async { final GoRouterPushSpy router = GoRouterPushSpy(routes: routes); diff --git a/packages/go_router/test/test_helpers.dart b/packages/go_router/test/test_helpers.dart index 6249f45e472..e6edf0cf8bd 100644 --- a/packages/go_router/test/test_helpers.dart +++ b/packages/go_router/test/test_helpers.dart @@ -70,9 +70,24 @@ class GoRouterGoSpy extends GoRouter { Object? extra; @override - void go(String location, {Object? extra}) { + Future go(String location, {Object? extra}) { myLocation = location; this.extra = extra; + return Future.value(); + } +} + +class GoRouterGoAsyncSpy extends GoRouter { + GoRouterGoAsyncSpy({required List routes}) : super(routes: routes); + + String? myLocation; + Object? extra; + + @override + Future go(String location, {Object? extra}) { + myLocation = location; + this.extra = extra; + return Future.value(extra as T?); } } @@ -85,7 +100,31 @@ class GoRouterGoNamedSpy extends GoRouter { Object? extra; @override - void goNamed( + Future goNamed( + String name, { + Map params = const {}, + Map queryParams = const {}, + Object? extra, + }) { + this.name = name; + this.params = params; + this.queryParams = queryParams; + this.extra = extra; + return Future.value(); + } +} + +class GoRouterGoNamedAsyncSpy extends GoRouter { + GoRouterGoNamedAsyncSpy({required List routes}) + : super(routes: routes); + + String? name; + Map? params; + Map? queryParams; + Object? extra; + + @override + Future goNamed( String name, { Map params = const {}, Map queryParams = const {}, @@ -95,6 +134,7 @@ class GoRouterGoNamedSpy extends GoRouter { this.params = params; this.queryParams = queryParams; this.extra = extra; + return Future.value(extra as T?); } } @@ -108,7 +148,7 @@ class GoRouterPushSpy extends GoRouter { Future push(String location, {Object? extra}) { myLocation = location; this.extra = extra; - return Future.value(); + return Future.value(); } } @@ -122,7 +162,7 @@ class GoRouterPushAsyncSpy extends GoRouter { Future push(String location, {Object? extra}) { myLocation = location; this.extra = extra; - return Future.value(extra as T); + return Future.value(extra as T?); } } @@ -159,7 +199,7 @@ class GoRouterPushNamedAsyncSpy extends GoRouter { Object? extra; @override - Future pushNamed( + Future pushNamed( String name, { Map params = const {}, Map queryParams = const {}, @@ -169,7 +209,7 @@ class GoRouterPushNamedAsyncSpy extends GoRouter { this.params = params; this.queryParams = queryParams; this.extra = extra; - return Future.value(extra as T); + return Future.value(extra as T?); } } From a1397dca71ecf4f26aecfcdb1dcb0a6a8ce8c362 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Tue, 16 Aug 2022 15:43:30 -0300 Subject: [PATCH 32/36] Completers saved in RouteMatchs rather than in a completer list in the delegate --- packages/go_router/CHANGELOG.md | 5 +- packages/go_router/lib/src/delegate.dart | 25 ++---- packages/go_router/lib/src/match.dart | 8 ++ packages/go_router/lib/src/matching.dart | 3 + .../go_router/lib/src/misc/extensions.dart | 8 +- packages/go_router/lib/src/parser.dart | 3 + packages/go_router/lib/src/router.dart | 15 ++-- packages/go_router/test/go_router_test.dart | 20 ++--- packages/go_router/test/test_helpers.dart | 82 +------------------ 9 files changed, 42 insertions(+), 127 deletions(-) diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index 471351f7a2d..34b989418f8 100644 --- a/packages/go_router/CHANGELOG.md +++ b/packages/go_router/CHANGELOG.md @@ -1,6 +1,7 @@ -## NEXT +## 4.3.0 -- Cleans up examples +- Adds a promise option to `push` and `pushNamed` making it posible to await results from a `pop`. +- Adds an optional parameter to the `pop` method, allowing to return values from a `pop`. ## 4.2.7 diff --git a/packages/go_router/lib/src/delegate.dart b/packages/go_router/lib/src/delegate.dart index 5addda4905d..d95d21444c3 100644 --- a/packages/go_router/lib/src/delegate.dart +++ b/packages/go_router/lib/src/delegate.dart @@ -44,9 +44,6 @@ class GoRouterDelegate extends RouterDelegate final GlobalKey _key = GlobalKey(); - /// The list of completers for the promises when pushing asynchronous routes. - final Map> completers = - >{}; RouteMatchList _matches = RouteMatchList.empty(); final Map _pushCounts = {}; @@ -57,12 +54,12 @@ class GoRouterDelegate extends RouterDelegate // Create a completer for the promise and store it in the completers map. final Completer completer = Completer(); - completers[fullPath] = completer; final int count = (_pushCounts[fullPath] ?? 0) + 1; _pushCounts[fullPath] = count; final ValueKey pageKey = ValueKey('$fullPath-p$count'); final RouteMatch newPageKeyMatch = RouteMatch( + completer: completer, route: match.route, subloc: match.subloc, fullpath: match.fullpath, @@ -89,14 +86,10 @@ class GoRouterDelegate extends RouterDelegate final RouteMatch last = _matches.last; // If there is a promise for this page, complete it. - final Completer? completer = - completers[last.fullpath] as Completer?; - if (completer != null) { - completer.complete(value); + if (last.completer != null) { + last.completer.complete(value); } - // Remove promise from completers map. - completers.remove(last.fullpath); _matches.pop(); notifyListeners(); } @@ -106,18 +99,10 @@ class GoRouterDelegate extends RouterDelegate /// See also: /// * [push] which pushes the given location onto the page stack. Future replace(RouteMatch match) { - final String lastPath = _matches.matches.last.fullpath; - - // Create a completer for the promise and store it in the completers map. - final Completer completer = Completer(); - completers[match.fullpath] = completer; - - // Remove the old promise from the completers map. - completers.remove(lastPath); - _matches.matches.last = match; + notifyListeners(); - return completer.future; + return match.completer.future as Future; } /// For internal use; visible for testing only. diff --git a/packages/go_router/lib/src/match.dart b/packages/go_router/lib/src/match.dart index d7f096e8a1b..2acdf986f47 100644 --- a/packages/go_router/lib/src/match.dart +++ b/packages/go_router/lib/src/match.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:async'; + import 'package:flutter/foundation.dart'; import 'path_utils.dart'; @@ -18,6 +20,7 @@ class RouteMatch { required this.fullpath, required this.encodedParams, required this.queryParams, + required this.completer, required this.extra, required this.error, this.pageKey, @@ -41,6 +44,7 @@ class RouteMatch { required String parentSubloc, // e.g. /family/f2 required String fullpath, // e.g. /family/:fid/person/:pid required Map queryParams, + required Completer completer, required Object? extra, }) { assert(!route.path.contains('//')); @@ -59,6 +63,7 @@ class RouteMatch { fullpath: fullpath, encodedParams: encodedParams, queryParams: queryParams, + completer: completer, extra: extra, error: null, ); @@ -79,6 +84,9 @@ class RouteMatch { /// Query parameters for the matched route. final Map queryParams; + /// The completer for the promise when pushing routes. + final Completer completer; + /// An extra object to pass along with the navigation. final Object? extra; diff --git a/packages/go_router/lib/src/matching.dart b/packages/go_router/lib/src/matching.dart index 755aed67078..790a7db68ec 100644 --- a/packages/go_router/lib/src/matching.dart +++ b/packages/go_router/lib/src/matching.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:async'; + import 'configuration.dart'; import 'match.dart'; import 'path_utils.dart'; @@ -140,6 +142,7 @@ List _getLocRouteRecursively({ fullpath: fullpath, queryParams: queryParams, extra: extra, + completer: Completer(), ); if (match == null) { diff --git a/packages/go_router/lib/src/misc/extensions.dart b/packages/go_router/lib/src/misc/extensions.dart index 9536107f36d..af5b173b553 100644 --- a/packages/go_router/lib/src/misc/extensions.dart +++ b/packages/go_router/lib/src/misc/extensions.dart @@ -19,16 +19,16 @@ extension GoRouterHelper on BuildContext { .namedLocation(name, params: params, queryParams: queryParams); /// Navigate to a location. - Future go(String location, {Object? extra}) async => - GoRouter.of(this).go(location, extra: extra); + void go(String location, {Object? extra}) => + GoRouter.of(this).go(location, extra: extra); /// Navigate to a named route. - Future goNamed( + void goNamed( String name, { Map params = const {}, Map queryParams = const {}, Object? extra, - }) async => + }) => GoRouter.of(this).goNamed( name, params: params, diff --git a/packages/go_router/lib/src/parser.dart b/packages/go_router/lib/src/parser.dart index 3f716e44c7b..c691b3f0a30 100644 --- a/packages/go_router/lib/src/parser.dart +++ b/packages/go_router/lib/src/parser.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:async'; + import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; @@ -109,6 +111,7 @@ class GoRouteInformationParser extends RouteInformationParser { final Exception error = Exception(errorMessage); return RouteMatchList([ RouteMatch( + completer: Completer(), subloc: uri.path, fullpath: uri.path, encodedParams: {}, diff --git a/packages/go_router/lib/src/router.dart b/packages/go_router/lib/src/router.dart index ebeb2be5ce5..104e1503244 100644 --- a/packages/go_router/lib/src/router.dart +++ b/packages/go_router/lib/src/router.dart @@ -154,29 +154,25 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { /// Navigate to a URI location w/ optional query parameters, e.g. /// `/family/f2/person/p1?color=blue` - Future go(String location, {Object? extra}) async { + void go(String location, {Object? extra}) { assert(() { log.info('going to $location'); return true; }()); _routeInformationProvider.value = RouteInformation(location: location, state: extra); - // Create a completer for the promise and store it in the completers map. - final Completer completer = Completer(); - _routerDelegate.completers[location] = completer; - return completer.future; } /// Navigate to a named route w/ optional parameters, e.g. /// `name='person', params={'fid': 'f2', 'pid': 'p1'}` /// Navigate to the named route. - Future goNamed( + void goNamed( String name, { Map params = const {}, Map queryParams = const {}, Object? extra, - }) async => - go( + }) => + go( namedLocation(name, params: params, queryParams: queryParams), extra: extra, ); @@ -190,7 +186,8 @@ class GoRouter extends ChangeNotifier with NavigatorObserver { }()); final RouteMatchList matches = await _routeInformationParser.parseRouteInformation( - DebugGoRouteInformation(location: location, state: extra)); + DebugGoRouteInformation(location: location, state: extra), + ); return _routerDelegate.push(matches.last); } diff --git a/packages/go_router/test/go_router_test.dart b/packages/go_router/test/go_router_test.dart index 2b1b6af0fff..0d86f6afa37 100644 --- a/packages/go_router/test/go_router_test.dart +++ b/packages/go_router/test/go_router_test.dart @@ -1704,9 +1704,9 @@ void main() { expect(router.extra, extra); }); - testWidgets('calls [go] on closest GoRouter with a promise', + testWidgets('calls [go] on closest GoRouter with a Future', (WidgetTester tester) async { - final GoRouterGoAsyncSpy router = GoRouterGoAsyncSpy(routes: routes); + final GoRouterGoSpy router = GoRouterGoSpy(routes: routes); await tester.pumpWidget( MaterialApp.router( routeInformationProvider: router.routeInformationProvider, @@ -1715,11 +1715,10 @@ void main() { title: 'GoRouter Example', ), ); - final String? result = await key.currentContext?.go( + key.currentContext?.go( location, extra: extra, ); - expect(result, extra); expect(router.myLocation, location); expect(router.extra, extra); }); @@ -1747,10 +1746,9 @@ void main() { expect(router.extra, extra); }); - testWidgets('calls [goNamed] on closest GoRouter with a promise', + testWidgets('calls [goNamed] on closest GoRouter with a Future', (WidgetTester tester) async { - final GoRouterGoNamedAsyncSpy router = - GoRouterGoNamedAsyncSpy(routes: routes); + final GoRouterGoNamedSpy router = GoRouterGoNamedSpy(routes: routes); await tester.pumpWidget( MaterialApp.router( routeInformationProvider: router.routeInformationProvider, @@ -1759,13 +1757,12 @@ void main() { title: 'GoRouter Example', ), ); - final String? result = await key.currentContext?.goNamed( + key.currentContext?.goNamed( name, params: params, queryParams: queryParams, extra: extra, ); - expect(result, extra); expect(router.name, name); expect(router.params, params); expect(router.queryParams, queryParams); @@ -1793,7 +1790,7 @@ void main() { testWidgets('calls [push] on closest GoRouter with a promise', (WidgetTester tester) async { - final GoRouterPushAsyncSpy router = GoRouterPushAsyncSpy(routes: routes); + final GoRouterPushSpy router = GoRouterPushSpy(routes: routes); await tester.pumpWidget( MaterialApp.router( routeInformationProvider: router.routeInformationProvider, @@ -1836,8 +1833,7 @@ void main() { testWidgets('calls [pushNamed] on closest GoRouter with a promise', (WidgetTester tester) async { - final GoRouterPushNamedAsyncSpy router = - GoRouterPushNamedAsyncSpy(routes: routes); + final GoRouterPushNamedSpy router = GoRouterPushNamedSpy(routes: routes); await tester.pumpWidget( MaterialApp.router( routeInformationProvider: router.routeInformationProvider, diff --git a/packages/go_router/test/test_helpers.dart b/packages/go_router/test/test_helpers.dart index e6edf0cf8bd..16128910060 100644 --- a/packages/go_router/test/test_helpers.dart +++ b/packages/go_router/test/test_helpers.dart @@ -70,24 +70,9 @@ class GoRouterGoSpy extends GoRouter { Object? extra; @override - Future go(String location, {Object? extra}) { + void go(String location, {Object? extra}) { myLocation = location; this.extra = extra; - return Future.value(); - } -} - -class GoRouterGoAsyncSpy extends GoRouter { - GoRouterGoAsyncSpy({required List routes}) : super(routes: routes); - - String? myLocation; - Object? extra; - - @override - Future go(String location, {Object? extra}) { - myLocation = location; - this.extra = extra; - return Future.value(extra as T?); } } @@ -100,31 +85,7 @@ class GoRouterGoNamedSpy extends GoRouter { Object? extra; @override - Future goNamed( - String name, { - Map params = const {}, - Map queryParams = const {}, - Object? extra, - }) { - this.name = name; - this.params = params; - this.queryParams = queryParams; - this.extra = extra; - return Future.value(); - } -} - -class GoRouterGoNamedAsyncSpy extends GoRouter { - GoRouterGoNamedAsyncSpy({required List routes}) - : super(routes: routes); - - String? name; - Map? params; - Map? queryParams; - Object? extra; - - @override - Future goNamed( + void goNamed( String name, { Map params = const {}, Map queryParams = const {}, @@ -134,7 +95,6 @@ class GoRouterGoNamedAsyncSpy extends GoRouter { this.params = params; this.queryParams = queryParams; this.extra = extra; - return Future.value(extra as T?); } } @@ -144,20 +104,6 @@ class GoRouterPushSpy extends GoRouter { String? myLocation; Object? extra; - @override - Future push(String location, {Object? extra}) { - myLocation = location; - this.extra = extra; - return Future.value(); - } -} - -class GoRouterPushAsyncSpy extends GoRouter { - GoRouterPushAsyncSpy({required List routes}) : super(routes: routes); - - String? myLocation; - Object? extra; - @override Future push(String location, {Object? extra}) { myLocation = location; @@ -174,30 +120,6 @@ class GoRouterPushNamedSpy extends GoRouter { Map? queryParams; Object? extra; - @override - Future pushNamed( - String name, { - Map params = const {}, - Map queryParams = const {}, - Object? extra, - }) { - this.name = name; - this.params = params; - this.queryParams = queryParams; - this.extra = extra; - return Future.value(); - } -} - -class GoRouterPushNamedAsyncSpy extends GoRouter { - GoRouterPushNamedAsyncSpy({required List routes}) - : super(routes: routes); - - String? name; - Map? params; - Map? queryParams; - Object? extra; - @override Future pushNamed( String name, { From 5a7418d31f4cbd8dfceb91b9efd63ddc932c4285 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Thu, 18 Aug 2022 18:50:46 -0300 Subject: [PATCH 33/36] Updated PR --- packages/go_router/CHANGELOG.md | 5 +++++ packages/go_router/pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index 69b1b70dab3..6fef80342f1 100644 --- a/packages/go_router/CHANGELOG.md +++ b/packages/go_router/CHANGELOG.md @@ -1,3 +1,8 @@ +## 4.3.0 + +- Adds a Future option to `push` and `pushNamed` making it posible to await results from a `pop`. +- Adds an optional parameter to the `pop` method, allowing to return values from a `pop`. + ## 4.2.8 - Fixes namedLocation to return URIs without trailing question marks if there are no query parameters. diff --git a/packages/go_router/pubspec.yaml b/packages/go_router/pubspec.yaml index 44cda90e94e..5a72446104d 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: 4.2.8 +version: 4.3.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 From 6f9fa084ff3baaa354a025a5cc71e111be3d32fd Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Tue, 27 Sep 2022 20:47:12 -0300 Subject: [PATCH 34/36] Final updates --- packages/go_router/lib/src/delegate.dart | 6 +++--- packages/go_router/lib/src/match.dart | 6 +++--- packages/go_router/test/match_test.dart | 3 +++ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/go_router/lib/src/delegate.dart b/packages/go_router/lib/src/delegate.dart index fd391254570..d4d613cd8fa 100644 --- a/packages/go_router/lib/src/delegate.dart +++ b/packages/go_router/lib/src/delegate.dart @@ -145,7 +145,7 @@ class GoRouterDelegate extends RouterDelegate // If there is a promise for this page, complete it. if (last.completer != null) { - last.completer.complete(value); + last.completer?.complete(value); } _matchList.pop(); @@ -156,11 +156,11 @@ class GoRouterDelegate extends RouterDelegate /// /// See also: /// * [push] which pushes the given location onto the page stack. - Future replace(RouteMatch match) { + Future? replace(RouteMatch match) { _matchList.matches.last = match; notifyListeners(); - return match.completer.future as Future; + return match.completer?.future as Future?; } /// For internal use; visible for testing only. diff --git a/packages/go_router/lib/src/match.dart b/packages/go_router/lib/src/match.dart index 08cd14bf25a..8fdcc3f4357 100644 --- a/packages/go_router/lib/src/match.dart +++ b/packages/go_router/lib/src/match.dart @@ -20,7 +20,7 @@ class RouteMatch { required this.fullpath, required this.encodedParams, required this.queryParams, - required this.completer, + this.completer, required this.queryParametersAll, required this.extra, required this.error, @@ -43,7 +43,7 @@ class RouteMatch { required String parentSubloc, // e.g. /family/f2 required String fullpath, // e.g. /family/:fid/person/:pid required Map queryParams, - required Completer completer, + Completer? completer, required Map> queryParametersAll, required Object? extra, }) { @@ -117,7 +117,7 @@ class RouteMatch { final Map queryParams; /// The completer for the promise when pushing routes. - final Completer completer; + final Completer? completer; /// Returns the URI query split into a map according to the rules specified /// for FORM post in the [HTML 4.01 specification section diff --git a/packages/go_router/test/match_test.dart b/packages/go_router/test/match_test.dart index 69e6eaca1ae..a2d50ddf73c 100644 --- a/packages/go_router/test/match_test.dart +++ b/packages/go_router/test/match_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:go_router/go_router.dart'; @@ -56,6 +58,7 @@ void main() { 'foo': ['bar'], }, extra: const _Extra('foo'), + completer: Completer(), ); if (match == null) { fail('Null match'); From 6ef8dfdf4a6f96806ab486d7005072cab57f5201 Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Wed, 12 Oct 2022 12:04:58 -0300 Subject: [PATCH 35/36] Update CHANGELOG.md --- packages/go_router/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index 5286a42ac35..98cb27614a3 100644 --- a/packages/go_router/CHANGELOG.md +++ b/packages/go_router/CHANGELOG.md @@ -2,6 +2,7 @@ - Adds a Future option to `push` and `pushNamed` making it posible to await results from a `pop`. - Adds an optional parameter to the `pop` method, allowing to return values from a `pop`. + ## 5.0.5 - Fixes issue where asserts in popRoute were preventing the app from From ce29ba7acd907a65790085ef8262c23cc28b1e4e Mon Sep 17 00:00:00 2001 From: Nazareno Cavazzon Date: Wed, 12 Oct 2022 12:58:13 -0300 Subject: [PATCH 36/36] Final updates --- packages/go_router/CHANGELOG.md | 616 +----------------- packages/go_router/README.md | 49 +- .../example/lib/async_redirection.dart | 8 +- .../go_router/example/lib/books/main.dart | 2 +- .../lib/books/src/screens/author_details.dart | 2 +- .../lib/books/src/screens/authors.dart | 2 +- .../lib/books/src/screens/book_details.dart | 2 +- .../example/lib/books/src/screens/books.dart | 2 +- .../lib/books/src/screens/scaffold.dart | 2 +- .../lib/books/src/screens/settings.dart | 2 +- packages/go_router/example/lib/main.dart | 2 +- .../go_router/example/lib/named_routes.dart | 2 +- .../example/lib/others/error_screen.dart | 2 +- .../example/lib/others/extra_param.dart | 2 +- .../example/lib/others/init_loc.dart | 2 +- .../example/lib/others/nav_observer.dart | 2 +- .../go_router/example/lib/others/push.dart | 2 +- .../example/lib/others/router_neglect.dart | 2 +- .../example/lib/others/state_restoration.dart | 2 +- .../example/lib/others/transitions.dart | 2 +- .../lib/path_and_query_parameters.dart | 2 +- .../go_router/example/lib/redirection.dart | 2 +- .../go_router/example/lib/shell_route.dart | 2 +- .../go_router/example/lib/sub_routes.dart | 2 +- packages/go_router/example/pubspec.yaml | 2 +- packages/go_router/lib/go_router.dart | 2 +- .../lib/src/information_provider.dart | 2 +- packages/go_router/lib/src/route.dart | 8 +- packages/go_router/lib/src/router.dart | 6 +- packages/go_router/lib/src/state.dart | 2 +- packages/go_router/pubspec.yaml | 10 +- packages/go_router/test/builder_test.dart | 8 +- .../go_router/test/configuration_test.dart | 2 +- packages/go_router/test/cupertino_test.dart | 2 +- .../test/custom_transition_page_test.dart | 2 +- packages/go_router/test/delegate_test.dart | 6 +- packages/go_router/test/error_page_test.dart | 2 +- packages/go_router/test/go_route_test.dart | 2 +- packages/go_router/test/go_router_test.dart | 4 +- .../test/helpers/error_screen_helpers.dart | 2 +- .../test/information_provider_test.dart | 2 +- packages/go_router/test/inherited_test.dart | 2 +- packages/go_router/test/logging_test.dart | 2 +- packages/go_router/test/match_test.dart | 4 +- packages/go_router/test/material_test.dart | 2 +- packages/go_router/test/parser_test.dart | 12 +- packages/go_router/test/path_utils_test.dart | 2 +- packages/go_router/test/route_data_test.dart | 2 +- packages/go_router/test/test_helpers.dart | 6 +- 49 files changed, 101 insertions(+), 710 deletions(-) diff --git a/packages/go_router/CHANGELOG.md b/packages/go_router/CHANGELOG.md index 98cb27614a3..0261d88006f 100644 --- a/packages/go_router/CHANGELOG.md +++ b/packages/go_router/CHANGELOG.md @@ -1,616 +1,4 @@ -## 5.1.0 - -- Adds a Future option to `push` and `pushNamed` making it posible to await results from a `pop`. -- Adds an optional parameter to the `pop` method, allowing to return values from a `pop`. - -## 5.0.5 - -- Fixes issue where asserts in popRoute were preventing the app from - exiting on Android. - -## 5.0.4 - -- Fixes a bug in ShellRoute example where NavigationBar might lose current index in a nested routes. - -## 5.0.3 - -- Changes examples to use the routerConfig API - -## 5.0.2 - -- Fixes missing code example in ShellRoute documentation. - -## 5.0.1 - -- Allows ShellRoute to have child ShellRoutes (flutter/flutter#111981) - -## 5.0.0 - -- Fixes a bug where intermediate route redirect methods are not called. -- GoRouter implements the RouterConfig interface, allowing you to call - MaterialApp.router(routerConfig: _myGoRouter) instead of passing - the RouterDelegate, RouteInformationParser, and RouteInformationProvider - fields. -- **BREAKING CHANGE** - - Redesigns redirection API, adds asynchronous feature, and adds build context to redirect. - - Removes GoRouterRefreshStream - - Removes navigatorBuilder - - Removes urlPathStrategy -- [go_router v5 migration guide](https://flutter.dev/go/go-router-v5-breaking-changes) - -## 4.5.1 - -- Fixes an issue where GoRoutes with only a redirect were disallowed - (flutter/flutter#111763) - -## 4.5.0 - -- Adds ShellRoute for nested navigation support (flutter/flutter#99126) -- Adds `parentNavigatorKey` to GoRoute, which specifies the Navigator to place that - route's Page onto. - -## 4.4.1 - -- Fix an issue where disabling logging clears the root logger's listeners - -## 4.4.0 - -- Adds `buildPageWithState` to `GoRouteData`. -- `GoRouteData.buildPage` is now deprecated in favor of `GoRouteData.buildPageWithState`. - -## 4.3.0 - -- Allows `Map` maps as `queryParams` of `goNamed`, `replacedName`, `pushNamed` and `namedLocation`. - -## 4.2.9 - -* Updates text theme parameters to avoid deprecation issues. -* Fixes lint warnings. - -## 4.2.8 - -- Fixes namedLocation to return URIs without trailing question marks if there are no query parameters. -- Cleans up examples. - -## 4.2.7 - -- Updates README. - -## 4.2.6 - -- Fixes rendering issues in the README. - -## 4.2.5 - -- Fixes a bug where calling extra parameter is always null in route level redirect callback - -## 4.2.4 - -- Rewrites Readme and examples. - -## 4.2.3 - -- Fixes a bug where the ValueKey to be the same when a page was pushed multiple times. - -## 4.2.2 - -- Fixes a bug where go_router_builder wasn't detecting annotations. - -## 4.2.1 - -- Refactors internal classes and methods - -## 4.2.0 - -- Adds `void replace()` and `replaceNamed` to `GoRouterDelegate`, `GoRouter` and `GoRouterHelper`. - -## 4.1.1 - -- Fixes a bug where calling namedLocation does not support case-insensitive way. - -## 4.1.0 - -- Adds `bool canPop()` to `GoRouterDelegate`, `GoRouter` and `GoRouterHelper`. - -## 4.0.3 - -- Adds missed popping log. - -## 4.0.2 - -- Fixes a bug where initialLocation took precedence over deep-links - -## 4.0.1 - -- Fixes a bug where calling setLogging(false) does not clear listeners. - -## 4.0.0 - -- Refactors go_router and introduces `GoRouteInformationProvider`. [Migration Doc](https://flutter.dev/go/go-router-v4-breaking-changes) -- Fixes a bug where top-level routes are skipped if another contains child routes. - -## 3.1.1 - -- Uses first match if there are more than one route to match. [ [#99833](https://github.com/flutter/flutter/issues/99833) - -## 3.1.0 - -- Adds `GoRouteData` and `TypedGoRoute` to support `package:go_router_builder`. - -## 3.0.7 - -- Refactors runtime checks to assertions. - -## 3.0.6 - -- Exports inherited_go_router.dart file. - -## 3.0.5 - -- Add `dispatchNotification` method to `DummyBuildContext` in tests. (This - should be revisited when Flutter `2.11.0` becomes stable.) -- Improves code coverage. -- `GoRoute` now warns about requiring either `pageBuilder`, `builder` or `redirect` at instantiation. - -## 3.0.4 - -- Updates code for stricter analysis options. - -## 3.0.3 - -- Fixes a bug where params disappear when pushing a nested route. - -## 3.0.2 - -- Moves source to flutter/packages. -- Removes all_lint_rules_community and path_to_regexp dependencies. - -## 3.0.1 - -- pass along the error to the `navigatorBuilder` to allow for different - implementations based on the presence of an error - -## 3.0.0 - -- breaking change: added `GoRouterState` to `navigatorBuilder` function -- breaking change: removed `BuildContext` from `GoRouter.pop()` to remove the - need to use `context` parameter when calling the `GoRouter` API; this changes - the behavior of `GoRouter.pop()` to only pop what's on the `GoRouter` page - stack and no longer calls `Navigator.pop()` -- new [Migrating to 3.0 section](https://gorouter.dev/migrating-to-30) in the - docs to describe the details of the breaking changes and how to update your - code -- added a new [shared - scaffold](https://github.com/csells/go_router/blob/main/go_router/example/lib/shared_scaffold.dart) - sample to show how to use the `navigatorBuilder` function to build a custom - shared scaffold outside of the animations provided by go_router - -## 2.5.7 - -- [PR 262](https://github.com/csells/go_router/pull/262): add support for - `Router.neglect`; thanks to [nullrocket](https://github.com/nullrocket)! -- [PR 265](https://github.com/csells/go_router/pull/265): add Japanese - translation of the docs; thanks to - [toshi-kuji](https://github.com/toshi-kuji)! Unfortunately I don't yet know - how to properly display them via docs.page, but [I'm working on - it](https://github.com/csells/go_router/issues/266) -- updated the examples using the `from` query parameter to be completely - self-contained in the `redirect` function, simplifying usage -- updated the async data example to be simpler -- added a new example to show how to implement a loading page -- renamed the navigator_integration example to user_input and added an example - of `WillPopScope` for go_router apps - -## 2.5.6 - -- [PR 259](https://github.com/csells/go_router/pull/259): remove a hack for - notifying the router of a route change that was no longer needed; thanks to - [nullrocket](https://github.com/nullrocket)! -- improved async example to handle the case that the data has been returned but - the page is no longer there by checking the `mounted` property of the screen - -## 2.5.5 - -- updated implementation to use logging package for debug diagnostics; thanks - to [johnpryan](https://github.com/johnpryan) - -## 2.5.4 - -- fixed up the `GoRouterRefreshStream` implementation with an export, an example - and some docs - -## 2.5.3 - -- added `GoRouterRefreshStream` from - [jopmiddelkamp](https://github.com/jopmiddelkamp) to easily map from a - `Stream` to a `Listenable` for use with `refreshListenable`; very useful when - combined with stream-based state management like - [flutter_bloc](https://pub.dev/packages/flutter_bloc) -- dartdocs fixups from [mehade369](https://github.com/mehade369) -- example link fixes from [ben-milanko](https://github.com/ben-milanko) - -## 2.5.2 - -- pass additional information to the `NavigatorObserver` via default args to - `MaterialPage`, etc. - -## 2.5.1 - -- [fix 205](https://github.com/csells/go_router/issues/205): hack around a - failed assertion in Flutter when using `Duration.zero` in the - `NoTransitionPage` - -## 2.5.0 - -- provide default implementation of `GoRoute.pageBuilder` to provide a simpler - way to build pages via the `GoRouter.build` method -- provide default implementation of `GoRouter.errorPageBuilder` to provide a - simpler way to build error pages via the `GoRouter.errorBuilder` method -- provide default implementation of `GoRouter.errorBuilder` to provide an error - page without the need to implement a custom error page builder -- new [Migrating to 2.5 section](https://gorouter.dev/migrating-to-25) in - the docs to show how to take advantage of the new `builder` and default error - page builder -- removed `launch.json` as VSCode-centric and unnecessary for discovery or easy - launching -- added a [new custom error screen - sample](https://github.com/csells/go_router/blob/master/example/lib/error_screen.dart) -- added a [new WidgetsApp - sample](https://github.com/csells/go_router/blob/master/example/lib/widgets_app.dart) -- added a new `NoTransitionPage` class -- updated docs to explain why the browser's Back button doesn't work - with the `extra` param -- updated README to point to new docs site: [gorouter.dev](https://gorouter.dev) - -## 2.3.1 - -- [fix 191](https://github.com/csells/go_router/issues/191): handle several - kinds of trailing / in the location, e.g. `/foo/` should be the same as `/foo` - -## 2.3.0 - -- fix a misleading error message when using redirect functions with sub-routes - -## 2.2.9 - -- [fix 182](https://github.com/csells/go_router/issues/182): fixes a regression - in the nested navigation caused by the fix for - [#163](https://github.com/csells/go_router/issues/163); thanks to - [lulupointu](https://github.com/lulupointu) for the fix! - -## 2.2.8 - -- reformatted CHANGELOG file; lets see if pub.dev is still ok with it... -- staged an in-progress doc site at https://docs.page/csells/go_router -- tightened up a test that was silently failing -- fixed a bug that dropped parent params in sub-route redirects - -## 2.2.7 - -- [fix 163](https://github.com/csells/go_router/issues/163): avoids unnecessary - page rebuilds -- [fix 139](https://github.com/csells/go_router/issues/139): avoids unnecessary - page flashes on deep linking -- [fix 158](https://github.com/csells/go_router/issues/158): shows exception - info in the debug output even during a top-level redirect coded w/ an - anonymous function, i.e. what the samples all use -- [fix 151](https://github.com/csells/go_router/issues/151): exposes - `Navigator.pop()` via `GoRouter.pop()` to make it easy to find - -## 2.2.6 - -- [fix 127](https://github.com/csells/go_router/issues/127): updated the docs - to add a video overview of the project for people that prefer that media style - over long-form text when approaching a new topic -- [fix 108](https://github.com/csells/go_router/issues/108): updated the - description of the `state` parameter to clarfy that not all properties will be - set at every usage - -## 2.2.5 - -- [fix 120 again](https://github.com/csells/go_router/issues/120): found the bug - in my tests that was masking the real bug; changed two characters to implement - the actual fix (sigh) - -## 2.2.4 - -- [fix 116](https://github.com/csells/go_router/issues/116): work-around for - auto-import of the `context.go` family of extension methods - -## 2.2.3 - -- [fix 132](https://github.com/csells/go_router/issues/132): route names are - stored as case insensitive and are now matched in a case insensitive manner - -## 2.2.2 - -- [fix 120](https://github.com/csells/go_router/issues/120): encoding and - decoding of params and query params - -## 2.2.1 - -- [fix 114](https://github.com/csells/go_router/issues/114): give a better error - message when the `GoRouter` isn't found in the widget tree via - `GoRouter.of(context)`; thanks [aoatmon](https://github.com/aoatmon) for the - [excellent bug report](https://github.com/csells/go_router/issues/114)! - -## 2.2.0 - -- added a new [`navigatorBuilder`](https://gorouter.dev/navigator-builder) argument to the - `GoRouter` constructor; thanks to [andyduke](https://github.com/andyduke)! -- also from [andyduke](https://github.com/andyduke) is an update to - improve state restoration -- refactor from [kevmoo](https://github.com/kevmoo) for easier maintenance -- added a new [Navigator Integration section of the - docs](https://gorouter.dev/navigator-integration) - -## 2.1.2 - -- [fix 61 again](https://github.com/csells/go_router/issues/61): enable images - and file links to work on pub.dev/documentation -- [fix 62](https://github.com/csells/go_router/issues/62) re-tested; fixed w/ - earlier Android system Back button fix (using navigation key) -- [fix 91](https://github.com/csells/go_router/issues/91): fix a regression w/ - the `errorPageBuilder` -- [fix 92](https://github.com/csells/go_router/issues/92): fix an edge case w/ - named sub-routes -- [fix 89](https://github.com/csells/go_router/issues/89): enable queryParams - and extra object param w/ `push` -- refactored tests for greater coverage and fewer methods `@visibleForTesting` - -## 2.1.1 - -- [fix 86](https://github.com/csells/go_router/issues/86): add `name` to - `GoRouterState` to complete support for URI-free navigation knowledge in your - code -- [fix 83](https://github.com/csells/go_router/issues/83): fix for `null` - `extra` object - -## 2.1.0 - -- [fix 80](https://github.com/csells/go_router/issues/80): adding a redirect - limit to catch too many redirects error -- [fix 81](https://github.com/csells/go_router/issues/81): allow an `extra` - object to pass through for navigation - -## 2.0.1 - -- add badges to the README and codecov to the GitHub commit action; thanks to - [rydmike](https://github.com/rydmike) for both - -## 2.0.0 - -- BREAKING CHANGE and [fix #50](https://github.com/csells/go_router/issues/50): - split `params` into `params` and `queryParams`; see the [Migrating to 2.0 - section of the docs](https://gorouter.dev/migrating-to-20) - for instructions on how to migrate your code from 1.x to 2.0 -- [fix 69](https://github.com/csells/go_router/issues/69): exposed named - location lookup for redirection -- [fix 57](https://github.com/csells/go_router/issues/57): enable the Android - system Back button to behave exactly like the `AppBar` Back button; thanks to - [SunlightBro](https://github.com/SunlightBro) for the one-line fix that I had - no idea about until he pointed it out -- [fix 59](https://github.com/csells/go_router/issues/59): add query params to - top-level redirect -- [fix 44](https://github.com/csells/go_router/issues/44): show how to use the - `AutomaticKeepAliveClientMixin` with nested navigation to keep widget state - between navigations; thanks to [rydmike](https://github.com/rydmike) for this - update - -## 1.1.3 - -- enable case-insensitive path matching while still preserving path and query - parameter cases -- change a lifetime of habit to sort constructors first as per - [sort_constructors_first](https://dart-lang.github.io/linter/lints/sort_constructors_first.html). - Thanks for the PR, [Abhishek01039](https://github.com/Abhishek01039)! -- set the initial transition example route to `/none` to make pushing the 'fade - transition' button on the first run through more fun -- fixed an error in the async data example - -## 1.1.2 - -- Thanks, Mikes! - - updated dartdocs from [rydmike](https://github.com/rydmike) - - also shoutout to [https://github.com/Salakar](https://github.com/Salakar) - for the CI action on GitHub - - this is turning into a real community effort... - -## 1.1.1 - -- now showing routing exceptions in the debug log -- updated the docs to make it clear that it will be called until it returns - `null` - -## 1.1.0 - -- added support `NavigatorObserver` objects to receive change notifications - -## 1.0.1 - -- docs updates based on user feedback for clarity -- fix for setting URL path strategy in `main()` -- fix for `push()` disables `AppBar` Back button - ## 1.0.0 -- updated version for initial release -- some renaming for clarify and consistency with transitions - - `GoRoute.builder` => `GoRoute.pageBuilder` - - `GoRoute.error` => `GoRoute.errorPageBuilder` -- added diagnostic logging for `push` and `pushNamed` - -## 0.9.6 - -- added support for `push` as well as `go` -- added 'none' to transitions example app -- updated animation example to use no transition and added an animated gif to - the docs - -## 0.9.5 - -- added support for custom transitions between routes - -## 0.9.4 - -- updated API docs -- updated docs for `GoRouterState` - -## 0.9.3 - -- updated API docs - -## 0.9.2 - -- updated named route lookup to O(1) -- updated diagnostics output to show known named routes - -## 0.9.1 - -- updated diagnostics output to show named route lookup -- docs updates - -## 0.9.0 - -- added support for named routes - -## 0.8.8 - -- fix to make `GoRouter` notify on pop - -## 0.8.7 - -- made `GoRouter` a `ChangeNotifier` so you can listen for `location` changes - -## 0.8.6 - -- books sample bug fix - -## 0.8.5 - -- added Cupertino sample -- added example of async data lookup - -## 0.8.4 - -- added state restoration sample - -## 0.8.3 - -- changed `debugOutputFullPaths` to `debugLogDiagnostics` and added add'l - debugging logging -- parameterized redirect - -## 0.8.2 - -- updated docs for `Link` widget support - -## 0.8.1 - -- added Books sample; fixed some issues it revealed - -## 0.8.0 - -- breaking build to refactor the API for simplicity and capability -- move to fixed routing from conditional routing; simplies API, allows for - redirection at the route level and there scenario was sketchy anyway -- add redirection at the route level -- replace guard objects w/ redirect functions -- add `refresh` method and `refreshListener` -- removed `.builder` ctor from `GoRouter` (not reasonable to implement) -- add Dynamic linking section to the docs -- replaced Books sample with Nested Navigation sample -- add ability to dump the known full paths to your routes to debug output - -## 0.7.1 - -- update to pageKey to take sub-routes into account - -## 0.7.0 - -- BREAK: rename `pattern` to `path` for consistency w/ other routers in the - world -- added the `GoRouterLoginGuard` for the common redirect-to-login-page pattern - -## 0.6.2 - -- fixed issue showing home page for a second before redirecting (if needed) - -## 0.6.1 - -- added `GoRouterState.pageKey` -- removed `cupertino_icons` from main `pubspec.yaml` - -## 0.6.0 - -- refactor to support sub-routes to build a stack of pages instead of matching - multiple routes -- added unit tests for building the stack of pages -- some renaming of the types, e.g. `Four04Page` and `FamiliesPage` to - `ErrorPage` and `HomePage` respectively -- fix a redirection error shown in the debug output - -## 0.5.2 - -- add `urlPathStrategy` argument to `GoRouter` ctor - -## 0.5.1 - -- docs and description updates - -## 0.5.0 - -- moved redirect to top-level instead of per route for simplicity - -## 0.4.1 - -- fixed CHANGELOG formatting - -## 0.4.0 - -- bundled various useful route handling variables into the `GoRouterState` for - use when building pages and error pages -- updated URL Strategy section of docs to reference `flutter run` - -## 0.3.2 - -- formatting update to appease the pub.dev gods... - -## 0.3.1 - -- updated the CHANGELOG - -## 0.3.0 - -- moved redirection into a `GoRoute` ctor arg -- forgot to update the CHANGELOG - -## 0.2.3 - -- move outstanding issues to [issue - tracker](https://github.com/csells/go_router/issues) -- added explanation of Deep Linking to docs -- reformatting to meet pub.dev scoring guidelines - -## 0.2.2 - -- docs updates - -## 0.2.1 - -- messing with the CHANGELOG formatting - -## 0.2.0 - -- initial useful release -- added support for declarative routes via `GoRoute` instances -- added support for imperative routing via `GoRoute.builder` -- added support for setting the URL path strategy -- added support for conditional routing -- added support for redirection -- added support for optional query parameters as well as positional parameters - in route names - -## 0.1.0 - -- squatting on the package name (I'm not too proud to admit it) +- Adds a Future option to `push` and `pushNamed` making it posible to await results from a `pop`. +- Adds an optional parameter to the `pop` method, allowing to return values from a `pop`. \ No newline at end of file diff --git a/packages/go_router/README.md b/packages/go_router/README.md index 79316389ad1..903cf536fe6 100644 --- a/packages/go_router/README.md +++ b/packages/go_router/README.md @@ -1,16 +1,35 @@ -# go_router +# go_router_flow -A Declarative Routing Package for Flutter. +This package was created for [SportsVisio's](https://sportsvisio.com/) apps, and it's currently in use and tested, and it'll be updated until the day go_router implements it. -This package uses the Flutter framework's Router API to provide a -convenient, url-based API for navigating between different screens. You can -define URL patterns, navigate using a URL, handle deep links, -and a number of other navigation-related scenarios. +This is a fork of the go_router package that let's you communicate between pages by returning values on pop like in navigator 1.0. This was implemented by adding completers in the routes and waiting for the values when requested. + +## Returning values +This is the reason for this package, to be able to return stuff when a screens pop. + +Waiting for a value to be returned: + +```dart +onTap: () { + // In the new page you can do 'context.pop(someValue)' to return a value. + final bool? result = await context.push('/page2'); + + WidgetsBinding.instance.addPostFrameCallback((_) { + if(result ?? false)... + }); +} +``` + +Returning a value: + +```dart +onTap: () => context.pop(true) +``` ## Getting Started -Follow the [package install instructions](https://pub.dev/packages/go_router/install), -and you can start using go_router in your app: +Follow the [package install instructions](https://pub.dev/packages/go_router_flow/install), +and you can start using go_router_flow in your app: ```dart import 'package:flutter/material.dart'; @@ -166,20 +185,6 @@ methods: onTap: () => context.go('/page2') ``` - -To wait for values when the screen pops: - -```dart -onTap: () { - // In the new page you can do 'context.pop(someValue)' to return a value. - final bool? result = await context.push('/page2'); - - WidgetsBinding.instance.addPostFrameCallback((_) { - if(result ?? false)... - }); -} -``` - ## Nested Navigation The `ShellRoute` route type provides a way to wrap all sub-routes with a UI shell. diff --git a/packages/go_router/example/lib/async_redirection.dart b/packages/go_router/example/lib/async_redirection.dart index 14598a0e383..6b30b29b05b 100644 --- a/packages/go_router/example/lib/async_redirection.dart +++ b/packages/go_router/example/lib/async_redirection.dart @@ -5,7 +5,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; // This scenario demonstrates how to use redirect to handle a asynchronous // sign-in flow. @@ -13,8 +13,8 @@ import 'package:go_router/go_router.dart'; // The `StreamAuth` is a mock of google_sign_in. This example wraps it with an // InheritedNotifier, StreamAuthScope, and relies on // `dependOnInheritedWidgetOfExactType` to create a dependency between the -// notifier and go_router's parsing pipeline. When StreamAuth broadcasts new -// event, the dependency will cause the go_router to reparse the current url +// notifier and go_router_flow's parsing pipeline. When StreamAuth broadcasts new +// event, the dependency will cause the go_router_flow to reparse the current url // which will also trigger the redirect. void main() => runApp(StreamAuthScope(child: App())); @@ -52,7 +52,7 @@ class App extends StatelessWidget { // redirect to the login page if the user is not logged in redirect: (BuildContext context, GoRouterState state) async { // Using `of` method creates a dependency of StreamAuthScope. It will - // cause go_router to reparse current route if StreamAuth has new sign-in + // cause go_router_flow to reparse current route if StreamAuth has new sign-in // information. final bool loggedIn = await StreamAuthScope.of(context).isSignedIn(); final bool loggingIn = state.subloc == '/login'; diff --git a/packages/go_router/example/lib/books/main.dart b/packages/go_router/example/lib/books/main.dart index 16068d6668a..7a38f448f3c 100644 --- a/packages/go_router/example/lib/books/main.dart +++ b/packages/go_router/example/lib/books/main.dart @@ -4,7 +4,7 @@ import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; import 'src/auth.dart'; import 'src/data/author.dart'; diff --git a/packages/go_router/example/lib/books/src/screens/author_details.dart b/packages/go_router/example/lib/books/src/screens/author_details.dart index d03ae630c52..ced97893be1 100644 --- a/packages/go_router/example/lib/books/src/screens/author_details.dart +++ b/packages/go_router/example/lib/books/src/screens/author_details.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; import '../data.dart'; import '../widgets/book_list.dart'; diff --git a/packages/go_router/example/lib/books/src/screens/authors.dart b/packages/go_router/example/lib/books/src/screens/authors.dart index 893a3c00bb6..ee82450c7a6 100644 --- a/packages/go_router/example/lib/books/src/screens/authors.dart +++ b/packages/go_router/example/lib/books/src/screens/authors.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; import '../data.dart'; import '../widgets/author_list.dart'; diff --git a/packages/go_router/example/lib/books/src/screens/book_details.dart b/packages/go_router/example/lib/books/src/screens/book_details.dart index 0bc724e0d86..6a39d7c2923 100644 --- a/packages/go_router/example/lib/books/src/screens/book_details.dart +++ b/packages/go_router/example/lib/books/src/screens/book_details.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; import 'package:url_launcher/link.dart'; import '../data.dart'; diff --git a/packages/go_router/example/lib/books/src/screens/books.dart b/packages/go_router/example/lib/books/src/screens/books.dart index ea868488519..7b6a3f08c4e 100644 --- a/packages/go_router/example/lib/books/src/screens/books.dart +++ b/packages/go_router/example/lib/books/src/screens/books.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; import '../data.dart'; import '../widgets/book_list.dart'; diff --git a/packages/go_router/example/lib/books/src/screens/scaffold.dart b/packages/go_router/example/lib/books/src/screens/scaffold.dart index a5ff831eef3..ba21c9b6bb0 100644 --- a/packages/go_router/example/lib/books/src/screens/scaffold.dart +++ b/packages/go_router/example/lib/books/src/screens/scaffold.dart @@ -5,7 +5,7 @@ import 'package:adaptive_navigation/adaptive_navigation.dart'; import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; /// The enum for scaffold tab. enum ScaffoldTab { diff --git a/packages/go_router/example/lib/books/src/screens/settings.dart b/packages/go_router/example/lib/books/src/screens/settings.dart index 71bd0f8513b..b6eb54a3121 100644 --- a/packages/go_router/example/lib/books/src/screens/settings.dart +++ b/packages/go_router/example/lib/books/src/screens/settings.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; import 'package:url_launcher/link.dart'; import '../auth.dart'; diff --git a/packages/go_router/example/lib/main.dart b/packages/go_router/example/lib/main.dart index c47fc49021f..8827bc8ca1a 100644 --- a/packages/go_router/example/lib/main.dart +++ b/packages/go_router/example/lib/main.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; // This scenario demonstrates a simple two-page app. // diff --git a/packages/go_router/example/lib/named_routes.dart b/packages/go_router/example/lib/named_routes.dart index 237581faf17..0b8f8c45f1e 100644 --- a/packages/go_router/example/lib/named_routes.dart +++ b/packages/go_router/example/lib/named_routes.dart @@ -8,7 +8,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; // This scenario demonstrates how to navigate using named locations instead of // URLs. diff --git a/packages/go_router/example/lib/others/error_screen.dart b/packages/go_router/example/lib/others/error_screen.dart index f7edca033ad..3371aefc6e0 100644 --- a/packages/go_router/example/lib/others/error_screen.dart +++ b/packages/go_router/example/lib/others/error_screen.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; void main() => runApp(App()); diff --git a/packages/go_router/example/lib/others/extra_param.dart b/packages/go_router/example/lib/others/extra_param.dart index a4d40e9647b..24bab216c4e 100644 --- a/packages/go_router/example/lib/others/extra_param.dart +++ b/packages/go_router/example/lib/others/extra_param.dart @@ -8,7 +8,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; final Map _families = const JsonDecoder().convert(''' { diff --git a/packages/go_router/example/lib/others/init_loc.dart b/packages/go_router/example/lib/others/init_loc.dart index 31ca5947420..3842c348473 100644 --- a/packages/go_router/example/lib/others/init_loc.dart +++ b/packages/go_router/example/lib/others/init_loc.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; void main() => runApp(App()); diff --git a/packages/go_router/example/lib/others/nav_observer.dart b/packages/go_router/example/lib/others/nav_observer.dart index a63023d99a9..21b9a243181 100644 --- a/packages/go_router/example/lib/others/nav_observer.dart +++ b/packages/go_router/example/lib/others/nav_observer.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; import 'package:logging/logging.dart'; void main() => runApp(App()); diff --git a/packages/go_router/example/lib/others/push.dart b/packages/go_router/example/lib/others/push.dart index 5d54ec2cde8..490caac6ca1 100644 --- a/packages/go_router/example/lib/others/push.dart +++ b/packages/go_router/example/lib/others/push.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; void main() => runApp(App()); diff --git a/packages/go_router/example/lib/others/router_neglect.dart b/packages/go_router/example/lib/others/router_neglect.dart index d5c22802992..d17ff2d2de1 100644 --- a/packages/go_router/example/lib/others/router_neglect.dart +++ b/packages/go_router/example/lib/others/router_neglect.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; void main() => runApp(App()); diff --git a/packages/go_router/example/lib/others/state_restoration.dart b/packages/go_router/example/lib/others/state_restoration.dart index 5c6016f4f53..5e9388d3c28 100644 --- a/packages/go_router/example/lib/others/state_restoration.dart +++ b/packages/go_router/example/lib/others/state_restoration.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; void main() => runApp( const RootRestorationScope(restorationId: 'root', child: App()), diff --git a/packages/go_router/example/lib/others/transitions.dart b/packages/go_router/example/lib/others/transitions.dart index 51c2a246c60..c7bc2b89eb9 100644 --- a/packages/go_router/example/lib/others/transitions.dart +++ b/packages/go_router/example/lib/others/transitions.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; void main() => runApp(App()); diff --git a/packages/go_router/example/lib/path_and_query_parameters.dart b/packages/go_router/example/lib/path_and_query_parameters.dart index 7e52baf68d7..defedca0db6 100755 --- a/packages/go_router/example/lib/path_and_query_parameters.dart +++ b/packages/go_router/example/lib/path_and_query_parameters.dart @@ -8,7 +8,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; // This scenario demonstrates how to use path parameters and query parameters. // diff --git a/packages/go_router/example/lib/redirection.dart b/packages/go_router/example/lib/redirection.dart index 1e235737798..e08677e85cb 100644 --- a/packages/go_router/example/lib/redirection.dart +++ b/packages/go_router/example/lib/redirection.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; import 'package:provider/provider.dart'; // This scenario demonstrates how to use redirect to handle a sign-in flow. diff --git a/packages/go_router/example/lib/shell_route.dart b/packages/go_router/example/lib/shell_route.dart index 8c73c83870a..e25c9c951ef 100644 --- a/packages/go_router/example/lib/shell_route.dart +++ b/packages/go_router/example/lib/shell_route.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; final GlobalKey _rootNavigatorKey = GlobalKey(debugLabel: 'root'); diff --git a/packages/go_router/example/lib/sub_routes.dart b/packages/go_router/example/lib/sub_routes.dart index 8bd7728ba7b..b6f1f6dcf5d 100644 --- a/packages/go_router/example/lib/sub_routes.dart +++ b/packages/go_router/example/lib/sub_routes.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter/material.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; // This scenario demonstrates an app with multi-level routing. // diff --git a/packages/go_router/example/pubspec.yaml b/packages/go_router/example/pubspec.yaml index e25674276ee..d60fa349da7 100644 --- a/packages/go_router/example/pubspec.yaml +++ b/packages/go_router/example/pubspec.yaml @@ -14,7 +14,7 @@ dependencies: cupertino_icons: ^1.0.2 flutter: sdk: flutter - go_router: + go_router_flow: path: .. logging: ^1.0.0 package_info_plus: ^1.3.0 diff --git a/packages/go_router/lib/go_router.dart b/packages/go_router/lib/go_router.dart index 1d9f9dd8e15..930ad6111c9 100644 --- a/packages/go_router/lib/go_router.dart +++ b/packages/go_router/lib/go_router.dart @@ -4,7 +4,7 @@ /// A declarative router for Flutter based on Navigation 2 supporting /// deep linking, data-driven routes and more. -library go_router; +library go_router_flow; export 'src/configuration.dart' show GoRoute, GoRouterState, RouteBase, ShellRoute; diff --git a/packages/go_router/lib/src/information_provider.dart b/packages/go_router/lib/src/information_provider.dart index 207ec45d40c..e3c1684c726 100644 --- a/packages/go_router/lib/src/information_provider.dart +++ b/packages/go_router/lib/src/information_provider.dart @@ -7,7 +7,7 @@ import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'parser.dart'; -/// The [RouteInformationProvider] created by go_router. +/// The [RouteInformationProvider] created by go_router_flow. class GoRouteInformationProvider extends RouteInformationProvider with WidgetsBindingObserver, ChangeNotifier { /// Creates a [GoRouteInformationProvider]. diff --git a/packages/go_router/lib/src/route.dart b/packages/go_router/lib/src/route.dart index aca0495e315..11594505a0e 100644 --- a/packages/go_router/lib/src/route.dart +++ b/packages/go_router/lib/src/route.dart @@ -92,7 +92,7 @@ import 'typedefs.dart'; /// In the above example, if /family route is matched, it will be used. /// else /:username route will be used. /// -/// See [Sub-routes](https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/sub_routes.dart) +/// See [Sub-routes](https://github.com/flutter/packages/blob/main/packages/go_router_flow/example/lib/sub_routes.dart) /// for a complete runnable example. @immutable abstract class RouteBase { @@ -195,7 +195,7 @@ class GoRoute extends RouteBase { /// ); /// ``` /// - /// See the [named routes example](https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/named_routes.dart) + /// See the [named routes example](https://github.com/flutter/packages/blob/main/packages/go_router_flow/example/lib/named_routes.dart) /// for a complete runnable app. final String? name; @@ -220,7 +220,7 @@ class GoRoute extends RouteBase { /// The query parameter are also capture during the route parsing and stored /// in [GoRouterState]. /// - /// See [Query parameters and path parameters](https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/sub_routes.dart) + /// See [Query parameters and path parameters](https://github.com/flutter/packages/blob/main/packages/go_router_flow/example/lib/sub_routes.dart) /// to learn more about parameters. final String path; @@ -305,7 +305,7 @@ class GoRoute extends RouteBase { /// /// Redirect can also be used for conditionally preventing users from visiting /// routes, also known as route guards. One canonical example is user - /// authentication. See [Redirection](https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/redirection.dart) + /// authentication. See [Redirection](https://github.com/flutter/packages/blob/main/packages/go_router_flow/example/lib/redirection.dart) /// for a complete runnable example. /// /// If [BuildContext.dependOnInheritedWidgetOfExactType] is used during the diff --git a/packages/go_router/lib/src/router.dart b/packages/go_router/lib/src/router.dart index 520c5f68496..58616bc47f2 100644 --- a/packages/go_router/lib/src/router.dart +++ b/packages/go_router/lib/src/router.dart @@ -23,10 +23,10 @@ import 'typedefs.dart'; /// The `routes` defines the routing table. It must not be empty and must /// contain an [GoRouter] to match `/`. /// -/// See [Routes](https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/main.dart) +/// See [Routes](https://github.com/flutter/packages/blob/main/packages/go_router_flow/example/lib/main.dart) /// for an example of defining a simple routing table. /// -/// See [Sub-routes](https://github.com/flutter/packages/blob/main/packages/go_router/example/lib/sub_routes.dart) +/// See [Sub-routes](https://github.com/flutter/packages/blob/main/packages/go_router_flow/example/lib/sub_routes.dart) /// for an example of defining a multi-level routing table. /// /// The `redirect` does top-level redirection before the URIs are parsed by @@ -37,7 +37,7 @@ import 'typedefs.dart'; /// /// See also: /// * [GoRoute], which provides APIs to define the routing table. -/// * [examples](https://github.com/flutter/packages/tree/main/packages/go_router/example), +/// * [examples](https://github.com/flutter/packages/tree/main/packages/go_router_flow/example), /// which contains examples for different routing scenarios. class GoRouter extends ChangeNotifier with NavigatorObserver diff --git a/packages/go_router/lib/src/state.dart b/packages/go_router/lib/src/state.dart index 7529c22a036..387ccf38015 100644 --- a/packages/go_router/lib/src/state.dart +++ b/packages/go_router/lib/src/state.dart @@ -31,7 +31,7 @@ class GoRouterState { ? fullpath : subloc); - // TODO(johnpryan): remove once namedLocation is removed from go_router. + // TODO(johnpryan): remove once namedLocation is removed from go_router_flow. // See https://github.com/flutter/flutter/issues/107729 final RouteConfiguration _configuration; diff --git a/packages/go_router/pubspec.yaml b/packages/go_router/pubspec.yaml index e0a7c08a856..95b90166ec7 100644 --- a/packages/go_router/pubspec.yaml +++ b/packages/go_router/pubspec.yaml @@ -1,9 +1,7 @@ -name: go_router -description: A declarative router for Flutter based on Navigation 2 supporting - deep linking, data-driven routes and more -version: 5.1.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 +name: go_router_flow +description: A fork of go_router that let's you returns value on pop like navigator 1.0 +version: 1.0.0 +repository: https://github.com/NazarenoCavazzon/flutter-packages/tree/main/packages/go_router environment: sdk: ">=2.17.0 <3.0.0" diff --git a/packages/go_router/test/builder_test.dart b/packages/go_router/test/builder_test.dart index 92eb17fb0b7..a2761198118 100644 --- a/packages/go_router/test/builder_test.dart +++ b/packages/go_router/test/builder_test.dart @@ -4,10 +4,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/src/builder.dart'; -import 'package:go_router/src/configuration.dart'; -import 'package:go_router/src/match.dart'; -import 'package:go_router/src/matching.dart'; +import 'package:go_router_flow/src/builder.dart'; +import 'package:go_router_flow/src/configuration.dart'; +import 'package:go_router_flow/src/match.dart'; +import 'package:go_router_flow/src/matching.dart'; void main() { group('RouteBuilder', () { diff --git a/packages/go_router/test/configuration_test.dart b/packages/go_router/test/configuration_test.dart index 61f769f4c53..18f0dec4d51 100644 --- a/packages/go_router/test/configuration_test.dart +++ b/packages/go_router/test/configuration_test.dart @@ -4,7 +4,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/src/configuration.dart'; +import 'package:go_router_flow/src/configuration.dart'; void main() { group('RouteConfiguration', () { diff --git a/packages/go_router/test/cupertino_test.dart b/packages/go_router/test/cupertino_test.dart index 323aea3e02d..acfd46018f0 100644 --- a/packages/go_router/test/cupertino_test.dart +++ b/packages/go_router/test/cupertino_test.dart @@ -5,7 +5,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/src/pages/cupertino.dart'; +import 'package:go_router_flow/src/pages/cupertino.dart'; import 'helpers/error_screen_helpers.dart'; diff --git a/packages/go_router/test/custom_transition_page_test.dart b/packages/go_router/test/custom_transition_page_test.dart index 50fe6255695..5938af3551a 100644 --- a/packages/go_router/test/custom_transition_page_test.dart +++ b/packages/go_router/test/custom_transition_page_test.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; void main() { testWidgets('CustomTransitionPage builds its child using transitionsBuilder', diff --git a/packages/go_router/test/delegate_test.dart b/packages/go_router/test/delegate_test.dart index f60ce65fd95..dc68009b1da 100644 --- a/packages/go_router/test/delegate_test.dart +++ b/packages/go_router/test/delegate_test.dart @@ -4,9 +4,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/go_router.dart'; -import 'package:go_router/src/match.dart'; -import 'package:go_router/src/misc/error_screen.dart'; +import 'package:go_router_flow/go_router.dart'; +import 'package:go_router_flow/src/match.dart'; +import 'package:go_router_flow/src/misc/error_screen.dart'; Future createGoRouter( WidgetTester tester, { diff --git a/packages/go_router/test/error_page_test.dart b/packages/go_router/test/error_page_test.dart index 071cc962e73..b688125515f 100644 --- a/packages/go_router/test/error_page_test.dart +++ b/packages/go_router/test/error_page_test.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/src/misc/error_screen.dart'; +import 'package:go_router_flow/src/misc/error_screen.dart'; import 'helpers/error_screen_helpers.dart'; diff --git a/packages/go_router/test/go_route_test.dart b/packages/go_router/test/go_route_test.dart index 31361aa6538..f7d0f6284dc 100644 --- a/packages/go_router/test/go_route_test.dart +++ b/packages/go_router/test/go_route_test.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; void main() { test('throws when a builder is not set', () { diff --git a/packages/go_router/test/go_router_test.dart b/packages/go_router/test/go_router_test.dart index 0c0e1368603..693c0185ec0 100644 --- a/packages/go_router/test/go_router_test.dart +++ b/packages/go_router/test/go_router_test.dart @@ -8,8 +8,8 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/go_router.dart'; -import 'package:go_router/src/match.dart'; +import 'package:go_router_flow/go_router.dart'; +import 'package:go_router_flow/src/match.dart'; import 'package:logging/logging.dart'; import 'test_helpers.dart'; diff --git a/packages/go_router/test/helpers/error_screen_helpers.dart b/packages/go_router/test/helpers/error_screen_helpers.dart index 26822e27333..ef984563ad9 100644 --- a/packages/go_router/test/helpers/error_screen_helpers.dart +++ b/packages/go_router/test/helpers/error_screen_helpers.dart @@ -5,7 +5,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; import '../test_helpers.dart'; diff --git a/packages/go_router/test/information_provider_test.dart b/packages/go_router/test/information_provider_test.dart index e6ce0945508..3afcf4d0215 100644 --- a/packages/go_router/test/information_provider_test.dart +++ b/packages/go_router/test/information_provider_test.dart @@ -4,7 +4,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/src/information_provider.dart'; +import 'package:go_router_flow/src/information_provider.dart'; const RouteInformation initialRoute = RouteInformation(location: '/'); const RouteInformation newRoute = RouteInformation(location: '/new'); diff --git a/packages/go_router/test/inherited_test.dart b/packages/go_router/test/inherited_test.dart index 08f202389d8..27c3b4a762a 100644 --- a/packages/go_router/test/inherited_test.dart +++ b/packages/go_router/test/inherited_test.dart @@ -5,7 +5,7 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; void main() { group('updateShouldNotify', () { diff --git a/packages/go_router/test/logging_test.dart b/packages/go_router/test/logging_test.dart index d6e278610fb..b2fa465b6c9 100644 --- a/packages/go_router/test/logging_test.dart +++ b/packages/go_router/test/logging_test.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/src/logging.dart'; +import 'package:go_router_flow/src/logging.dart'; import 'package:logging/logging.dart'; void main() { diff --git a/packages/go_router/test/match_test.dart b/packages/go_router/test/match_test.dart index a2d50ddf73c..ab317dd8d16 100644 --- a/packages/go_router/test/match_test.dart +++ b/packages/go_router/test/match_test.dart @@ -6,8 +6,8 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/go_router.dart'; -import 'package:go_router/src/match.dart'; +import 'package:go_router_flow/go_router.dart'; +import 'package:go_router_flow/src/match.dart'; void main() { group('RouteMatch', () { diff --git a/packages/go_router/test/material_test.dart b/packages/go_router/test/material_test.dart index 4da273ea7b0..d8ae5cfc479 100644 --- a/packages/go_router/test/material_test.dart +++ b/packages/go_router/test/material_test.dart @@ -5,7 +5,7 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/src/pages/material.dart'; +import 'package:go_router_flow/src/pages/material.dart'; import 'helpers/error_screen_helpers.dart'; diff --git a/packages/go_router/test/parser_test.dart b/packages/go_router/test/parser_test.dart index 01654662b85..b1fd5012d32 100644 --- a/packages/go_router/test/parser_test.dart +++ b/packages/go_router/test/parser_test.dart @@ -4,12 +4,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/go_router.dart'; -import 'package:go_router/src/configuration.dart'; -import 'package:go_router/src/information_provider.dart'; -import 'package:go_router/src/match.dart'; -import 'package:go_router/src/matching.dart'; -import 'package:go_router/src/parser.dart'; +import 'package:go_router_flow/go_router.dart'; +import 'package:go_router_flow/src/configuration.dart'; +import 'package:go_router_flow/src/information_provider.dart'; +import 'package:go_router_flow/src/match.dart'; +import 'package:go_router_flow/src/matching.dart'; +import 'package:go_router_flow/src/parser.dart'; void main() { Future createParser( diff --git a/packages/go_router/test/path_utils_test.dart b/packages/go_router/test/path_utils_test.dart index 1c883c45155..fcf2a2e7f83 100644 --- a/packages/go_router/test/path_utils_test.dart +++ b/packages/go_router/test/path_utils_test.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/src/path_utils.dart'; +import 'package:go_router_flow/src/path_utils.dart'; void main() { test('patternToRegExp without path parameter', () async { diff --git a/packages/go_router/test/route_data_test.dart b/packages/go_router/test/route_data_test.dart index 4ae12f6dfb1..64e5fbe62f9 100644 --- a/packages/go_router/test/route_data_test.dart +++ b/packages/go_router/test/route_data_test.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/go_router.dart'; +import 'package:go_router_flow/go_router.dart'; class _GoRouteDataBuild extends GoRouteData { const _GoRouteDataBuild(); diff --git a/packages/go_router/test/test_helpers.dart b/packages/go_router/test/test_helpers.dart index 2a755d6d22f..40b1a551df9 100644 --- a/packages/go_router/test/test_helpers.dart +++ b/packages/go_router/test/test_helpers.dart @@ -8,9 +8,9 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter/src/foundation/diagnostics.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/go_router.dart'; -import 'package:go_router/src/match.dart'; -import 'package:go_router/src/matching.dart'; +import 'package:go_router_flow/go_router.dart'; +import 'package:go_router_flow/src/match.dart'; +import 'package:go_router_flow/src/matching.dart'; Future createGoRouter(WidgetTester tester) async { final GoRouter goRouter = GoRouter(