PrismLibrary / Prism

Prism is a framework for building loosely coupled, maintainable, and testable XAML applications in WPF, Xamarin Forms, and Uno / Win UI Applications..
Other
6.35k stars 1.64k forks source link

[Enhancement] DeepLink Navigation into subPages of TabbarItem (Xamarin.Forms) #2038

Closed MaxFmi closed 1 year ago

MaxFmi commented 4 years ago

Summary

DeepLink into a subPage of one TabbarItem. Navigate by an absolute path -> /NavigationPage/TabbedPage/TabA/ViewA_Page/ViewB_Page

API Changes

_navigationService.NavigateAsync($"/NavigationPage/TabbedPage?{KnownNavigationParameters.SelectedTab}=TabAContentPage/ViewA_Page/ViewB_Page");

Intended Use Case

Having a consumer application where it is possible to see some electronic devices and buy additional features. One tab would be for device settings. Some detail pages have a linkt to the shop tab and it's detailPages for specific Items. So we want to navigate from "/TabbedPage/TabDevices/DeviceOne/PrintCartridgeStatus" to "/TabbedPage/TabShop/PrinterCartridges".

Related issue: https://github.com/PrismLibrary/Prism/issues/2033

dylanberry commented 4 years ago

@dansiegel I'm interested in implementing this feature.

dansiegel commented 4 years ago

I look forward to the PR 👍

ping me on Slack if you have any questions.

brianlagunas commented 4 years ago

I'll add that you can't simply change the way deep link navigation works when dealing with a selected tab to automatically start nesting the nav process. That would be a massive navigation behavior break. instead, you will need some type of flag or way to opt-into a nested navigation operation for tabs.

brianlagunas commented 4 years ago

If you manage to implement this feature, you'll also have to update the INavigationServiceExtensions.GetNavigationUriPath method to account for nested tab navigation stacks to return the proper nav uri

dylanberry commented 4 years ago

Something like this Brian?

https://github.com/TorontoMobileDevelopers/PrismTabNav/blob/d7c1a520d4c316d7baaae2f3214837e9fa16addf/PrismTabNav/ViewModels/ItemsViewModel.cs#L79

On Wed., Apr. 8, 2020, 7:09 p.m. Brian Lagunas, notifications@github.com wrote:

I'll add that you can't simply change the way deep link navigation works when dealing with a selected tab to automatically start nesting the nav process. That would be a massive navigation behavior break. instead, you will need some type of flag or way to opt-into a nested navigation operation for tabs.

— You are receiving this because you were assigned. Reply to this email directly, view it on GitHub https://github.com/PrismLibrary/Prism/issues/2038#issuecomment-611239660, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAOBL7RWHODEHLGCP4QQVTDRLT73HANCNFSM4LGQGQUA .

dansiegel commented 4 years ago

I do want to add some notes here as well for clarification... There are a couple of parts to this issue as I see it.

  1. Enhance the QueryString parsing for DeepLink Dynamic creation of tabs.
  2. Support scenarios where one or more tabs is a NavigationPage
  3. Handle the Navigation relative to the tab in question. (more on this later)

Proposed Code

The following is pretty much what was discussed on the stream from @dylanberry

NavigationService.NavigateAsync("TabbedPage?createTab=ViewA&createTab=ViewB&selectedTab=ViewB/ViewC");

This code current should and should always continue to push ViewC modally over the TabbedPage. Any time we run into a / we should always treat this as a new navigation segment not a continuation of the existing segment.

Corrected Approach

When we're trying to deal with the first issue I listed and to deal with the issue of treating a forward slash as a new navigation segment the answer is quite simple... URL Encode your parameters. The result is now something like this:

NavigationService.NavigateAsync("TabbedPage?createTab=ViewA&createTab=NavigationPage%2FViewB%2FViewC%2FViewD&selectedTab={NavigationPage|ViewB|ViewD}/ViewE");

This would be the equivalent of:

var tabbedPage = new TabbedPage();
var navigationPage = new NavigationPage(new ViewB());
await navigationPage.PushAsync(new ViewC());
await navigationPage.PushAsync(new ViewD());
tabbedPage.Children.Add(new ViewA());
tabbedPage.Children.Add(navigationPage);
tabbedPage.CurrentPage = navigationPage;
navigationPage.PushAsync(new ViewE());

SelectedTab

I'm certainly open to community feedback on this, however I do believe that if we are supporting NavigationPage's as tabs then this adds some complexity in determining what the Selected tab is.

Handling subsequent Navigation

With those issues addressed we should next tackle the issue of navigating from the context of the current tab. If the current tab is a NavigationPage then we should push subsequent pages into that NavigationPage unless it's been overridden with the useModalNavigation querystring parameter.

dylanberry commented 4 years ago

Based on discussions with @brianlagunas, if we implement this using the "slash approach", it breaks from the master-detail navigation behavior and existing tab navigation behavior.

We should aim for a few things:

  1. Human readability/developer friendly navigation paths
  2. Flexibility, being able to navigate to any page navigation combination that can be reached with UI
  3. Maintain existing behavior
  4. Consistency

With those considerations in mind, uri encoding makes already complex uris even more difficult to read and the "slash approach" doesn't allow for a mix of pushing pages onto the selected tab's navigation stack and creation of new modal stack, it also breaks existing behavior. In order to keep the consistent approach established by createTab, using pipes looks to be the best way to implement this:

TabbedPage?selectTab=Tab2|ViewA|ViewB|ViewC/AnotherPage
TabbedPage?createTab=Tab1&createTab=NavigationPage|Tab2&createTab=Tab3&selectTab=Tab2|ViewA|ViewB|ViewC/AnotherPage
dylanberry commented 4 years ago

@brianlagunas @dansiegel gents, any issues with me updating the HelloWorld app projects to the latest Xamarin + XF?

dansiegel commented 4 years ago

@dylanberry we have an open PR #2103 that is going to be updating the Xamarin.Forms reference in the primary Prism repo... is this what you're asking about or are you asking about the samples?

dylanberry commented 4 years ago

Just the sample projects used for the UI tests :)

dansiegel commented 4 years ago

that should always be in sync with Prism.Forms... so it will be updated with 2103

dylanberry commented 4 years ago

@brianlagunas @dansiegel with Maui now coming into the picture, I'm more hesitant about the Uri structure. I'll give this some more thought and follow-up.

stale[bot] commented 4 years 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.

mackayn commented 4 years ago

This is something that tripped us up recently, we wanted to build a nav stack on a tab based on a notification type been selection, we just pushed it to the bottom of the backlog for now

dansiegel commented 4 years ago

@mackayn I know @dylanberry was working on this.. I don't know if he just needs a few beers sent to him to finish this up or if someone needs to take over the PR to get it across the finish line... maybe he can tell us :)

vniehues commented 4 years ago

@dansiegel @dylanberry Can you tell me about the current state of the PR or the plans for this feature? If there is not much left to do I'd like to give it a shot because this is a feature I really need inside my apps. Thanks in advance! :)

dansiegel commented 4 years ago

@vniehues at this point the PR needs to be rebased. It was never merged due to failing UI tests. If you'd like to give it a go and open a new PR to replace this one we're all for it. @dylanberry has been swamped by his pesky job so I'm sure he won't mind 😂

vniehues commented 4 years ago

@dansiegel I have the project up and running on my system now. All build-errors are eliminated and all unit tests are passing. I have never worked with UI tests in xamarin. How do i find out, if they pass now? :)

vniehues commented 4 years ago

@dansiegel I would really like to help implement these changes as I can imagine that they would help many people like me. Please let me know how I can proceed with this PR. Also, please have mercy as this is my first PR.

Again: I already rebased the PR on the current Master and fixed all build-errors. Also all unit tests are passing as of right now.

dansiegel commented 4 years ago

@vniehues best place to start is with this video from when we setup the UI Tests... that should help give you the info you need to get started and understand how to run and work with the UI Tests https://www.youtube.com/watch?v=gsqf52Q5QOw

dansiegel commented 1 year ago

This will not be backported for Xamarin.Forms but should be supported already in Prism.Maui