Skip to content

Conversation

@miquelbeltran
Copy link
Member

@miquelbeltran miquelbeltran commented Dec 22, 2022

Migration of veggieseaons to go_router.

Applying the same solution using ShellRoute as in #1437

  • Uses ShellRoute to handle navigation within a CupertinoTabBar
  • The GoRouter is implemented with state restoration in mind. The widget test for state restoration is untouched so all the state restoration that worked before still does.
  • The detail screen route is always a subroute of the path that opened it. For example, opening details for item 1 from /list goes to /list/details/1, opening details for the same item from favorites is /favorites/details/1, etc. This warranties that the navigation stack is always preserved when restoring the app.
  • Trying to use push did not work here, like pushing /details/1 from /list, as the navigation stack was lost during restoration. This could be due to a limitation in the go_router package. The previous implementation used restorablePush which does not exist on go_router.

Pre-launch Checklist

  • I read the Flutter Style Guide recently, and have followed its advice.
  • I signed the CLA.
  • I read the Contributors Guide.
  • I updated/added relevant documentation (doc comments with ///).
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-devrel channel on Discord.

@miquelbeltran
Copy link
Member Author

@domesticmouse @johnpryan I'm having problems with the 'restoration smoke test' in the veggieseasons app when using go_router, part of the restoration tests work, but some don't. For example, the issue I am having is that the scroll position is not being restored when the route is restored, but seems that route restoration works as I am able to restore a route to a details screen.

Could you do a review on the current PR code and see if you can find anything that I may have missed?

Doing a bit of research, I've found this issue: flutter/flutter#99124 and this PR here: flutter/packages#2650 could this be related as well?

},
debugLogDiagnostics: true,
routes: [
ShellRoute(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a ShellRoute to present the contents for the navigation tabs.

final index = _getSelectedIndex(GoRouter.of(context).location);
return RestorationScope(
restorationId: restorationId,
child: CupertinoTabScaffold(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CupertinoTabScaffold is gone, and is replaced by a CupertinoPageScaffold that contains the ShellRoute child and the CupertinoTabBar instead.

builder: (context, state, child) {
return HomeScreen(
restorationId: 'home',
child: child,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pass the ShellRoute child to the HomeScreen, will be displayed inside the CupertinoTabScaffold

@miquelbeltran
Copy link
Member Author

After a lot of trial and error, I think that GoRouter is the main cause on why the state of the screens is not correctly restored, I have created a new issue on the Flutter repo with all the info I could collect as well as widget tests that can reproduce the issue: flutter/flutter#117683

My conclusion is that simply put, GoRouter doesn't restore the state of the screens it creates inside its router configuration, and I fail to see what is needed to be done for that to work. I couldn't find any examples or documentation about this, so I am following up, and I'll try to update any relevant docs.

@domesticmouse
Copy link
Contributor

@johnpryan love to get your eyes on this

@domesticmouse domesticmouse changed the title WIP migrate veggieseasons to go_router WIP migrate veggieseasons to go_router Feb 6, 2023
@domesticmouse
Copy link
Contributor

@johnpryan PTAL

@miquelbeltran
Copy link
Member Author

miquelbeltran commented Feb 20, 2023

According to the responses in flutter/flutter#117683 (comment) this should work with a combination of using pageBuilder instead of builder and having a restoration id on the MaterialPage/CupertinoPage widget.

I will have a look and retake this

@domesticmouse
Copy link
Contributor

Looks like we have some lint fixes required. dart fix --apply?

@miquelbeltran
Copy link
Member Author

Yes, I am still fixing the unit tests. Part of the restoration tests are working, except for the details screen.

The problem is with the go_router push function. Previously, the code used restorablePush from the Navigator API to open the details screen, however looks like go_router does not implement something like that, and I need to find an alternative for this.

Otherwise, we are getting some progress here.

@domesticmouse
Copy link
Contributor

Cool, ping me when this is ready for review. Thanks!

@miquelbeltran miquelbeltran changed the title WIP migrate veggieseasons to go_router Migrate veggieseasons to go_router Feb 21, 2023
Comment on lines +59 to +60
final _rootNavigatorKey = GlobalKey<NavigatorState>();
final _shellNavigatorKey = GlobalKey<NavigatorState>();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Different navigator key helps to open the detail pages inside or outside the shell navigator as a top modal screen

);
}

GoRoute _buildDetailsRoute() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The details route is shared between the /list, /favorites and /search paths, but works exactly the same


import 'package:flutter/cupertino.dart';

class FadeTransitionPage<T> extends Page<T> {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, maybe CustomTransitionPage needs add support for the restorationId, but this LGTM for now.

return GestureDetector(
onTap: () => DetailsScreen.show(Navigator.of(context), veggie.id),
onTap: () {
context.go('${GoRouter.of(context).location}/details/${veggie.id}');
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allows to dynamically call this from either /favorites or /search, and builds /favorites/details/1 or /search/details/1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, go_router doesn't have support for relative routes (flutter/flutter#108177), it might be a good idea to add a comment here to explain what this line is doing.

@miquelbeltran miquelbeltran marked this pull request as ready for review February 21, 2023 13:54
@miquelbeltran
Copy link
Member Author

@domesticmouse ready for review now, I updated the PR description with my implementation details

Copy link
Contributor

@domesticmouse domesticmouse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@domesticmouse
Copy link
Contributor

PTAL @johnpryan

Copy link
Contributor

@johnpryan johnpryan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM overall, but the fade transitions aren't working for me.

pageBuilder: (context, state) {
return FadeTransitionPage(
restorationId: 'route.list',
child: Builder(builder: (context) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious, why are you using a Builder for these routes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, they don't seem to be necessary here!

GoRoute(
path: '/list',
pageBuilder: (context, state) {
return FadeTransitionPage(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not seeing a fade transition when I tap on destinations in the bottom navigation bar - is that what this is supposed to do?

Copy link
Member Author

@miquelbeltran miquelbeltran Feb 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edit: All good now! Turns out I had to pass the state.pageKey to the FadeTransitionPage in order to work.


import 'package:flutter/cupertino.dart';

class FadeTransitionPage<T> extends Page<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, maybe CustomTransitionPage needs add support for the restorationId, but this LGTM for now.

return GestureDetector(
onTap: () => DetailsScreen.show(Navigator.of(context), veggie.id),
onTap: () {
context.go('${GoRouter.of(context).location}/details/${veggie.id}');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, go_router doesn't have support for relative routes (flutter/flutter#108177), it might be a good idea to add a comment here to explain what this line is doing.

@miquelbeltran
Copy link
Member Author

Screencast.from.23.02.2023.15.05.40.webm

FYI the transition animation is now fixed.

Copy link
Contributor

@johnpryan johnpryan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - the CI failure looks unrelated to this change.

@domesticmouse
Copy link
Contributor

LGTM - the CI failure looks unrelated to this change.

There's an open bug tracking that failure, I don't know how to fix it.

@domesticmouse
Copy link
Contributor

@miquelbeltran land when you are ready

@miquelbeltran miquelbeltran merged commit 8c06626 into flutter:main Feb 24, 2023
@miquelbeltran miquelbeltran deleted the mb_veggieseasons_gorouter branch February 24, 2023 07:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants