dvNavigator2Routes function

List<DVNavigatorRoute> dvNavigator2Routes(
  1. List<RouteBase> routes, {
  2. String at = '/',
  3. ValueChanged<Uri>? onLocationChanged,
})

For Navigator 2.0: every one of Dartvel's routes, mounted at at, as entries for the app's own route table -- spread them in beside its own.

Each entry builds the same page, keyed by the mount, that runs Dartvel's whole route table: moving between two Dartvel locations keeps that page and its state, and Dartvel's guards, parameters, query and back stack behave as in a Dartvel app. Under a prefix, a final <at>/** entry gives an unknown path under the mount Dartvel's not-found page rather than the app's. When somebody navigates inside Dartvel, the new location, under the mount, is handed to onLocationChanged so the delegate keeps the address bar in step.

Implementation

List<DVNavigatorRoute> dvNavigator2Routes(
  List<RouteBase> routes, {
  String at = '/',
  ValueChanged<Uri>? onLocationChanged,
}) {
  Page<Object?> hostedPage(Uri location) {
    final String path = location.path.isEmpty ? '/' : location.path;
    final String inner = at == '/'
        ? path
        : path == at
            ? '/'
            : path.startsWith('$at/')
                ? path.substring(at.length)
                : path;
    return MaterialPage<Object?>(
      key: ValueKey<String>('dartvel:$at'),
      name: location.toString(),
      child: DVHostedPage(
        location: location.replace(path: inner).toString(),
        routes: routes,
        at: at,
        onLocationChanged: onLocationChanged,
      ),
    );
  }

  return <DVNavigatorRoute>[
    for (final String pattern in dvRoutePaths(routes))
      DVNavigatorRoute(dvHostedPath(pattern, at: at), hostedPage),
    if (at != '/') DVNavigatorRoute('$at/**', hostedPage),
  ];
}