setNewRoutePath method
For use by the Router architecture as part of the RouterDelegate.
Implementation
// This class avoids using async to make sure the route is processed
// synchronously if possible.
@override
Future<void> setNewRoutePath(RouteMatchList configuration) {
if (currentConfiguration == configuration) {
return SynchronousFuture<void>(null);
}
assert(configuration.isNotEmpty || configuration.isError);
final BuildContext? navigatorContext = navigatorKey.currentContext;
// If navigator is not built or disposed, the GoRoute.onExit is irrelevant.
if (navigatorContext != null) {
final List<RouteMatch> currentGoRouteMatches = <RouteMatch>[];
currentConfiguration.visitRouteMatches((RouteMatchBase match) {
if (match is RouteMatch) {
currentGoRouteMatches.add(match);
}
return true;
});
final List<RouteMatch> newGoRouteMatches = <RouteMatch>[];
configuration.visitRouteMatches((RouteMatchBase match) {
if (match is RouteMatch) {
newGoRouteMatches.add(match);
}
return true;
});
final int compareUntil = math.min(
currentGoRouteMatches.length,
newGoRouteMatches.length,
);
int indexOfFirstDiff = 0;
for (; indexOfFirstDiff < compareUntil; indexOfFirstDiff++) {
if (currentGoRouteMatches[indexOfFirstDiff] !=
newGoRouteMatches[indexOfFirstDiff]) {
break;
}
}
if (indexOfFirstDiff < currentGoRouteMatches.length) {
final List<RouteMatch> exitingMatches =
currentGoRouteMatches.sublist(indexOfFirstDiff).toList();
return _callOnExitStartsAt(
exitingMatches.length - 1,
context: navigatorContext,
matches: exitingMatches,
).then<void>((bool exit) {
if (!exit) {
return SynchronousFuture<void>(null);
}
return _setCurrentConfiguration(configuration);
});
}
}
return _setCurrentConfiguration(configuration);
}