pathSegmentPop static method

bool pathSegmentPop(
  1. BuildContext context,
  2. BeamerDelegate delegate,
  3. RouteInformationSerializable state,
  4. BeamPage poppedPage,
)

The default pop behavior for BeamPage.

Pops the last path segment from URI and calls BeamerDelegate.update.

Implementation

static bool pathSegmentPop(
  BuildContext context,
  BeamerDelegate delegate,
  RouteInformationSerializable state,
  BeamPage poppedPage,
) {
  if (!delegate.navigator.canPop()) {
    return false;
  }

  // take the data in case we remove the BeamLocation from history
  // and generate a new one (but the same).
  final data = delegate.currentBeamLocation.data;

  // Take the history element that is being popped and the one before
  // as they will be compared later on to fine-tune the pop experience.
  final poppedHistoryElement = delegate.removeLastHistoryElement()!;
  final previousHistoryElement = delegate.beamingHistory.isNotEmpty
      ? delegate.beamingHistory.last.history.last
      : null;

  // Convert both to Uri as their path and query will be compared.
  final poppedUri = poppedHistoryElement.routeInformation.uri;
  final previousUri = previousHistoryElement != null
      ? previousHistoryElement.routeInformation.uri
      : Uri.parse(delegate.initialPath);

  final poppedPathSegments = poppedUri.pathSegments;
  final poppedQueryParameters = poppedUri.queryParameters;

  // Pop path is obtained via removing the last path segment from path
  // that is being popped.
  final popPathSegments = List.from(poppedPathSegments)..removeLast();
  final popPath = '/' + popPathSegments.join('/');
  final popUri = Uri(
    path: popPath,
    queryParameters: poppedPage.keepQueryOnPop
        ? poppedQueryParameters.isEmpty
            ? null
            : poppedQueryParameters
        : (popPath == previousUri.path)
            ? previousUri.queryParameters.isEmpty
                ? null
                : previousUri.queryParameters
            : null,
  );

  // We need the route information from the route we are trying to pop to.
  //
  // Remove the last history element if it's the same as the path
  // we're trying to pop to, because `update` will add it to history.
  // This is `false` in case we deep-linked.
  //
  // Otherwise, find the route information with popPath in history.
  RouteInformation? lastRouteInformation;
  if (popPath == previousUri.path) {
    lastRouteInformation =
        delegate.removeLastHistoryElement()?.routeInformation;
  } else {
    // find the last
    var found = false;
    for (var beamLocation in delegate.beamingHistory.reversed) {
      if (found) {
        break;
      }
      for (var historyElement in beamLocation.history.reversed) {
        final uri = historyElement.routeInformation.uri;
        if (uri.path == popPath) {
          lastRouteInformation = historyElement.routeInformation;
          found = true;
          break;
        }
      }
    }
  }

  delegate.update(
    configuration: delegate.configuration.copyWith(
      uri: popUri,
      state: lastRouteInformation?.state,
    ),
    data: data,
  );

  return true;
}