JaspervanRiet / duck_router

A Flutter router with intents
MIT License
4 stars 3 forks source link

popUntil from nested router to root router #16

Closed DelcoigneYves closed 2 months ago

DelcoigneYves commented 3 months ago

Hi there!

Is it, or should it be possible to call popUntil from a nested Location, and make it pop to a root Location?

I've been trying to do this, but it looks like it only pops the pages in the nested Navigator (until no pages are in the stack anymore).

DelcoigneYves commented 3 months ago

I've been investigating this a bit more, and it should be relatively easy to support this.

First, an observation that I would like to see confirmed: is it correct to state that only 1 level of nested navigation is supported? At least that is my understanding of the implementation of the DuckShellState.

Secondly, this can be supported by editing the DuckShellState,popUntil method with this content:

bool popUntil(Location location) {
    final navigatorKey = _navigatorKeys[_currentIndex];
    if (navigatorKey.currentState == null) {
      return false;
    }

    final routerDelegate = _routerDelegates[_currentIndex];
    final hasLocation = routerDelegate.currentConfiguration.locations.contains(location);
    if (!hasLocation) {
      return false;
    }

    navigatorKey.currentState?.popUntil((route) {
      return route.settings.name == location.path;
    });

    return true;
  }

And the DuckRouterDelegate.popUntil method like this:

void popUntil(Location location) {
    final currentLocation = currentConfiguration.locations.last;

    if (currentLocation is StatefulLocation) {
      /// Pop inside the stateful child location as long as that's possible.
      /// Else we will pop the whole route.
      if (currentLocation.state.currentRouterDelegate.currentConfiguration
              .locations.length >
          1) {
        final result = currentLocation.state.popUntil(location);
        if (result) {
          return;
        }
      }
    }

    NavigatorState? state;
    if (navigatorKey.currentState?.canPop() ?? false) {
      state = navigatorKey.currentState;
    }
    state?.popUntil((route) {
      return route.settings.name == location.path;
    });
  }
}
JaspervanRiet commented 2 months ago

@DelcoigneYves This does make sense to me, would you like to make a PR?

DelcoigneYves commented 2 months ago

I'll check tomorrow for this, as the tests will then also need an update