Skip to content

Instantly share code, notes, and snippets.

@PureWeen
Last active June 11, 2019 04:31
Show Gist options
  • Save PureWeen/f9308c9bee5a27afe25992c021c39d16 to your computer and use it in GitHub Desktop.
Save PureWeen/f9308c9bee5a27afe25992c021c39d16 to your computer and use it in GitHub Desktop.
Spec for shell navigation hooks

Shell Navigation interfaces

Existing work being done here xamarin/Xamarin.Forms#6383

Notes

The intent of this setup is to empower MVVM frameworks to effectively influence every aspect of shell processing a Uri. ShellRouteState represents the data object that Shell understands but MVVM frameworks can effectively implement there own uri scheme with the above set of interfaces. People can also just tap into parts of the process if they only want to influence one or two things.

ShellNavigationArgs

Arguments passed to Navigating process indicating where I'm going to be going

public class ShellNavigationArgs : EventArgs
{
	public Shell Shell { get; }
	public ShellRouteState FutureState { get; }
}

Properties

API Description
Shell The current shell.
FutureState The state being changed to.

ShellContentCreateArgs

Arguments passed to Shell Content creation.

public class ShellContentCreateArgs : EventArgs
{
	public ShellContent Content { get; }
}

Properties

API Description
Content The Shell Content being created.

ShellUriParserArgs

Arguments passed to Method that parses Uri to New Route Path

public class ShellUriParserArgs : EventArgs
{
	public Shell Shell { get; }
	public Uri Uri { get; }
}

Properties

API Description
Shell The Current Shell.
------------- -------------
Uri The Uri being navigated to.

ShellLifecycleArgs

Arguments passed to various stages related to life cycle.

public class ShellLifecycleArgs : EventArgs
{
	public BaseShellItem BaseShellItem { get; }
	public PathPart PathPart { get; }
	public RoutePath RoutePath { get; }
	public bool IsLast { get; }
}

Properties

API Description
BaseShellItem Shell event is happening to.
PathPart The part of the path that's connected to this BaseShellItem.
RoutePath The full path.
IsLast Is this the last thing being routed to.

ShellRouteState

Used to indicate the entire routing state of the shell. This contains all the branched stacks, the different paths that represent each different page, the paramteres to apply to those pages, how to transition to and away from those. The idea here is that you can setup an entire route state based on this data. All of this could be serialized during tombstoning as well to fully recreate the application. The renderer level can also take this in to see where the user is going and then at that point make decisions about what it wants to present and how

public class ShellRouteState
{
    public RoutePath[] Routes { get; }

    public RoutePath CurrentRoute { get;  }

}

Properties

API Description
Routes Flyout items effectively cause you to swap stacks so this is a way to represent those different stacks.
ActiveRoute this represents the visible stack.

RoutePath

Signifies an individual stack path

public class RoutePath
{
    public RoutePath(IList<PathPart> pathParts)
    {
        PathParts = new ReadOnlyCollection<PathPart>(pathParts);
    }

    public IReadOnlyList<PathPart> PathParts { get; }
    public Dictionary<string, string> NavigationParameters { get; }
}

Properties

API Description
PathParts List of path parts representing different pages on the stack.
NavigationParameters The parameters to apply at the shell level.

PathPart

Signifies a specific part of the route that applies to a given shell element being navigated to. This also contains the parameters that will be applied to the particular shell part

public class PathPart
{
    public string Path { get; }

    // in theory you could store a bindingcontext here for tombstoning        
    public KeyValuePair<string, object> Parameters { get; }
    public BaseShellItem ShellItem { get; }

    // This describes how you will transition to and away from this Path Part
    ITransitionPlan Transition { get; }

    // how am I presented? Modally? as a page?W
    PresentationHint Presentation { get;  }
}

Properties

API Description
Path The path associated with this Shell Part.
Parameters List of parameters to apply to the realized content.
Transition How to transition to this page when it's added and when it's removed.
Presentation Am I modal? A dialog box? other?
BaseShellItem Shell associated with this path of the Uri

Version 2.0 things

public enum PresentationHint
{
    Page,
    Modal,
    Dialog,
            Custom
}
interface ITransitionPlan
{
    ITransition Pushed { get; }
    ITransition Popped { get; }
}

interface ITransition
{
}

Interface Bonanza

IUriProjectionParser

  • Allows a developer to implement a custom uri scheme. The uri could completely demolish the current state and just return a new setup completely
public interface IUriProjectionParser
{
    Task<ShellRouteState> ParseAsync(ShellUriParserArgs args);
}

IShellNavigationRequest

  • The args for Navigating will have the current shell and the route being travelled to. Based on where the user is going the developer can modify anything they want to with the route being travelled to. If they want to they can return a completely different one. If you want to cancel navigation then just return null or current state
public interface IShellNavigationRequest
{
    Task<ShellRouteState> NavigatingToAsync(ShellNavigationArgs args);
}

IShellContentCreator

  • Customize how a content page is created
public interface IShellContentCreator
{		
    ContentPage Create(ShellContentCreateArgs content);
}

IShellApplyParameters

  • Apply routing parameters to the destination point. This will be called prior to navigating to any page. So if the user hits the back button this will get called
public interface IShellApplyParameters
{
    Task ApplyParametersAsync(ShellLifecycleArgs args);
}

IShellPartAppearing

  • Do things before the Shell is appearing but the intention for it to appear is definite and nothing can stop it. This is called for ShellItem, Section, Content.
public interface IShellPartAppearing
{
    Task AppearingAsync(ShellLifecycleArgs args);
}

IShellPartAppeared

  • Page is visible on the screen
public interface IShellPartAppeared
{
    Task Appeared(ShellLifecycleArgs args);
}

IShellPartDisappeared

  • Shell part has been navigated away from and is no longer visible
public interface IShellPartDisappeared
{
    Task DisappearedAsync(ShellLifecycleArgs args);
}

Order of calling interfaces

  • IUriProjectionParser.Parse

  • IShellNavigationRequest.NavigatingTo

    • Any Navigation or modification to shell state at this point will throw an exception
  • IShellContentCreator.Create

  • IShellApplyParameters.ApplyParameters

  • IShellProjectionHandler.Project

  • IShellPartAppearing.Appearing

  • IShellPartAppearing.Appeared

    • at this point you can apply new navigation requests
  • IShellPartAppearing.Disappeared

Brain storm helpers for people and other things to make

  • Initial Loading Shell Item users can use as the first landing page while initial nav is sorted out which can also be used for coming back from tombstoning. Need a tombstoning provider
  • Shell.SetVisibility("route", bool)
  • Shell.ChangeLayout("route")
  • Shell.GetCurrentPage()
  • Shell.Add(Thing, "parentroute") //used to easily add tabs and content to shell
  • Shell.BackbuttonBehavior changes should operate based off of change modifications and not replacement. Thing like Shell.BackButtonBehavior.SetIcon(Icon) which will generate a new BackButtonBehavior matching everything except a new icon or just don't replace the whole thing if they set overrides. I have some code where this is sort of built
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment