-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[go_router] Refactor internal classes and methods #2317
Conversation
- Separate matching from redirection - Add RouteRedirector typedef - Add RouteMatcher class - Add RouteBuilder class - Add RouteConfiguration class - Rename and reorganize internal classes and libraries - Add todo comments
- Change name back to GoRouterRefreshStream - Update toString() methods for new naming - Make fields final - Add logging to parser - Add comments - add tests - Move function-scope to new library-scope _addRedirect function - import widgets instead of material where possible
} | ||
|
||
/// Adds the redirect to [redirects] if it is valid. | ||
/// Returns true if the redirect was processed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Returns true if the redirect was processed. |
name: null, | ||
// no name available at the top level |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think of moving comments to before the argument? Same comment for line 130.
name: null, | |
// no name available at the top level | |
// no name available at the top level | |
name: null, |
|
||
@override | ||
String toString() => | ||
super.toString() + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to double-check, is super.toString()
guaranteed to have some sort of trailing whitespace?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM but please make sure to check API docs for unexpected breaking changes before merging!
Co-authored-by: Loïc Sharma <737941+loic-sharma@users.noreply.github.com>
I diffed the API docs this branch and Technically, we are also exporting |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the direction this pr is going, but I am a bit concern about some of the class renaming and this can be a breaking change for developer who use the goroute- delegates directly.
export 'state.dart'; | ||
|
||
/// The route configuration for GoRouter configured by the app. | ||
class RouteConfiguration { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The properties in this class are only needed in gorouteinformationparser once we remove the namedLocation. I am a bit unsure whether we should introduce a new class that will probably be deprecated in the future
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The routeConfiguration field is marked @visibleForTesting
in RouterDelegate, so I don't consider this a new public API. The reason for making this a separate class is make it easier to change the configuration without updating all of the places where the routeConfiguration is being passed around. For example, we might want to deprecate topRedirect
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but at somepoint we won't need to pass it around.
We would need to expose this class if we expose the GoRouterDelegate, otherwise, developer won't be able to use GoRouterDelegate constructor directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filed an issue to remove this along with the namedLocation API: flutter/flutter#108139
/// The router delegate used by the go router. | ||
late final GoRouterDelegate routerDelegate; | ||
/// The route information parser used by [GoRouter]. | ||
// TODO(johnpryan): change type to RouteInformationParser |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel we will still need to expose the GoRoute- delegates if customers want to create their own delegates to use with the GoRouter- delegates
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class isn't currently part of the public API, but yes if we wanted to make it configurable as the part of the constructor we would have to export it:
import 'package:go_router/go_router.dart'
class CustomMatchListParser extends MatchListParser {
// ...
}
// ...
final _router = GoRouter(
builder: CustomMatchListBuilder(),
parser: CustomMatchListParser(),
matcher: CustomMatchListMatcher(),
redirector: CustomMatchListRedirector(),
routes: [
// ...
],
We could take it one step further and allow users to specify a custom implementation of RouteConfiguration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean unless we are never going to expose GoRouteInfromationParser/GoRouterDelegate, it doesn't make sense to change the type back to RouteInformationParser given that it is already exposed as GoRouteInformationParser. I think right now this package is in a weird state that some classes should have been exposed as public but don't, and it was too late to making it completely private because some other classes have exposed them as part of their APIs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I misunderstood your question. There was a discussion about this in a previous review: #2317 (comment)
Co-authored-by: chunhtai <47866232+chunhtai@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@@ -29,8 +29,8 @@ class GoRouterState { | |||
: subloc), | |||
assert((path ?? '').isEmpty == (fullpath ?? '').isEmpty); | |||
|
|||
// TODO(chunhtai): remove this once namedLocation is removed from go_router. | |||
final GoRouteInformationParser _delegate; | |||
// TODO(johnpryan): remove once namedLocation is removed from go_router. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe link this ? flutter/flutter#107729
@@ -64,12 +64,13 @@ class GoRouterState { | |||
|
|||
/// Get a location from route name and parameters. | |||
/// This is useful for redirecting to a named location. | |||
// TODO(johnpryan): deprecate namedLocation API |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This moves some things around to make things easier to change. The GoRouteInformationParser now returns a RouteMatchList object by delegating the matching to a RouteMatcher object. Once the initial matches are found, the parser processes redirects using an abstract RouteRedirector function. After redirecting, the parsing is done and the RouteMatchList is provided to GoRouterDelegate through setNewRoutePath, where it stores the current RouteMatchList.
Once the GoRouterDelegate updates its RouteMatchList state, it builds the widget tree by delegating to RouteBuilder. RouteBuilder is a new class that builds widget tree starting with the top-level Navigator all the way down to the active sub-route.
List of changes:
I didn't modify the tests too much, but this should make it possible to write more specific tests for matching, redirection, building, etc.
Pre-launch Checklist
dart format
.)[shared_preferences]
pubspec.yaml
with an appropriate new version according to the [pub versioning philosophy], or this PR is [exempt from version changes].CHANGELOG.md
to add a description of the change, [following repository CHANGELOG style].///
).