-
-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Proposal] Add Routing Support #41
Comments
Regarding nested routes. Would such thing as below be possible? It feels more inline with routes being the representation of state, where you don't have to explicitly push any new routes onto the stack and all the routes in the Navigator have corresponding pages. class AppRouting extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FlowBuilder<AuthState>(
state: context.watch<AuthBloc>().state,
onGeneratePages: (AuthState state, List<Page> pages) {
switch (state) {
case AuthState.uninitialized:
return [Splash.page()];
case AuthState.unauthenticated:
case AuthState.signInInProgress:
return [
Login.page(),
if (state == AuthState.signInInProgress) SignInRouting.page(),
];
case AuthState.authenticated:
return [Home.page()];
}
});
}
}
enum AuthState {
uninitialized,
unauthenticated,
signInInProgress,
authenticated
}
class SignInRouting extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FlowBuilder<SignInState>(
state: context.watch<SignInBloc>().state,
onGeneratePages: (SignInState state, List<Page> pages) {
switch (state) {
case SignInState.step1:
return [SignInStep1.page()];
case SignInState.step2:
return [SignInStep2.page()];
case SignInState.verify:
return [SignInVerify.page()];
}
});
}
}
enum SignInState {
step1,
step2,
verify,
} Of course when using enums like class AppRouting extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FlowBuilder<AppState>(
state: context.watch<AppState>().state,
onGeneratePages: (AppState state, List<Page> pages) {
switch (state.authState) {
case AuthState.uninitialized:
return [Splash.page()];
case AuthState.unauthenticated:
return [
Login.page(),
if (state.signState == SignState.signIn)
SignInRouting.page(),
if (state.signState == SignState.signUp)
SignUpRouting.page(),
];
case AuthState.authenticated:
return [Home.page()];
}
});
}
}
class AppState {
AppState(this.authState, this.signState);
final AuthState authState;
final SignState signState;
}
enum SignState {
signIn,
signUp,
}
enum AuthState { uninitialized, unauthenticated, authenticated }
class SignInRouting extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FlowBuilder<SignInState>(
state: context.watch<SignInBloc>().state,
onGeneratePages: (SignInState state, List<Page> pages) {
switch (state) {
case SignInState.step1:
return [SignInStep1.page()];
case SignInState.step2:
return [SignInStep2.page()];
case SignInState.verify:
return [SignInVerify.page()];
}
});
}
}
enum SignInState {
step1,
step2,
verify,
} |
What would be structure of |
For everyones benefit, here are the scenarios that this proposal would support: https://github.com/flutter/uxr/blob/master/nav2-usability/storyboards/%5BPublic%5D%20Flutter%20Navigator%20Scenarios%20Storyboards%20v2.pdf I believe the onLocationChange and the FlowLocation really make sense for the deep linking path and query parameters and now I can clearly see how we can declaratively do this. With the FlowLocation, we really just add a named parameter and that's pretty simple. As always, it's not so much about what the API looks like as to how you use the API ! This means those little examples could go a long way and I look forward to helping apply the examples to these scenarios. The real feedback will come when more people use it and we uncover desire paths. I personally cannot imagine any more scenarios and I have full faith in the communities ability to use this in ways we never imagined, for better or for worse ! |
In your examples, you have this function which I think really helps being up at the top of the file List<Page> onGenerateProfilePages(Profile profile, List<Page> pages) {
return [
MaterialPage<void>(child: ProfileNameForm()),
if (profile.name != null) MaterialPage<void>(child: ProfileAgeForm()),
if (profile.age != null) MaterialPage<void>(child: ProfileWeightForm()),
];
} Would you suggest similar for onLocationUpdate? |
Sorry to derail a bit - is the intention of this to be a full drop in replacement for all routing within an app, or an enhancement for better flow support that should be used in conjunction with an existing routing solution? |
For those who need the web working today you can try auto_route with authguard + authentication bloc There are some limitations but it works somehow |
This can do both. Whether you would like to make it for a full replacement, or piecewise, that's the flexibility it offers
I think you will appreciate this ! https://github.com/felangel/bloc/tree/master/examples/flutter_firebase_login |
@felangel any ETA of this proposal? |
Sorry for the delay! I'm planning to pick this up later this week or this weekend 👍 |
Are there any updates about this? This would be very helpful for some deep link cases me and my team are working on! Thank you all for your efforts! |
For anyone interested, there's a WIP branch for this proposal at https://github.com/felangel/flow_builder/tree/feat/url-routing-and-deep-linking 🎉 |
@felangel How sync the browser url? |
I am interested, but it is not working as expected Here is my code
onDidPop is never called, onLocationChanged only on initial routing when starting the app. |
the problem seems to be that
is this a Bug or do I need to rethink my state for Navigation? UPDATE: |
Any update on this? |
Looking forward for this feature to be added. |
So, it's mainly suitable for onboarding or other limited page flows, or has anyone successfully used it as a comprehensive routing solution ? or possibly alongside packages like |
I think it is mostly used with vanilla navigation. It may be using auto
route or gorouter underneath but never tried this.
I think that gorouter and both auto route alongside bloc provide us enough
functionality and versatility to accomplish the same or similar flow.
I think we should go with whatever team is familiar with.
FlowBuilder<Profile>( state: const Profile(), onGeneratePages: (profile,
pages) { return [ MaterialPage(child: NameForm()), if (profile.name != null)
MaterialPage(child: AgeForm()), ]; }, );
…On Wed, Oct 30, 2024 at 1:25 AM Nabraj Khadka ***@***.***> wrote:
So, it's mainly suitable for onboarding or other limited page flows, or
has anyone successfully used it as a comprehensive routing solution ? or
possibly alongside packages like go_router or auto_route?
—
Reply to this email directly, view it on GitHub
<#41 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AL5HDXNIVWR47QLRILKEPS3Z6CCXDAVCNFSM6AAAAABJYCXCQCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINBWGA2TQMJVGY>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
[Proposal] Add Routing Support
Currently
FlowBuilder
does not have custom routing support for deep linking, dynamic linking, custom paths, query parameters, browser url synchronization, etc (#20).This proposal outlines a potential FlowBuilder API which can accomodate for the above use-cases by leveraging the Navigator 2.0 router APIs. Ideally, the proposed enhancements should be backward compatible with the existing API.
Routing API
Execution Flow
FlowBuilder
is initialized with astate
onLocationChanged
is invoked when a location change occurs.onGeneratePages
is triggered when the flow state changes & updates the nav stack.The developer can optionally react to changes in
FlowLocation
(abstraction on top ofRouteInformation
) and trigger updates in flow state.Named Routes
Named routes can be achieved by defining a
FlowPage
which extendsPage
.The above code will result in the following state to route mapping:
Profile()
(default):/profile
Profile(name: 'Felix')
:/profile?name=Felix
Profile(name: 'Felix', age: 26)
:/profile?name=Felix&age=26
Navigation
Navigation will largely remain unchanged. Using
context.flow
or aFlowController
, developers canupdate
the flow state orcomplete
the flow. The main difference would be updates to the flow state can potentially be accompanied by location changes if the associated pages are of typeFlowPage
with a customlocation
. When a named route is pushed viaNavigator.of(context).pushNamed
, all availableFlowBuilder
instances will be notified viaonLocationChanged
.Nested Routes
FlowBuilders
can be nested to support nested routing. For example:We can push a nested flow from within
Login
to initiate a Sign Up flow.The text was updated successfully, but these errors were encountered: