Milad-Akarie / auto_route_library

Flutter route generator
MIT License
1.56k stars 394 forks source link

[Hero] not working as expected on [web] when `includePrefixMatches` is set to `true` #1670

Open a-h-mzd opened 1 year ago

a-h-mzd commented 1 year ago

Steps to reproduce:

  1. Create a simple app with two screens each containing a Hero widget with its transitionOnUserGestures set to true.
  2. Assign these routes to them:
    • /
    • /second
  3. Set includePrefixMatches to true
  4. Open the app and navigate to the second screen.
  5. Reload the page.
  6. Try to go back using a swipe gesture to see the issue.

Screen record

https://github.com/Milad-Akarie/auto_route_library/assets/42738288/ecb30a95-b4aa-4a96-a6bc-764dd63b4d9c

Versions:

flutter: 3.10.6 auto_route: 7.7.1 auto_route_generator: 7.2.0

Stack trace:

══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
The following assertion was thrown while handling a gesture:
Assertion failed:
packages/flutter/src/widgets/heroes.dart 477:12
box.hasSize && box.size.isFinite
is not true
When the exception was thrown, this was the stack:
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 288:49  throw_
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 29:3    assertFailed
packages/flutter/src/widgets/heroes.dart 477:30                               _boundingBoxFor
packages/flutter/src/widgets/heroes.dart 493:36                               get toHeroLocation
packages/flutter/src/widgets/heroes.dart 502:53                               get isValid
packages/flutter/src/widgets/heroes.dart 957:39                               [_startHeroTransition]
packages/flutter/src/widgets/heroes.dart 872:9                                [_maybeStartHeroTransition]
packages/flutter/src/widgets/heroes.dart 813:5                                didStartUserGesture
packages/flutter/src/widgets/navigator.dart 5187:17                           didStartUserGesture
packages/flutter/src/cupertino/route.dart 711:15                              new
packages/flutter/src/cupertino/route.dart 241:12                              _startPopGesture
packages/flutter/src/cupertino/route.dart 288:36                              <fn>
packages/flutter/src/cupertino/route.dart 624:54                              [_handleDragStart]
packages/flutter/src/gestures/monodrag.dart 497:45                            <fn>
packages/flutter/src/gestures/recognizer.dart 275:24                          invokeCallback
packages/flutter/src/gestures/monodrag.dart 497:7                             [_checkStart]
packages/flutter/src/gestures/monodrag.dart 420:7                             acceptGesture
packages/flutter/src/gestures/arena.dart 268:10                               [_resolveByDefault]
packages/flutter/src/gestures/arena.dart 248:31                               callback
dart-sdk/lib/async/schedule_microtask.dart 40:11                              _microtaskLoop
dart-sdk/lib/async/schedule_microtask.dart 49:5                               _startMicrotaskLoop
dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 177:15           <fn>
Handler: "onStart"
Recognizer:
  HorizontalDragGestureRecognizer#e42fb
════════════════════════════════════════════════════════════════════════════════════════════════════
Milad-Akarie commented 1 year ago

Hey @a-h-mzd does this work with includePrefixmatches set to false?

a-h-mzd commented 1 year ago

Hey @Milad-Akarie. in that case there are no screens behind the current one because we have just reloaded the screen. Am I right?

Milad-Akarie commented 1 year ago

@a-h-mzd You are right, so in your case there are actual a page behind active route but the transaction not working?

a-h-mzd commented 1 year ago

@Milad-Akarie Correct. Also, interactivity is lost if you try to pop using a gesture. You can check the stack trace and the video to see this.

a-h-mzd commented 1 year ago

@Milad-Akarie I can send you a minimum working project so you can see the error for yourself if this would help.

Milad-Akarie commented 1 year ago

@a-h-mzd that would be great, I've noticed that you're initiating your router inside of the build method which can cause a lot of issues, remove it from the build method first then see if you still get issues.

Milad-Akarie commented 1 year ago
class MyApp extends StatelessWidget {
   MyApp();

