appyx
appyx copied to clipboard
Portals POC
Description
IMHO Portals itself looks like a proof that current navigation mental model is not scaleable at all. We are confusing component scopes (tree) and navigation (stack). At the moment when we start doing things like Portal we break initial tree. The base idea behind current component structure is wrong. To be able to do what Portals do, we need to completely separate rendering from component tree.
Works in the following way:
- Nodes who want to use portals should create
PortalClientNavModel
via factory - Client nodes should use the created nav model as its own nav model to manage creation/destruction of portaled node
- PortalNode will be aware of all created
PortalClientNavModel
- PortalNode will merge all client nav models into single nav model which will be used as its own nav model
- PortalNode resolver will reuse children created by client nodes via
PortalClient.attach
- PortalNode will take control over children lifecycle by using sync object
Issues:
- Hard to handle transitions. Need to do sync in both ways: from client to portal to be aware about new nav targets, merge all clients into a single list and from portal to client to properly update transition state.
- Back press handler system should be updated again, as it requires now to update the list of back click handlers dynamically.
- Hard to support
KeepMode.SUSPEND
properly.
Client code:
PortalNode(buildContext, rootNodeFactory = { context, clientFactory
RootNode(context, clientFactory)
})
class RootNode(
...
clientFactory: PortalClientFactory,
val client: PortalClient = clientFactory.createPortalClient(),
): ParentNode(
...
navModel = client.navModel + backStack + ...,
) {
fun onBuilt() {
client.attach(children, lifecycle)
}
fun openPortal() {
client.navModel.push(PortaledNavTarget)
}
}
Check list
- [ ] I have updated
CHANGELOG.md
if required. - [ ] I have updated documentation if required.