Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
chunhtai committed Dec 6, 2023
1 parent db16866 commit 109bdfc
Show file tree
Hide file tree
Showing 14 changed files with 308 additions and 278 deletions.
7 changes: 7 additions & 0 deletions packages/go_router/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 13.0.0

- Refactored `RouteMatchList` and imperative APIs.
- **BREAKING CHANGE**:
- RouteMatchList structure changed.
- Matching logic updated.

## 12.1.2

* Fixes an incorrect use of `extends` for Dart 3 compatibility.
Expand Down
148 changes: 79 additions & 69 deletions packages/go_router/lib/src/builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -105,22 +105,20 @@ class RouteBuilder {
// empty box until then.
return const SizedBox.shrink();
}
assert(
matchList.isError || !matchList.last.route.redirectOnly);
assert(matchList.isError || !matchList.last.route.redirectOnly);
return builderWithNav(
context,
_CustomNavigator(
navigatorKey: configuration.navigatorKey,
observers: observers,
navigatorRestorationId: restorationScopeId,
onPopPageWithRouteMatch: onPopPageWithRouteMatch,
matchList: matchList,
matches: matchList.matches,
configuration: configuration,
errorBuilder: errorBuilder,
errorPageBuilder: errorPageBuilder,
)
);
context,
_CustomNavigator(
navigatorKey: configuration.navigatorKey,
observers: observers,
navigatorRestorationId: restorationScopeId,
onPopPageWithRouteMatch: onPopPageWithRouteMatch,
matchList: matchList,
matches: matchList.matches,
configuration: configuration,
errorBuilder: errorBuilder,
errorPageBuilder: errorPageBuilder,
));
}
}

Expand Down Expand Up @@ -150,11 +148,10 @@ class _CustomNavigator extends StatefulWidget {

@override
State<StatefulWidget> createState() => _CustomNavigatorState();

}

class _CustomNavigatorState extends State<_CustomNavigator> {
late final HeroController _controller;
HeroController? _controller;
late Map<Page<Object?>, RouteMatchBase> _pageToRouteMatchBase;
final GoRouterStateRegistry _registry = GoRouterStateRegistry();
List<Page<Object?>>? _pages;
Expand All @@ -170,23 +167,30 @@ class _CustomNavigatorState extends State<_CustomNavigator> {
@override
void didChangeDependencies() {
super.didChangeDependencies();
/// Return a HeroController based on the app type.
if (isMaterialApp(context)) {
_controller = createMaterialHeroController();
} else if (isCupertinoApp(context)) {
_controller = createCupertinoHeroController();
} else {
_controller = HeroController();
// Return a HeroController based on the app type.
if (_controller == null) {
if (isMaterialApp(context)) {
_controller = createMaterialHeroController();
} else if (isCupertinoApp(context)) {
_controller = createCupertinoHeroController();
} else {
_controller = HeroController();
}
}
// This method can also be called if any of the page builders depend on
// the context. In this case, make sure _pages are rebuilt.
_pages = null;
}

void _updatePages(BuildContext context) {
assert(_pages == null);
final List<Page<Object?>> pages = <Page<Object?>>[];
final Map<Page<Object?>, RouteMatchBase> pageToRouteMatchBase = <Page<Object?>, RouteMatchBase>{};
final Map<Page<Object?>, GoRouterState> registry = <Page<Object?>, GoRouterState>{};
final Map<Page<Object?>, RouteMatchBase> pageToRouteMatchBase =
<Page<Object?>, RouteMatchBase>{};
final Map<Page<Object?>, GoRouterState> registry =
<Page<Object?>, GoRouterState>{};
if (widget.matchList.isError) {
pages.add(_buildErrorPage(context));
pages.add(_buildErrorPage(context, widget.matchList));
} else {
for (final RouteMatchBase match in widget.matches) {
final Page<Object?>? page = _buildPage(context, match);
Expand All @@ -206,6 +210,9 @@ class _CustomNavigatorState extends State<_CustomNavigator> {

Page<Object?>? _buildPage(BuildContext context, RouteMatchBase match) {
if (match is RouteMatch) {
if (match is ImperativeRouteMatch && match.matches.isError) {
return _buildErrorPage(context, match.matches);
}
return _buildPageForGoRoute(context, match);
}
if (match is ShellRouteMatch) {
Expand All @@ -214,12 +221,11 @@ class _CustomNavigatorState extends State<_CustomNavigator> {
throw GoError('unknown match type ${match.runtimeType}');
}



/// Builds a [Page] for [GoRoute]
Page<Object?>? _buildPageForGoRoute(BuildContext context, RouteMatch match) {
final GoRouterPageBuilder? pageBuilder = match.route.pageBuilder;
final GoRouterState state = match.buildState(widget.configuration, widget.matchList);
final GoRouterState state =
match.buildState(widget.configuration, widget.matchList);
if (pageBuilder != null) {
final Page<Object?> page = pageBuilder(context, state);
if (page is! NoOpPage) {
Expand All @@ -232,24 +238,27 @@ class _CustomNavigatorState extends State<_CustomNavigator> {
if (builder == null) {
return null;
}
return _buildPlatformAdapterPage(context, state, Builder(builder: (BuildContext context) {
return _buildPlatformAdapterPage(context, state,
Builder(builder: (BuildContext context) {
return builder(context, state);
}));
}

/// Builds a [Page] for [ShellRouteBase]
Page<Object?> _buildPageForShellRoute(
BuildContext context,
ShellRouteMatch match,
) {
final GoRouterState state = match.buildState(widget.configuration, widget.matchList);
BuildContext context,
ShellRouteMatch match,
) {
final GoRouterState state =
match.buildState(widget.configuration, widget.matchList);
final GlobalKey<NavigatorState> navigatorKey = match.navigatorKey;
final ShellRouteContext shellRouteContext = ShellRouteContext(
route: match.route,
routerState: state,
navigatorKey: navigatorKey,
routeMatchList: widget.matchList,
navigatorBuilder: (List<NavigatorObserver>? observers, String? restorationScopeId) {
navigatorBuilder:
(List<NavigatorObserver>? observers, String? restorationScopeId) {
return _CustomNavigator(
// The state needs to persist across rebuild.
key: GlobalObjectKey(navigatorKey.hashCode),
Expand All @@ -266,13 +275,15 @@ class _CustomNavigatorState extends State<_CustomNavigator> {
);
},
);
final Page<Object?>? page = match.route.buildPage(context, state, shellRouteContext);
final Page<Object?>? page =
match.route.buildPage(context, state, shellRouteContext);
if (page != null && page is! NoOpPage) {
return page;
}

// Return the result of the route's builder() or pageBuilder()
return _buildPlatformAdapterPage(context, state, Builder(builder: (BuildContext context) {
return _buildPlatformAdapterPage(context, state,
Builder(builder: (BuildContext context) {
return match.route.buildWidget(context, state, shellRouteContext)!;
}));
}
Expand Down Expand Up @@ -308,13 +319,13 @@ class _CustomNavigatorState extends State<_CustomNavigator> {
required String restorationId,
required Widget child,
}) =>
NoTransitionPage<void>(
name: name,
arguments: arguments,
key: key,
restorationId: restorationId,
child: child,
);
NoTransitionPage<void>(
name: name,
arguments: arguments,
key: key,
restorationId: restorationId,
child: child,
);
_errorBuilderForAppType =
(BuildContext c, GoRouterState s) => ErrorScreen(s.error);
}
Expand All @@ -326,10 +337,10 @@ class _CustomNavigatorState extends State<_CustomNavigator> {

/// builds the page based on app type, i.e. MaterialApp vs. CupertinoApp
Page<Object?> _buildPlatformAdapterPage(
BuildContext context,
GoRouterState state,
Widget child,
) {
BuildContext context,
GoRouterState state,
Widget child,
) {
// build the page based on app type
_cacheAppType(context);
return _pageBuilderForAppType!(
Expand All @@ -344,22 +355,22 @@ class _CustomNavigatorState extends State<_CustomNavigator> {
);
}

GoRouterState _buildErrorState() {
assert(widget.matchList.isError);
GoRouterState _buildErrorState(RouteMatchList matchList) {
assert(matchList.isError);
return GoRouterState(
widget.configuration,
uri: widget.matchList.uri,
matchedLocation: widget.matchList.uri.path,
fullPath: widget.matchList.fullPath,
pathParameters: widget.matchList.pathParameters,
error: widget.matchList.error,
pageKey: ValueKey<String>('${widget.matchList.uri}(error)'),
uri: matchList.uri,
matchedLocation: matchList.uri.path,
fullPath: matchList.fullPath,
pathParameters: matchList.pathParameters,
error: matchList.error,
pageKey: ValueKey<String>('${matchList.uri}(error)'),
);
}

/// Builds a an error page.
Page<void> _buildErrorPage(BuildContext context) {
final GoRouterState state = _buildErrorState();
Page<void> _buildErrorPage(BuildContext context, RouteMatchList matchList) {
final GoRouterState state = _buildErrorState(matchList);
assert(state.error != null);

// If the error page builder is provided, use that, otherwise, if the error
Expand All @@ -371,22 +382,21 @@ class _CustomNavigatorState extends State<_CustomNavigator> {
return widget.errorPageBuilder != null
? widget.errorPageBuilder!(context, state)
: _buildPlatformAdapterPage(
context,
state,
errorBuilder != null
? errorBuilder(context, state)
: _errorBuilderForAppType!(context, state),
);
context,
state,
errorBuilder != null
? errorBuilder(context, state)
: _errorBuilderForAppType!(context, state),
);
}

@override
void dispose() {
_controller.dispose();
_controller?.dispose();
super.dispose();
}

bool _handlePopPage(
Route<Object?> route, Object? result) {
bool _handlePopPage(Route<Object?> route, Object? result) {
final Page<Object?> page = route.settings as Page<Object?>;
final RouteMatchBase match = _pageToRouteMatchBase[page]!;
return widget.onPopPageWithRouteMatch(route, result, match);
Expand All @@ -401,7 +411,7 @@ class _CustomNavigatorState extends State<_CustomNavigator> {
return GoRouterStateRegistryScope(
registry: _registry,
child: HeroControllerScope(
controller: _controller,
controller: _controller!,
child: Builder(
builder: (BuildContext context) {
return Navigator(
Expand Down
10 changes: 5 additions & 5 deletions packages/go_router/lib/src/configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,8 @@ class RouteConfiguration {
final Uri uri = Uri.parse(canonicalUri(location));

final Map<String, String> pathParameters = <String, String>{};
final List<RouteMatchBase> matches = _getLocRouteMatches(uri, pathParameters);
final List<RouteMatchBase> matches =
_getLocRouteMatches(uri, pathParameters);

if (matches.isEmpty) {
return _errorRouteMatchList(
Expand Down Expand Up @@ -335,9 +336,6 @@ class RouteConfiguration {
rootNavigatorKey: navigatorKey,
route: route,
uri: uri,
remainingLocation: uri.path,
matchedLocation: '',
matchedPath: '',
pathParameters: pathParameters,
);
if (result.isNotEmpty) {
Expand Down Expand Up @@ -394,6 +392,7 @@ class RouteConfiguration {
}
return prevMatchList;
}

final List<RouteMatch> routeMatches = <RouteMatch>[];
prevMatchList.visitRouteMatches((RouteMatchBase match) {
if (match is RouteMatch) {
Expand Down Expand Up @@ -443,7 +442,8 @@ class RouteConfiguration {
final RouteMatch match = routeMatches[currentCheckIndex];
FutureOr<String?> processRouteRedirect(String? newLocation) =>
newLocation ??
_getRouteLevelRedirect(context, matchList, routeMatches, currentCheckIndex + 1);
_getRouteLevelRedirect(
context, matchList, routeMatches, currentCheckIndex + 1);
final GoRoute route = match.route;
FutureOr<String?> routeRedirectResult;
if (route.redirect != null) {
Expand Down
9 changes: 3 additions & 6 deletions packages/go_router/lib/src/delegate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList>
.whereType<GoRoute>()
.toList();
return _callOnExitStartsAt(exitingGoRoutes.length - 1,
context: navigatorContext, routes: exitingGoRoutes)
context: navigatorContext, routes: exitingGoRoutes)
.then<void>((bool exit) {
if (!exit) {
return SynchronousFuture<void>(null);
Expand All @@ -247,14 +247,12 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList>
}
final GoRoute goRoute = routes[index];
if (goRoute.onExit == null) {
return _callOnExitStartsAt(index - 1,
context: context, routes: routes);
return _callOnExitStartsAt(index - 1, context: context, routes: routes);
}

Future<bool> handleOnExitResult(bool exit) {
if (exit) {
return _callOnExitStartsAt(index - 1,
context: context, routes: routes);
return _callOnExitStartsAt(index - 1, context: context, routes: routes);
}
return SynchronousFuture<bool>(false);
}
Expand All @@ -268,7 +266,6 @@ class GoRouterDelegate extends RouterDelegate<RouteMatchList>

Future<void> _setCurrentConfiguration(RouteMatchList configuration) {
currentConfiguration = configuration;
print('configuration set to:\n$configuration');
notifyListeners();
return SynchronousFuture<void>(null);
}
Expand Down
Loading

0 comments on commit 109bdfc

Please sign in to comment.