  final _rootRouter = RootRouter();

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: _rootRouter.config(),
    );
  }
a-h-mzd commented 1 year ago

I'm initiating it this way only in this example project and not in the actual project that I'm working on. And I can tell you that the issue persists.

Milad-Akarie commented 1 year ago

I see, I'm waiting for minimum project that reproduces this issue.

a-h-mzd commented 1 year ago

main.dart

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      title: 'Flutter Test',
      theme: ThemeData.light(),
      routerConfig: AppRouter().config(
        includePrefixMatches: true,
      ),
    );
  }
}

page1.dart

@RoutePage()
class Page1 extends StatelessWidget {
  const Page1({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Hero(
          tag: #tag,
          transitionOnUserGestures: true,
          child: FloatingActionButton(
            heroTag: null,
            onPressed: () => context.navigateTo(const Route2()),
            child: const Icon(Icons.arrow_forward_ios_rounded),
          ),
        ),
      ),
    );
  }
}

page2.dart

@RoutePage()
class Page2 extends StatelessWidget {
  const Page2({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Hero(
          tag: #tag,
          transitionOnUserGestures: true,
          child: FloatingActionButton(
            heroTag: null,
            onPressed: () => context.back(),
            child: const Icon(Icons.arrow_back_ios_new_rounded),
          ),
        ),
      ),
    );
  }
}

router.dart

@AutoRouterConfig()
final class AppRouter extends $AppRouter {
  @override
  List<AutoRoute> get routes {
    return <AutoRoute>[
      AutoRoute(
        path: '/',
        page: Route1.page,
      ),
      AutoRoute(
        path: '/second',
        page: Route2.page,
      ),
    ];
  }
}
Milad-Akarie commented 1 year ago

@a-h-mzd what does this hashtag mean? tag: #tag. this's new to me

Milad-Akarie commented 1 year ago

@a-h-mzd When working for the web you should use context.router.back() instead of router.pop() or the shortcut context.back() because that's the same as clicking the browser's back button, on the other hand popping routes will add duplicate entries and complicate things on the web.

also, consider using context.router.navigate instead of context.router.push on the web so you avoid duplicate entries

shortcut: context.navigateTo(route)

try again with these suggestions and let me know what you get

a-h-mzd commented 1 year ago

@Milad-Akarie the hashtag is how you'd define a Symbol. Since the hero tag can be anything I prefer using a hashtag to create a symbol for it.

a-h-mzd commented 1 year ago

@Milad-Akarie Thank you for the great advice. I updated the minimum project that reproduces this issue. Should I use those methods only on the web or are they safe to use also on other platforms? FYI the issue persists!

Milad-Akarie commented 1 year ago

ya they're preferred to be used in Web Apps, especially the back() method, what I also did is remove the initializing of the route from the build method.

class MyApp extends StatelessWidget {
    MyApp({super.key});
  final router = TestAppRouter();
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      title: 'Flutter Test',
      theme: ThemeData.light(),
      routerConfig: router.config(
        includePrefixMatches: true,
      ),
    );
  }
}

I'm not getting any errors any more, everything works nicely

Milad-Akarie commented 1 year ago

https://github.com/Milad-Akarie/auto_route_library/assets/55059449/a59d04e4-8408-48a4-8213-59a2330ca528

a-h-mzd commented 1 year ago

Are you sure? Because I still get the error.

https://github.com/Milad-Akarie/auto_route_library/assets/42738288/9c55b033-f24e-43f8-8637-69a1d5c3ecf6

Make sure to use gestures to go back not click on the button.

a-h-mzd commented 1 year ago

@Milad-Akarie, Is there anything else I can provide you with?

github-actions[bot] commented 11 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions

a-h-mzd commented 11 months ago

Commenting to prevent issue from getting closed.

github-actions[bot] commented 10 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions

a-h-mzd commented 10 months ago

Commenting to remove the no-issue-activity tag.

github-actions[bot] commented 9 months ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions