felangel / flow_builder

Flutter Flows made easy! A Flutter package which simplifies navigation flows with a flexible, declarative API.
https://pub.dev/packages/flow_builder
MIT License
389 stars 63 forks source link

Add API to detect back navigation #62

Open omartinma opened 2 years ago

omartinma commented 2 years ago

Is your feature request related to a problem? Please describe. Let's say we have a list of items. Clicking on an item will navigate to the details of this item. Normally to handle that we will have on the state of our flow with a property Item? so if the item is null we know we should be on the list page, else we should be on the details page.

The problem comes if you try to navigate back from details to the list page again. Typically we can handle that just overriding the back button or using will pop scope.

Describe the solution you'd like I would like to have a new API that informs whether the user pops a page. Then we have 2 choices for updating the state:

  1. I will need also maybe the page that is popping and I will manually check what I need to do, in this case clear the item of the state.
  2. Have a similar approach to the ReplayBloc with the undo.

I think number 1 should be easier to develop in the flow builder package, but developers will need to handle these cases anyway. Number 2 seems more complicated but developers will not need to do anything.

Additional context This is an issue If you are using external state management, in my case, bloc.

alestiago commented 1 year ago

You can use a NavigationObserver to detect back pops, this may solve (1).

For example, with the current API one can detect back navigation as follows:

  @override
  Widget build(BuildContext context) {
    return FlowBuilder<MyState>(
      state: context.watch<MyBloc>().state,
      onGeneratePages: onGeneratePages,
      observers: [
        _PopObserver(
          onPop: () => context.read<MyBloc>().add(const Popped()),
        )
      ],
    );
  }
}

class _PopObserver extends NavigatorObserver {
  _PopObserver({
    this.onPop,
  });

  final VoidCallback? onPop;

  @override
  void didPop(Route route, Route? previousRoute) {
    super.didPop(route, previousRoute);
    onPop?.call();
  }
}

However, I do believe FlowBuilder should expose a better API for detecting back navigation. One of the possible APIs could be adding an onChangedPages to FlowBuilder. I would expect onChangedPages to be called whenever the stack of pages changes.

Something as:

@override
  Widget build(BuildContext context) {
    return FlowBuilder<MyBlocState>(
      state: context.watch<MyBloc>().state,
      onChangedPages: (List<Page<void>> previous,  List<Page<void>> current) {}
      onGeneratePages: onGeneratePages,
    );
  }

So, one could detect a page has been poped by, for example, checking that the last element has changed.

Another alternative would be to provide a FlowNavigatorObserver or similar.

felangel commented 1 year ago

Hi @alestiago 👋

onDidPop was added as part of #99. Can you take a look and let me know if that satisfies your requirements?