-
Notifications
You must be signed in to change notification settings - Fork 6k
Let the framework toggle between single- and multi-entry histories #26164
Conversation
38c7c79 to
7d2a0e2
Compare
chunhtai
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot to submit the review comments. I think we should still have some way to warn user about this. Also I think letting people switching back and forth may not be ideal. My original intention is to let people switch to multi and drop all the single updates. The rational behind this is user will have to implement additional code path in order to send multi updates.
| ); | ||
| return false; | ||
| } | ||
| case 'selectMultiEntryHistory': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
who is going to send the selectMultiEntryHistory and selectSingleEntryHistory?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See flutter/flutter#82594 for what I had in mind to call this.
Basically nobody would call selectMultiEntryHistory by and the other one would be called by the Navigator code during initState if it's in the single-history mode.
| await _useMultiEntryBrowserHistory(); | ||
| return true; | ||
| case 'selectSingleEntryHistory': | ||
| await _useSingleEntryBrowserHistory(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure we want to let user do this without knowing that they are switching in between the multi/ single browser history. If they are doing this, we may as well don't touch the browser history since it will likely be in a broken state.
#edit not broken per say, but it will be hard to predict what the back button or forward button will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well the user would never do this, it's an API. Unless you mean the developer? The developer would only do this specifically in order to switch between the different modes.
I'm happy to change this further, I don't have a strong opinion about what should do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry i meant the developer. I think the requirement was as the following when i made the change: The browser history favors the Router. If it has ever received the update from the Router, it should stay mult entry. If it receives navigator update after that, it should warn the developer and drop the update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah but I don't know that we can do that. Consider an app that switches between entirely different trees of widgets based on some user configuration. In one mode it uses MaterialApp.router, in another CupertinoApp, in another in just has a hard-coded Navigator, in another it has an old-style MaterialApp. Flutter's design implies that switches widgets like this is always safe and idempotent; remove the widget tree, bring in a new one, and it'll just work. But if we make the engine stateful like this, then that's no longer true (worse, it's no longer true but only for web).
Now, with this PR and the one I mentioned above, it's still not perfect, because we never explicitly switch back to multiEntry mode after switching to singleEntry mode, and maybe we should work on that also, but at least it's less bad in that at least the app doesn't crash when you do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that is a valid use case.
the original issue I faced when i made this change was people nesting MaterialApp with in another MaterialApp.router. In this case, the browser will be switching back and forth within one frame. I guess there is no perfect way to deal with this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It feels like there should be a singleton on the framework side does this, and by default only the root material app hook on to the singleton, if user want to do something fancy, they can disable the root material app from doing this and hook their own router/navigator to do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There might not be one "root" MaterialApp. Consider an app like this:
runApp(Column(children: [MaterialApp.router(...), MaterialApp.router(...), ]));
I don't really see how a singleton could help there. How would the widgets know which one should win?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know how we should define in this example. The reason i think a singleton may help is at least only one of them will win instead of both trying to report routeinformation. The later may makes browser button unusable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could make the singleton (accessible from the binding) support multiple clients that it could interleave. Then all the various APIs that talk to the browser today could talk through that singleton, and we wouldn't have any issues with multiple widgets, swapping widgets, etc.
Should I file a bug with that suggestion?
This seems somewhat orthogonal to this PR though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure how we can make them interleave in a meaningful way. To me, if there are more than one client, we should only allow one of them to report. If there are multiple clients that want to report in the same frame, it is likely a developer error. That being said, I remember there was an issue to add an API to disable MaterialApp from reporting route change. we should probably do that as well.
Yes, can you file a bug for this?
a15cbff to
477e0aa
Compare
|
Yay, the tests passed. |
chunhtai
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, although there is still some open question on how framework should handle nested materialApp, but that is parallel to this pr
|
Filed flutter/flutter#83044 to track the singleton idea. |
Pre-launch Checklist
writing and running engine tests.
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.