flutter / uxr

UXR work for Flutter
BSD 3-Clause "New" or "Revised" License
229 stars 28 forks source link

Comments on Flutter navigation scenarios #4

Closed InMatrix closed 3 years ago

InMatrix commented 3 years ago

We're looking into designing a high-level API to simplify common usage of Flutter's Navigator 2.0 (learn more from the project overview). As part of the API design process, we have defined a set of core navigation scenarios this new API should support. We'd like to have your feedback on those scenarios ([PDF] Flutter Navigator API Scenarios - Storyboards). Specifically, please consider responding to the following questions once you have reviewed the scenario storyboards:

  1. Which of these scenarios are critical for your project(s) and why?
  2. Which scenarios are not as important?
  3. Are there any other scenarios we should consider?

We are also looking for specific feedback on the skipping stacks scenario and the nested routes scenario.

Thank you for your feedback!

jlubeck commented 3 years ago
  1. I have a couple of different projects that would improve exponentially from properly implementing
  1. Deep Linking - Path Parameters
  2. Deep Linking - Query Parameters
  3. Login/Logout/Sign-up Routing
  4. Nested Routing

Not sure how to respond to the why other than the fact that is how the designers created the original wireframes.

  1. I'm sure 3 and 4 could come in handy of some situations, but not for me personally right now

  2. Can't think of anything that wouldn't be covered by the ones you already mentioned. Will be sure to come back if I can think of any

illia-romanenko commented 3 years ago

Hi @InMatrix and Flutter UXR team, thanks for sharing the progress.

From the reference project (https://github.com/johnpryan/page_router) having an easy ability to push route is great and easily returns us to the original simple API: PageRouter.of(context).pushNamed('/users/123');

  1. Which of these scenarios are critical for your project(s) and why?

1,2,3,5 - those either we are using or plan to use soon

  1. Which scenarios are not as important?

4,6 as we don't plan to use them yet

  1. Are there any other scenarios we should consider?

What we struggled with is how to react toBack and Forward browser buttons and have the ability to tie them to back to navigation (Back -> pop, Forward - navigate by URL). Is that something that is planned as well? Here is the previous discussion on the issue https://github.com/flutter/flutter/issues/71122 for your reference.

Thanks for your work on this, it's a very important issue to the community. Illia

bernaferrari commented 3 years ago

For me:

chimon2000 commented 3 years ago
  1. Which of these scenarios are critical for your project(s) and why?

1, 2, 4, 5, 6 are the most critical. Deep linking is a common scenario for mobile & PWAs. Skipping stacks is more prevalent for wizard flows where the flow changes based on user input. Authentication routing is probably the most common scenario for any app that has authentication. Nested routing is important for an app that I am building that uses bottom bar, but it is also probably important for desktop/web apps that blend global navigation with some feature-level routing.

  1. Which scenarios are not as important?

I have never had a client ask for dynamic linking.

  1. Are there any other scenarios we should consider?

Most routing frameworks have some version of auth guards that prevent navigation to routes based on some conditions. I am not sure if this is captured by the Login/Logout/Sign-up Routing, but it feels like something that developers should get for free.

page_router covers similar behavior with validator functions.

Some prior art:

  1. Flutter Modular route guards
  2. AutoRoute route guards
  3. Qlevar Router redirecting guards
  4. Beamer guards
  5. Angular route guards
passsy commented 3 years ago

When we tried to migrate to Navigator 2.0, because we wanted to offer better navigation in our web app, there were two show blockers: Nested Navigators are de facto impossible and sharing the navigation logic between web & mobile doesn't work. Our solution right now is to prevent navigation using the browser back/forward buttons altogether and continue using Navigator 1.0.

Nested Navigators

There are two ways we use nested routing I find in my apps:

Sharing between web & mobile

After weeks spent on Navigator 2.0, we came to the conclusion that navigation on web works fundamentally different than navigation on web.

On Web there should always be a single page on the stack. Navigation replaces that single item on the stack. It's simple: new url -> render new page. Back and forth are handled by the browser. There is no nested navigation.

Anywhere else (mobile, desktop), we want to keep a stack of pages in memory, even multiple stacks for nested navigation.

Both navigation concepts don't work well together. We basically have to build it twice to make it right on both platforms. This also means that deep linking has to be implemented twice.

I'd like to see examples where the same navigation logic is used on mobile and web. Currently, I don't think it's possible with nested navigation.

Priority

I consider "Deep Linking" (Query and Path), "Dynamic Linking" and "Nested Routing" as highest priority. I would feel limited without them and it's the bare minimum every javascript router package offers.

I'd like to combine "Skipping Stacks" and "Login/Logout/Sign-up Routing" as both require manipulation of the history stack. This was straight forward when we migrated to Navigator 2.0 API. Therefore I don't see much work to do in that region.

jarlestabell commented 3 years ago
  1. Which of these scenarios are critical for your project(s) and why?

Deep Linking - Query Parameters Deep Linking - Path Parameters Login/Logout/Sign-up Routing

  1. Which scenarios are not as important?

Skipping stacks would sometimes be handy. Personally I haven't yet felt the need for nested navigation. (But I may regret this statement in the future! :) )

  1. Are there any other scenarios we should consider?

I assume most users of the apps I'm building nowadays are very used to web apps, so I want navigation to be as web-like as possible. This includes the ability for the "same" page (say the book with id = 5) to be at multiple places in the history stack. (History stack with unlimited depth) For me, an explicit history stack would be preferable, where each item in the stack is either a real widget or a builder to (re)create the widget when/if needed. (It may be due to the apps that I have built lately that I need an explicit stack, a "declarative" approach to the history stack wouldn't suffice)

vinwonghk commented 3 years ago
  1. Which of these scenarios are critical for your project(s) and why?

Deep Linking - Path Parameters Deep Linking - Query Parameters Dynamic Linking Login/Logout/Sign-up Routing

For our use-case as a web game, Dynamic Linking is very important for us to implement the game room feature. But I guess this use-case is not as common as the other use-cases like Deep Linking and Signup Routing. Deep linking is useful for most of the use-cases and they are required to easily share the particular "item" page for other users. This helps bringing more users to the platform.

  1. Which scenarios are not as important?

Skipping Stacks as we are not planning to use it.

  1. Are there any other scenarios we should consider?

We have struggled in having the app act good on Back and Forward button.

Thanks for all of the hard work. This is important for Flutter Web.

jackkim9 commented 3 years ago

Skipping stacks is more prevalent for wizard flows where the flow changes based on user input.

@chimon2000 I'm curious to hear more about skipping stacks. Do you have or have come across any good example illustrating this scenario?

lukepighetti commented 3 years ago

Do we know if the Navigator 2.0 API is going to remain intact, or if this will be added on top of it?

escamoteur commented 3 years ago

@lukepighetti For my understanding they don't want to change the API but offer a higher level API on top of Navigator 2.0

rydmike commented 3 years ago

Which of these scenarios are critical for your project(s) and why?

1. Deep Linking - Path Parameters 2. Deep Linking - Query Parameters 5. Login/Logout/Sign-up Routing

1 and 2 are critical for most web apps. Our default is that should default do use correct back stack from their default deep location. So many features require 5. to offer smooth UX for exactly the type of of use case you show in the scenario docs

6. Nested Routing - CRITICAL

I can't see how you can provide users with a smooth application user experience without it, be it web, desktop or a tablet. I would like to add that for the best UX it is also critical to retain the state of each route visited, as it were when you last visited it, when you get back too it, also the scroll position.

Say you have an app with the destinations used in your example:

At Home, click Schedule, we get to "Schedule Main" (tab) (default for the tab view) , then click Schedule Kanban (tab) view-> Now at Kanban (tab), here lets say we scroll down to a position far down in the view, then -> Budget (tab).

Then go back. We now get to "Schedule Kanban" (tab) and it is still in same scroll position, or in whatever deeper navigation it had, like eg a details/edit view and even there in its previous scroll pos. If you click back and forth on the Schedule tabs, they all remain in the position and state they had when you last visited them.

Then let's from "Schedule Kanban" (tab), click "Team" we end up in "Team Main" (tab) (default) -> Add member (tab) With a back, back, we would be back in Schedule Kanban again, exactly where we were when we left its nav tree and scroll position.

Alternatively to the above "back, back", with just a single click on the "Schedule" main level side menu choice, we would also end up in "Schedule Kanban" (tab) view and not the "Schedule Main" (tab), since the "Schedule Kanban" tab was where we were when we last left it. We would also be back at whatever nav depth and scroll position we had in the Kanban Schedule (tab), this all because that is where we were last time we were on this nested route.

I built this for a Flutter desktop/tablet routing case, but have not really managed to port it over to Web (yet).

Which scenarios are not as important?

3. “Dynamic Linking” 4. “Skipping Stacks” Are less critical for us at at the moment. However if 1,2,5 and 6 are done, you pretty much have 3 and 4 in there somewhere already.

Are there any other scenarios we should consider?

Route guards would be very important too.

InMatrix commented 3 years ago

@lukepighetti Thank you for your question. Yes, the Navigator 2.0 API is going to remain intact in the foreseeable future.

I'd like to take this opportunity to clarify a few things about the purpose of this project, which we try to communicate in the project overview wiki page. To focus the conversation in this thread on scenarios, I opened #6 for general feedback on this project and posted my longer response there. Please take a look and let me know if I have addressed your concerns. Happy to chat offline as well.

cedvdb commented 3 years ago

One of my common use case is to redirect based on a stream.

For example I can have a 2 streams, authenticated$ and hasProfile$. And the page being shown needs to change when a new event is emitted through those streams.

Here is some pseudo code, I'm on mobile so Pardon the roughness of it

If authState is unknown
  Show loading page
If authState is unauthenticated
  If current url starts with 'unprotected' stay on url
  Else go to unprotected/sign-in

If authstate is authenticated {
  If hasProfileState is unknown
    Show loading page
  If has profile
    Stay on current route if we are not on unprotected subpart, if we are then go to home
  If has not profile
    Go to profile création page
}

Something like this

xuanswe commented 3 years ago

Which of these scenarios are critical for your project(s) and why?

To me, these scenarios are important for my app. But I would like to combine with the 3rd question here: Are there any other scenarios we should consider? to demonstrate a single list with the order of important:

Which scenarios are not as important?

Nice to have these scenarios in my app:

tiloc commented 3 years ago

I am building personal health apps. Linking to particular items from the outside is not a use-case for them. They need rock-solid authentication that cannot be circumvented by any playing around with URLs, etc. I am also using bottom navigation bar to navigate around with a few nested sub-pages under some of these items. Some of the nested pages should ideally not allow one to navigate away from them (for instance they are communicating with a medical device). On top of that I have a couple of fly-outs, such as a preference dialog from a hamburger menu.

My ranking would thus be: 1. Deep Linking - Path Parameters Not so important

2. Deep Linking - Query Parameters Not so important

3. “Dynamic Linking” Not so important

4. “Skipping Stacks” Useful in conjunction with nested routing, to get back to the main screen of a bottom navigation tab.

5. Login/Logout/Sign-up Routing Clearly the most important one for me

6. Nested Routing Yes, especially in combination with bottom navigation bar (or maybe navigation rail on the web). I would also require an easy way for the pages in the nested routing to remember their state. When I go from tab to tab in the bottom navigation bar I want the screens for each tab to remember their exact state.

lukepighetti commented 3 years ago
  • Route interceptor Normally, people will think about route guard. But I think, we should replace it with something more general and more powerful, like route interceptor. It does not only cover the case of route guard, but also provide much more usages. For example, I can create required instances before I navigate to a route and destroy instances when I exit the route. I can do it manually, or use an injection framework like GetIt with scopes.

It sounds like you're looking for route lifecycle? I think of a guard as being guarding the push of a route, but it sounds like you're talking about an 'onMount' and 'onDispose' lifecycle methods that you can register when it's pushed? What's the difference between that and doing it in the initState and dispose methods of a StatefulWidget screen widget?

xuanswe commented 3 years ago

@lukepighetti

It sounds like you're looking for route lifecycle?

Yes, exactly it's route lifecycle.

I think of a guard as being guarding the push of a route, but it sounds like you're talking about an 'onMount' and 'onDispose' lifecycle methods that you can register when it's pushed? What's the difference between that and doing it in the initState and dispose methods of a StatefulWidget screen widget?

It's totally different things. With Route Interceptor, I only care the route state. The Route Interceptor works like route guard but much more general and extremely flexible. The logic of Route Interceptor shouldn't know about the widgets. For example, before decision of building the widgets for a route, we could redirect to next route, or run next Route Interceptor, or show a dialog to tell user that "Hey, you don't have permission to open this URL, please buy PRO version or click Cancel to continue using FREE version", etc. All these stuffs happens before you decide to build the widget or not. And very important, with route lifecycle, I can integrate my injection solution with my own logic (normally when enter or exit a route). I have full control what I can do for each route event. We can check the Angular Router Events to learn from it.

Route Interceptor I mentioned is also a bit different than the route listener in angular. The route interceptor I introduced, is used directly to configure a route and just an extension of route guard. But route listener is totally independent from the route configuration and suitable for other cases.

lukepighetti commented 3 years ago

Can you offer a sketch of what the API might look like?

xuanswe commented 3 years ago

Can you offer a sketch of what the API might look like?

I also have more general feedback with detail and example

idkq commented 3 years ago

This is great, thanks for opening this research project.

My initial comments are: all of them are critical and are highly likely to be required in all dashboard-like apps.

Also would suggest renaming the Login/Logout/Sign-up Routing scenario (pg 14).

Instead of:

Scenario: Login/Logout/Sign-up Routing Example Scenario: Health Dashboard

to:

Scenario: Conditional Routing Example Scenario: Login/Logout/Sign-up Routing

That is, if a condition is met (logged in = true) go to B otherwise go to A, then go to B. Very important navigation pattern.

cedvdb commented 3 years ago

That is, if a condition is met (logged in = true) go to B otherwise go to A, then go to B. Very important navigation pattern.

I don't think it's necessarily a boolean condition, most of the time I have 3 states (loading, true, false)

idkq commented 3 years ago

@cedvdb Agree, not necessarily boolean, just an example but good call. Basically is one or more "forked" routes depending on conditions. We can think of it as a switch-case expression to resolve the conditions.

Not sure if there is any state-navigation requirements here. For example, when shopping in a website, a user tries to check-out and is asked to login/create user. She does so and now needs to go back to the same step/state that she was at previously. Are there any requirements for state-navigation purposes we can think of to maybe unwind the login-forked route stack?

lulupointu commented 3 years ago

New scenario (login+BottomNavBar)

I think one scenario is missing and is present is basically any app, I don't know what name name it should have but it is basically login+BottomNavBar

Description of the scenario

Click to see a GIF of the scenario ![login_bnb_scenario](https://user-images.githubusercontent.com/5128921/109656818-1b029700-7b65-11eb-97a2-30e568995739.gif)

The pages:

  1. A login page with a button to connect
  2. A scaffold with a bottom navigation bar which is synced with the body
  3. as body of the scaffold: A Home page
  4. as body of the scaffold: A Settings page

The navigation scenario

  1. Display a login page
  2. Tap the login button
  3. Display the Home page inside the scaffold, with a bottom navigation bar having its first item selected
  4. Tap the second item of the bottom navigation bar
  5. Display the Settings page inside the scaffold, with a bottom navigation bar having its second item selected

Why is that interesting/Different form others

The interesting part here is that there is a 2 level navigation issue.

The real challenge is that when navigating between "Login" and "Home", the entire screen should have a route animation. But when navigating between "Home" and "Settings", only the body of the scaffold should have a route animation.

While this might not seems like much it is the only way to have a complex animated bottom navigation bar. And apart from this toy example, there might be many cases when you only want part of the screen to change when navigating.

Please tell me if you think this would be an interesting scenario to add !

slovnicki commented 3 years ago

@lulupointu I completely agree!

And this is in fact the most problematic scenario to implement with Navigator 2.0, especially if we go a step further and have Home and Settings be separate Routers.

It can be straightforward in mobile, but gets quite more complicated to sync it with browser in web.

tiloc commented 3 years ago

+1 This is really the scenario where I was also tearing my hair out with Nav 2.0. A bottom bar, and the screen behind every menu entry can branch into additional screens, dialogs, etc. Some of them should keep the nav bar visible. Some should be full-screen.

jlubeck commented 3 years ago

I though that would be covered by the Nested Routing use case?

johnpryan commented 3 years ago

@lulupointu I agree that this sounds like a nested router scenario, but I'm curious what the specific route names would look like. Say we have three routes, /login, /home, and /settings, where /home/ and settings/ share some UI, and /login does not:

router

Alternatively, a nested router might not allow this, and instead you would have to declare a 'parent' route (app/ for example) that builds the bottom navigation bar and declares two children that are built and displayed in the space above the navigation bar:

router 2

slovnicki commented 3 years ago

I though that would be covered by the Nested Routing use case?

I agree, it should be a part of that scenario, but it's important to point out all the subtle differences that could arise when considering a very broad term "nested routers".

lulupointu commented 3 years ago

@johnpryan yes what you describe seems to be right, the second alternative with the '/app' might be a proof of more flexibility so it might be even better.

I agree that this could be taken into account into the nested scenario, but what I describe was not described in Navigation scenario storyboards. I think the part where the route animation should be once global and once inside the body of the scaffold in very important (and a complicated matter).

idkq commented 3 years ago

a nested router might not allow this, and instead you would have to declare a 'parent' route

Not ideal. Ideally we should be able to go to /home /settings without a parent. All routes should be final & sealed, that is, they redirect to a single point of view, so /app is an anti-pattern.

There should be no hierarchy enforcement whatsoever on the routes. Even though / (fwd slash) is used for organization purposes it should not matter at all.

theweiweiway commented 3 years ago

A feature that hasn't been suggested much here - but one that I think is really important - is declarative routing (or flow routing). Basically, routes that respond to a change in state like felangel's Flow builder package https://github.com/felangel/flow_builder, instead of having to call .push and .pop

(I know Felix's package isn't a routing solution per say, but it's a great example of declarative routing)

Almost every mobile app i can think of uses flows, where the user proceeds through a series of inputs and then does something with the final result (like a Create Account flow, or Profile Info flow)

jackkim9 commented 3 years ago

@lulupointu and @slovnicki, thanks for calling out this scenario. Do you by any chance have any real-world examples of this?

(+ @johnpryan), in terms of writing code snippets, how much of a variant of nested routing is this to call this out separately?

Alternatively, a nested router might not allow this, and instead you would have to declare a 'parent' route (app/ for example) that builds the bottom navigation bar and declares two children that are built and displayed in the space above the navigation bar:

router 2

slovnicki commented 3 years ago

@jackkim9 yes. For example the GitHub app I'm using;

It has a main interface with persistent bottom bar navigation where each tab seems to be a separate router, but when I go read an issue or am writing a response (like now), there is no bottom bar and this seems like a main router pushing pages on top of that bottom bar view with multiple routers.

(it can be seen even in the app store screenshots)

lukepighetti commented 3 years ago

A feature that hasn't been suggested much here - but one that I think is really important - is declarative routing (or flow routing).

I'm starting to think that we should be able to plug in a Declarative or Imperative mechanism to the front of our Stacked or Nested router. I have no idea how that works right now.

johnpryan commented 3 years ago

I agree that this could be taken into account into the nested scenario, but what I describe was not described in Navigation scenario storyboards.

@lulupointu How so? The Nested Routing scenario shows a left navigation menu instead of a bottom app bar, but is essentially the same. The Login / Logout / Sign-up scenario is also mentioned in the storyboards.

I think the part where the route animation should be once global and once inside the body of the scaffold in very important (and a complicated matter).

@jackkim9 we could consider including animation details in the storyboards, but I think our users already expect to be able to configure animations for any route. Right now this can be configured on a per-page basis by extending the Page class.

in terms of writing code snippets, how much of a variant of nested routing is this to call this out separately?'

@jackkim9 From an end-user's perspective, there's really no difference, but from a developer's perspective it could be harder to describe the first image using an API than the second.

I think the second image is easier to imagine. If the /home and /settings pages within an /app page, then the /app page would be responsible for building the BottomNavigationBar, and defining where in the subtree the "outlet" or VRouteElementData.of(context).vChild widget is displayed (usually in the body of the Scaffold.) A complication is that it would need to know the rest of the path (or at least the next path component) to set the correct currentIndex on the BottomNavigationBar.

The first image might be possible by having similar build() methods in the /home and /settings widgets, but would be more difficult to maintain two copies of a BottomNavigationBar between two different widgets and relying on the framework to consider them the same (you would need to provide the same key, essentially.)

idkq commented 3 years ago

How much are we coupling the url with the classes nesting inside the code? To me urls can be anything and '//////' means nothing for routing, it is just a String that can be resolved into point to a location (using regex for ex, if '//////' go to A). The use of slugs are an example.

An url can have at least one of these features:

I don't understand the use of /app and how it meets this criteria, since it leads to nowhere.

A clear downside to this is that you lose hierarchy on navigation - you cannot go up one level (like in files directory) but only back and forward. But this can be easily solved depending on how you model the urls and its resolver.

johnpryan commented 3 years ago

I don't understand the use of /app and how it meets this criteria, since it leads to nowhere.

The image probably wasn't very clear, but the /app page would be responsible for building the Scaffold and BottomNavigationBar that surround the /home and /settings screens.

theweiweiway commented 3 years ago

Another point I would like to bring up is wrapping routes (Not really a "navigation scenario" but it is deeply linked to navigation).

I think the use case exists for almost all medium to large sized apps, where the developer might want to wrap a certain set of routes with another widget. For example, I might want to scope my ProductsCubit to only /products routes. Otherwise, i need to lift all of my cubits to above the router.

If a router supports nested routers, then chances are that it supports wrapping routes. But it might be worth adding this to the storyboard to compare how easy it is to wrap a set of routes. Maybe, maybe not

slovnicki commented 3 years ago

@theweiweiway I completely agree.

Navigation could (should?) be seen as a glue between architecture and state management. I'm unsure how to word it better.

This was exactly on my mind when implementing BeamLocation.builder: https://pub.dev/packages/beamer#location-builder (description, gif example and link to code). That "architectural state" idea had a major influence on the whole concept of BeamLocation.

And if we allow arbitrary Widget for wrapping (doesn't make sense not to), we can get something like this for free: https://pub.dev/packages/beamer#beamer-widget (see second gif, altough its code is not using that idea)

adrianflutur commented 3 years ago

Hi, I think I found one more use case scenario: HTML fragments (e.g. https://xyz.com/index.html#section2). Those should be appended to the end of the URL without pushing the page over again (and also the page should scroll to specified fragment's position).

Also not necessarily just the fragments, but in general it should be possible to change the URL in response to some user actions, like filters being applied/removed to/from a search criteria. This would allow one to copy the modified URL (containing various parameters/filters/fragments/etc, which were added in the URL) for later use (paste it in the address bar).

InMatrix commented 3 years ago

@theweiweiway Thanks for bringing up the declarative routing issue. I opened https://github.com/flutter/uxr/issues/15 for further discussion on that topic.

lulupointu commented 3 years ago

Hi,

I am not sure how much this is important to flutter devs but are some features that are useful on the web and not covered by the scenarios:

This is something that is not covered by Navigator 2 but which seem pretty important to me for a web app. The history state manipulation can be quite tricky especially when covering every cases (in particular if we when to change it in reaction to a browser back button) but possible nonetheless.

Concrete scenarios in which this might be useful:

1. Replacing a url instead of pushing a new one (i.e the previous one won't appear in the history of the browser):

The first and most important case would be for redirecting. If we redirect the user to '/404' for example, chances are we don't want to save the previous url as an history entry.

Another case would be the one of a one-time flow. For example if we have an unauthenticated user trying to access a secure page that we first want to authenticate. Here is the scenario: "Public page" |(click)|->1 "Private page" |(redirect)|->2 "Login" |(click)|->3 "Private page" |(back button)|->4 "Public page" For navigation 2 and 3 we want to override the history entry. This means that in navigation 4, when the user presses the browser back button, the user will go back to "Public page".

2. Manipulating the history state: pushing a new one and replacing it afterward:

The most important case here would be to store a scoll amount for example: "Github issue" |(user scroll to pixel 400)| |(click)|->1 "other page" |(back button)|->2 "Github issue (with 400 pixel scrolled)"

This could also be used for form saving, even if one might argue that this kind of state should be stored globally (not tied to a web entry).

In any case, I do believe both are very important for a complete web routing API. That said, it might be worth asking ourselves if this is needed considering the fact that it is not platform agnostic. My personal view is that it should but tell me what you think!

jackkim9 commented 3 years ago

dash

Hi everyone,

Thanks so much for sharing your comments and suggestions for the navigation and routing scenarios. We have updated the storyboards based on your feedback and can be found here: Storyboards v2. Please feel free to leave any comments on the slides here: #5 (for general Feedback) and #20 (for new scenarios to consider).

We will continue to document scenarios that are not captured in this deck via this new issue: #20.

Our immediate next step is to conduct a more detailed evaluation (#7) of usability benefits and disadvantages based on code snippets (#9) provided by package authors based on the updated scenarios (i.e. Storyboard v2).

For the intial round of comparative analysis, we will focus on 1-2 packages and 1-2 scenarios so that the team can evaluate the review process end-to-end. We will announce the package(s) here: #10.

Thanks so much for your support!

xuanswe commented 3 years ago

@jackkim9

lukepighetti commented 3 years ago

Dynamic linking contains deep linking, as far as I know. It seems like a dynamic link would not be in the scope of a router package, but would rely on the deep linking capabilities.

lukepighetti commented 3 years ago

I do believe that nested routers should be configurable to not be included in the back/forward steps. Changing tabs is not something I would typically expect when hitting the back button. But returning to the last viewed tab when going back to a page that had one is.

EDIT this might be covered by the "removing duplicate pages" scenario

Screen Shot 2021-03-17 at 11 00 30 AM
lukepighetti commented 3 years ago

I'll be honest I don't understand the Skipping Stacks scenario.

xuanswe commented 3 years ago

I'll be honest I don't understand the Skipping Stacks scenario.

The scenario is quite clear to me. It has 2 stacks. When you jump to a 2nd stack, you should stay on the 2nd stack when click in-app back button. At the time of jumping, the old stack is not related to the context any more.

Maybe plaintext is helpful:

  1. open HomePage => current stack = [HomePage]
  2. open other pages, ex. search page and found a book. => current stack = [HomePage, SearchPage] If click in-app back button (AppBar, leftside) => current stack = [HomePage]
  3. open book details => current stack = [HomePage, HistorialFictionCategoryPage, BookDetailsPage] If click in-app back button (AppBar, leftside) => current stack = [HomePage, HistorialFictionCategoryPage].
johnpryan commented 3 years ago

I found the diagrams from Understanding Navigation - Types of Navigation section of the Material Design docs helpful to illustrate the scenario. These docs are illustrating the difference between forward, backward, and lateral navigation, but the app flow diagram they use is handy:

image

The highlighted bit is "lateral navigation" - which seem to me like a "skipping stacks" use-case where the stack has a depth of 1. Navigating from the search screen to the song screen is also an example, the stack has changed from [Search] to [Library, Album, Song].

lukepighetti commented 3 years ago

The [Search] to [Library, Album, Song] stack transition is super illustrative of this. Thanks.