redirect method

FutureOr<RouteMatchList> redirect(
  1. BuildContext context,
  2. FutureOr<RouteMatchList> prevMatchListFuture, {
  3. required List<RouteMatchList> redirectHistory,
})

Processes redirects by returning a new RouteMatchList representing the new location.

Implementation

FutureOr<RouteMatchList> redirect(
    BuildContext context, FutureOr<RouteMatchList> prevMatchListFuture,
    {required List<RouteMatchList> redirectHistory}) {
  FutureOr<RouteMatchList> processRedirect(RouteMatchList prevMatchList) {
    final String prevLocation = prevMatchList.uri.toString();
    FutureOr<RouteMatchList> processTopLevelRedirect(
        String? topRedirectLocation) {
      if (topRedirectLocation != null &&
          topRedirectLocation != prevLocation) {
        final RouteMatchList newMatch = _getNewMatches(
          topRedirectLocation,
          prevMatchList.uri,
          redirectHistory,
        );
        if (newMatch.isError) {
          return newMatch;
        }
        return redirect(
          context,
          newMatch,
          redirectHistory: redirectHistory,
        );
      }

      FutureOr<RouteMatchList> processRouteLevelRedirect(
          String? routeRedirectLocation) {
        if (routeRedirectLocation != null &&
            routeRedirectLocation != prevLocation) {
          final RouteMatchList newMatch = _getNewMatches(
            routeRedirectLocation,
            prevMatchList.uri,
            redirectHistory,
          );

          if (newMatch.isError) {
            return newMatch;
          }
          return redirect(
            context,
            newMatch,
            redirectHistory: redirectHistory,
          );
        }
        return prevMatchList;
      }

      final List<RouteMatchBase> routeMatches = <RouteMatchBase>[];
      prevMatchList.visitRouteMatches((RouteMatchBase match) {
        if (match.route.redirect != null) {
          routeMatches.add(match);
        }
        return true;
      });
      final FutureOr<String?> routeLevelRedirectResult =
          _getRouteLevelRedirect(context, prevMatchList, routeMatches, 0);

      if (routeLevelRedirectResult is String?) {
        return processRouteLevelRedirect(routeLevelRedirectResult);
      }
      return routeLevelRedirectResult
          .then<RouteMatchList>(processRouteLevelRedirect);
    }

    redirectHistory.add(prevMatchList);
    // Check for top-level redirect
    final FutureOr<String?> topRedirectResult = _routingConfig.value.redirect(
      context,
      buildTopLevelGoRouterState(prevMatchList),
    );

    if (topRedirectResult is String?) {
      return processTopLevelRedirect(topRedirectResult);
    }
    return topRedirectResult.then<RouteMatchList>(processTopLevelRedirect);
  }

  if (prevMatchListFuture is RouteMatchList) {
    return processRedirect(prevMatchListFuture);
  }
  return prevMatchListFuture.then<RouteMatchList>(processRedirect);
}