slovnicki / beamer

A routing package built on top of Router and Navigator's pages API, supporting arbitrary nested navigation, guards and more.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Feature] Button - Multiple clicks on the same button with beamToNamed leads to "Page not found"

karvulf opened this issue · comments

Is your feature request related to a problem? Please describe.

I had troubles using beamToNamed when adding a route to the current path on a button.
E.g. I have a button that has

...
void _handlePressed() {
  context.beamToNamed('test');
}
...

When tapping the button multiple times, it can happen that beamToNamed will be called more than one time. To reproduce my problem easier, you could also just call beamToNamed two times like this

...
void _handlePressed() {
  context.beamToNamed('test');
  context.beamToNamed('test');
}
...

Now I would start a navigation to a path that is not defined in my pathPatterns, e.g. the double call could lead to /screen-a/test/test but I only defined the path for /screen-a/test.
If I could somehow prevent beaming to the wrong route (/screen-a/test/test), then I shouldn't be worry about multiple clicks on the same button.
I know, I could also define the absolute path to ensure that I beam to the correct route. But sometimes it's easier just not to do that to prevent really long paths defined in beamToNamed and it makes functions also reusable.


Describe the solution you'd like
What I really would like is to add a flag to beamToNamed to say that I want to prevent beaming to the same place again, when it was called in a specific timespan.
E.g. I could have a timeStamp that is always updated when beaming to a new page. Then before I beam to the next page, I check if the route is still the same and if so, I could check the last timeStamp if the difference is big enough to pass the navigation.

Like this
const _maxDuration = Duration(milliseconds: 100);
String _lastUri = '';
DateTime _lastUriTimestamp = DateTime.now();

void beamToNamedUnique(String uri, {Object? data}) {
  final now = DateTime.now();
  if (uri != _lastUri ||
      now.subtract(_maxDuration).compareTo(_lastUriTimestamp) > 0) {
    this.beamToNamed(uri, data: data);
  }
  _lastUri = uri;
  _lastUriTimestamp = now;
}

Of course, I would like to have this logic in beamToNamed with a flag like duplicatesTimespan.

  void beamToNamed(
    String uri, {
    Object? routeState,
    Object? data,
    String? popToNamed,
    TransitionDelegate? transitionDelegate,
    bool beamBackOnPop = false,
    bool popBeamLocationOnPop = false,
    bool stacked = true,
    bool replaceRouteInformation = false,
   DateTime? duplicatesTimespan,
  }) {
...

And if the flag is set, the logic from above could be used where _maxDuration could be duplicatesTimespan.


Additional context

I think this can be a general problem when beaming to a page by pressing a button and the user is fast enough to press it multiple times. Maybe I also missed something and I already can prevent that.