Remove NodeBuilder to ensure that Params and Callback are always provided.

This commit is contained in:
Benoit Marty
2025-10-30 11:37:59 +01:00
committed by Benoit Marty
parent 5197154f54
commit 566515ca88
115 changed files with 954 additions and 1174 deletions

View File

@@ -333,10 +333,11 @@ class LoggedInFlowNode(
callback.navigateToBugReport() callback.navigateToBugReport()
} }
} }
homeEntryPoint homeEntryPoint.createNode(
.nodeBuilder(this, buildContext) parentNode = this,
.callback(callback) buildContext = buildContext,
.build() callback = callback,
)
} }
is NavTarget.Room -> { is NavTarget.Room -> {
val joinedRoomCallback = object : JoinedRoomLoadedFlowNode.Callback { val joinedRoomCallback = object : JoinedRoomLoadedFlowNode.Callback {
@@ -389,10 +390,12 @@ class LoggedInFlowNode(
backstack.push(NavTarget.Room(roomId.toRoomIdOrAlias())) backstack.push(NavTarget.Room(roomId.toRoomIdOrAlias()))
} }
} }
userProfileEntryPoint.nodeBuilder(this, buildContext) userProfileEntryPoint.createNode(
.params(UserProfileEntryPoint.Params(userId = navTarget.userId)) parentNode = this,
.callback(callback) buildContext = buildContext,
.build() params = UserProfileEntryPoint.Params(userId = navTarget.userId),
callback = callback,
)
} }
is NavTarget.Settings -> { is NavTarget.Settings -> {
val callback = object : PreferencesEntryPoint.Callback { val callback = object : PreferencesEntryPoint.Callback {
@@ -417,10 +420,12 @@ class LoggedInFlowNode(
} }
} }
val inputs = PreferencesEntryPoint.Params(navTarget.initialElement) val inputs = PreferencesEntryPoint.Params(navTarget.initialElement)
preferencesEntryPoint.nodeBuilder(this, buildContext) preferencesEntryPoint.createNode(
.params(inputs) parentNode = this,
.callback(callback) buildContext = buildContext,
.build() params = inputs,
callback = callback,
)
} }
NavTarget.CreateRoom -> { NavTarget.CreateRoom -> {
val callback = object : StartChatEntryPoint.Callback { val callback = object : StartChatEntryPoint.Callback {
@@ -433,27 +438,32 @@ class LoggedInFlowNode(
} }
} }
startChatEntryPoint startChatEntryPoint.createNode(
.nodeBuilder(this, buildContext) parentNode = this,
.callback(callback) buildContext = buildContext,
.build() callback = callback,
)
} }
is NavTarget.SecureBackup -> { is NavTarget.SecureBackup -> {
secureBackupEntryPoint.nodeBuilder(this, buildContext) secureBackupEntryPoint.createNode(
.params(SecureBackupEntryPoint.Params(initialElement = navTarget.initialElement)) parentNode = this,
.callback(object : SecureBackupEntryPoint.Callback { buildContext = buildContext,
params = SecureBackupEntryPoint.Params(initialElement = navTarget.initialElement),
callback = object : SecureBackupEntryPoint.Callback {
override fun onDone() { override fun onDone() {
backstack.pop() backstack.pop()
} }
}) },
.build() )
} }
NavTarget.Ftue -> { NavTarget.Ftue -> {
ftueEntryPoint.createNode(this, buildContext) ftueEntryPoint.createNode(this, buildContext)
} }
NavTarget.RoomDirectory -> { NavTarget.RoomDirectory -> {
roomDirectoryEntryPoint.nodeBuilder(this, buildContext) roomDirectoryEntryPoint.createNode(
.callback(object : RoomDirectoryEntryPoint.Callback { parentNode = this,
buildContext = buildContext,
callback = object : RoomDirectoryEntryPoint.Callback {
override fun navigateToRoom(roomDescription: RoomDescription) { override fun navigateToRoom(roomDescription: RoomDescription) {
backstack.push( backstack.push(
NavTarget.Room( NavTarget.Room(
@@ -463,31 +473,35 @@ class LoggedInFlowNode(
) )
) )
} }
}) },
.build() )
} }
is NavTarget.IncomingShare -> { is NavTarget.IncomingShare -> {
shareEntryPoint.nodeBuilder(this, buildContext) shareEntryPoint.createNode(
.callback(object : ShareEntryPoint.Callback { parentNode = this,
buildContext = buildContext,
params = ShareEntryPoint.Params(intent = navTarget.intent),
callback = object : ShareEntryPoint.Callback {
override fun onDone(roomIds: List<RoomId>) { override fun onDone(roomIds: List<RoomId>) {
navigateUp() navigateUp()
roomIds.singleOrNull()?.let { roomId -> roomIds.singleOrNull()?.let { roomId ->
backstack.push(NavTarget.Room(roomId.toRoomIdOrAlias())) backstack.push(NavTarget.Room(roomId.toRoomIdOrAlias()))
} }
} }
}) },
.params(ShareEntryPoint.Params(intent = navTarget.intent)) )
.build()
} }
is NavTarget.IncomingVerificationRequest -> { is NavTarget.IncomingVerificationRequest -> {
incomingVerificationEntryPoint.nodeBuilder(this, buildContext) incomingVerificationEntryPoint.createNode(
.params(IncomingVerificationEntryPoint.Params(navTarget.data)) parentNode = this,
.callback(object : IncomingVerificationEntryPoint.Callback { buildContext = buildContext,
params = IncomingVerificationEntryPoint.Params(navTarget.data),
callback = object : IncomingVerificationEntryPoint.Callback {
override fun onDone() { override fun onDone() {
backstack.pop() backstack.pop()
} }
}) },
.build() )
} }
} }
} }

View File

@@ -83,16 +83,15 @@ class NotLoggedInFlowNode(
callback.navigateToBugReport() callback.navigateToBugReport()
} }
} }
loginEntryPoint loginEntryPoint.createNode(
.nodeBuilder(this, buildContext) parentNode = this,
.params( buildContext = buildContext,
LoginEntryPoint.Params( params = LoginEntryPoint.Params(
accountProvider = inputs.loginParams?.accountProvider, accountProvider = inputs.loginParams?.accountProvider,
loginHint = inputs.loginParams?.loginHint, loginHint = inputs.loginParams?.loginHint,
) ),
) callback = callback,
.callback(callback) )
.build()
} }
} }
} }

View File

@@ -249,11 +249,13 @@ class RootFlowNode(
createNode<NotLoggedInFlowNode>(buildContext, plugins = listOf(params, callback)) createNode<NotLoggedInFlowNode>(buildContext, plugins = listOf(params, callback))
} }
is NavTarget.SignedOutFlow -> { is NavTarget.SignedOutFlow -> {
signedOutEntryPoint.nodeBuilder(this, buildContext).params( signedOutEntryPoint.createNode(
SignedOutEntryPoint.Params( parentNode = this,
sessionId = navTarget.sessionId buildContext = buildContext,
) params = SignedOutEntryPoint.Params(
).build() sessionId = navTarget.sessionId,
),
)
} }
NavTarget.SplashScreen -> emptyNode(buildContext) NavTarget.SplashScreen -> emptyNode(buildContext)
NavTarget.BugReport -> { NavTarget.BugReport -> {
@@ -262,7 +264,11 @@ class RootFlowNode(
backstack.pop() backstack.pop()
} }
} }
bugReportEntryPoint.nodeBuilder(this, buildContext).callback(callback).build() bugReportEntryPoint.createNode(
parentNode = this,
buildContext = buildContext,
callback = callback,
)
} }
is NavTarget.AccountSelect -> { is NavTarget.AccountSelect -> {
val callback: AccountSelectEntryPoint.Callback = object : AccountSelectEntryPoint.Callback { val callback: AccountSelectEntryPoint.Callback = object : AccountSelectEntryPoint.Callback {
@@ -287,7 +293,11 @@ class RootFlowNode(
backstack.pop() backstack.pop()
} }
} }
accountSelectEntryPoint.nodeBuilder(this, buildContext).callback(callback).build() accountSelectEntryPoint.createNode(
parentNode = this,
buildContext = buildContext,
callback = callback,
)
} }
} }
} }

View File

@@ -180,10 +180,12 @@ class RoomFlowNode(
} }
} }
val params = Params(navTarget.roomAlias) val params = Params(navTarget.roomAlias)
roomAliasResolverEntryPoint.nodeBuilder(this, buildContext) roomAliasResolverEntryPoint.createNode(
.callback(callback) parentNode = this,
.params(params) buildContext = buildContext,
.build() params = params,
callback = callback,
)
} }
is NavTarget.JoinRoom -> { is NavTarget.JoinRoom -> {
val inputs = JoinRoomEntryPoint.Inputs( val inputs = JoinRoomEntryPoint.Inputs(
@@ -205,10 +207,12 @@ class RoomFlowNode(
} }
is NavTarget.JoinedSpace -> { is NavTarget.JoinedSpace -> {
val spaceCallback = plugins<SpaceEntryPoint.Callback>().single() val spaceCallback = plugins<SpaceEntryPoint.Callback>().single()
spaceEntryPoint.nodeBuilder(this, buildContext) spaceEntryPoint.createNode(
.inputs(SpaceEntryPoint.Inputs(roomId = navTarget.spaceId)) parentNode = this,
.callback(spaceCallback) buildContext = buildContext,
.build() inputs = SpaceEntryPoint.Inputs(roomId = navTarget.spaceId),
callback = spaceCallback,
)
} }
} }
} }

View File

@@ -140,10 +140,12 @@ class JoinedRoomLoadedFlowNode(
backstack.push(NavTarget.ForwardEvent(eventId)) backstack.push(NavTarget.ForwardEvent(eventId))
} }
} }
return roomDetailsEntryPoint.nodeBuilder(this, buildContext) return roomDetailsEntryPoint.createNode(
.params(RoomDetailsEntryPoint.Params(initialTarget)) parentNode = this,
.callback(callback) buildContext = buildContext,
.build() params = RoomDetailsEntryPoint.Params(initialTarget),
callback = callback,
)
} }
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
@@ -177,10 +179,12 @@ class JoinedRoomLoadedFlowNode(
} }
} }
} }
forwardEntryPoint.nodeBuilder(this, buildContext) forwardEntryPoint.createNode(
.params(params) parentNode = this,
.callback(callback) buildContext = buildContext,
.build() params = params,
callback = callback,
)
} }
} }
} }
@@ -199,10 +203,12 @@ class JoinedRoomLoadedFlowNode(
backstack.push(NavTarget.RoomMemberList) backstack.push(NavTarget.RoomMemberList)
} }
} }
return spaceEntryPoint.nodeBuilder(this, buildContext) return spaceEntryPoint.createNode(
.inputs(SpaceEntryPoint.Inputs(roomId = inputs.room.roomId)) parentNode = this,
.callback(callback) buildContext = buildContext,
.build() inputs = SpaceEntryPoint.Inputs(roomId = inputs.room.roomId),
callback = callback,
)
} }
private fun createMessagesNode( private fun createMessagesNode(
@@ -233,10 +239,12 @@ class JoinedRoomLoadedFlowNode(
val params = MessagesEntryPoint.Params( val params = MessagesEntryPoint.Params(
MessagesEntryPoint.InitialTarget.Messages(navTarget.focusedEventId) MessagesEntryPoint.InitialTarget.Messages(navTarget.focusedEventId)
) )
return messagesEntryPoint.nodeBuilder(this, buildContext) return messagesEntryPoint.createNode(
.params(params) parentNode = this,
.callback(callback) buildContext = buildContext,
.build() params = params,
callback = callback,
)
} }
sealed interface NavTarget : Parcelable { sealed interface NavTarget : Parcelable {

View File

@@ -19,6 +19,7 @@ import com.bumble.appyx.testing.unit.common.helper.parentNodeTestHelper
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.appnav.di.RoomGraphFactory import io.element.android.appnav.di.RoomGraphFactory
import io.element.android.appnav.room.RoomNavigationTarget import io.element.android.appnav.room.RoomNavigationTarget
import io.element.android.appnav.room.joined.FakeJoinedRoomLoadedFlowNodeCallback
import io.element.android.appnav.room.joined.JoinedRoomLoadedFlowNode import io.element.android.appnav.room.joined.JoinedRoomLoadedFlowNode
import io.element.android.features.forward.api.ForwardEntryPoint import io.element.android.features.forward.api.ForwardEntryPoint
import io.element.android.features.messages.api.MessagesEntryPoint import io.element.android.features.messages.api.MessagesEntryPoint
@@ -48,29 +49,20 @@ class JoinedRoomLoadedFlowNodeTest {
@get:Rule @get:Rule
val mainDispatcherRule = MainDispatcherRule() val mainDispatcherRule = MainDispatcherRule()
private class FakeMessagesEntryPoint : MessagesEntryPoint, MessagesEntryPoint.NodeBuilder { private class FakeMessagesEntryPoint : MessagesEntryPoint {
var buildContext: BuildContext? = null
var nodeId: String? = null var nodeId: String? = null
var parameters: MessagesEntryPoint.Params? = null var parameters: MessagesEntryPoint.Params? = null
var callback: MessagesEntryPoint.Callback? = null var callback: MessagesEntryPoint.Callback? = null
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): MessagesEntryPoint.NodeBuilder { override fun createNode(
this.buildContext = buildContext parentNode: Node,
return this buildContext: BuildContext,
} params: MessagesEntryPoint.Params,
callback: MessagesEntryPoint.Callback,
override fun params(params: MessagesEntryPoint.Params): MessagesEntryPoint.NodeBuilder { ): Node {
parameters = params parameters = params
return this
}
override fun callback(callback: MessagesEntryPoint.Callback): MessagesEntryPoint.NodeBuilder {
this.callback = callback this.callback = callback
return this return node(buildContext) {}.also {
}
override fun build(): Node {
return node(buildContext!!) {}.also {
nodeId = it.id nodeId = it.id
} }
} }
@@ -85,55 +77,36 @@ class JoinedRoomLoadedFlowNodeTest {
private class FakeRoomDetailsEntryPoint : RoomDetailsEntryPoint { private class FakeRoomDetailsEntryPoint : RoomDetailsEntryPoint {
var nodeId: String? = null var nodeId: String? = null
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): RoomDetailsEntryPoint.NodeBuilder { override fun createNode(
return object : RoomDetailsEntryPoint.NodeBuilder { parentNode: Node,
override fun params(params: RoomDetailsEntryPoint.Params): RoomDetailsEntryPoint.NodeBuilder { buildContext: BuildContext,
return this params: RoomDetailsEntryPoint.Params,
} callback: RoomDetailsEntryPoint.Callback,
) = node(buildContext) {}.also {
override fun callback(callback: RoomDetailsEntryPoint.Callback): RoomDetailsEntryPoint.NodeBuilder { nodeId = it.id
return this
}
override fun build(): Node {
return node(buildContext) {}.also {
nodeId = it.id
}
}
}
} }
} }
private class FakeSpaceEntryPoint : SpaceEntryPoint { private class FakeSpaceEntryPoint : SpaceEntryPoint {
var nodeId: String? = null var nodeId: String? = null
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): SpaceEntryPoint.NodeBuilder { override fun createNode(
return object : SpaceEntryPoint.NodeBuilder { parentNode: Node,
override fun inputs(inputs: SpaceEntryPoint.Inputs): SpaceEntryPoint.NodeBuilder { buildContext: BuildContext,
return this inputs: SpaceEntryPoint.Inputs,
} callback: SpaceEntryPoint.Callback,
) = node(buildContext) {}.also {
override fun callback(callback: SpaceEntryPoint.Callback): SpaceEntryPoint.NodeBuilder { nodeId = it.id
return this
}
override fun build(): Node {
return node(buildContext) {}.also {
nodeId = it.id
}
}
}
} }
} }
private class FakeForwardEntryPoint : ForwardEntryPoint { private class FakeForwardEntryPoint : ForwardEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): ForwardEntryPoint.NodeBuilder { override fun createNode(
return object : ForwardEntryPoint.NodeBuilder { parentNode: Node,
override fun params(params: ForwardEntryPoint.Params) = this buildContext: BuildContext,
override fun callback(callback: ForwardEntryPoint.Callback) = this params: ForwardEntryPoint.Params,
override fun build() = node(buildContext) {} callback: ForwardEntryPoint.Callback,
} ) = node(buildContext) {}
}
} }
private fun TestScope.createJoinedRoomLoadedFlowNode( private fun TestScope.createJoinedRoomLoadedFlowNode(
@@ -165,7 +138,7 @@ class JoinedRoomLoadedFlowNodeTest {
val fakeMessagesEntryPoint = FakeMessagesEntryPoint() val fakeMessagesEntryPoint = FakeMessagesEntryPoint()
val inputs = JoinedRoomLoadedFlowNode.Inputs(room, RoomNavigationTarget.Root()) val inputs = JoinedRoomLoadedFlowNode.Inputs(room, RoomNavigationTarget.Root())
val roomFlowNode = createJoinedRoomLoadedFlowNode( val roomFlowNode = createJoinedRoomLoadedFlowNode(
plugins = listOf(inputs), plugins = listOf(inputs, FakeJoinedRoomLoadedFlowNodeCallback()),
messagesEntryPoint = fakeMessagesEntryPoint, messagesEntryPoint = fakeMessagesEntryPoint,
) )
// WHEN // WHEN
@@ -185,7 +158,7 @@ class JoinedRoomLoadedFlowNodeTest {
val spaceEntryPoint = FakeSpaceEntryPoint() val spaceEntryPoint = FakeSpaceEntryPoint()
val inputs = JoinedRoomLoadedFlowNode.Inputs(room, RoomNavigationTarget.Root()) val inputs = JoinedRoomLoadedFlowNode.Inputs(room, RoomNavigationTarget.Root())
val roomFlowNode = createJoinedRoomLoadedFlowNode( val roomFlowNode = createJoinedRoomLoadedFlowNode(
plugins = listOf(inputs), plugins = listOf(inputs, FakeJoinedRoomLoadedFlowNodeCallback()),
spaceEntryPoint = spaceEntryPoint, spaceEntryPoint = spaceEntryPoint,
) )
// WHEN // WHEN
@@ -206,7 +179,7 @@ class JoinedRoomLoadedFlowNodeTest {
val fakeRoomDetailsEntryPoint = FakeRoomDetailsEntryPoint() val fakeRoomDetailsEntryPoint = FakeRoomDetailsEntryPoint()
val inputs = JoinedRoomLoadedFlowNode.Inputs(room, RoomNavigationTarget.Root()) val inputs = JoinedRoomLoadedFlowNode.Inputs(room, RoomNavigationTarget.Root())
val roomFlowNode = createJoinedRoomLoadedFlowNode( val roomFlowNode = createJoinedRoomLoadedFlowNode(
plugins = listOf(inputs), plugins = listOf(inputs, FakeJoinedRoomLoadedFlowNodeCallback()),
messagesEntryPoint = fakeMessagesEntryPoint, messagesEntryPoint = fakeMessagesEntryPoint,
roomDetailsEntryPoint = fakeRoomDetailsEntryPoint, roomDetailsEntryPoint = fakeRoomDetailsEntryPoint,
) )
@@ -228,7 +201,7 @@ class JoinedRoomLoadedFlowNodeTest {
val inputs = JoinedRoomLoadedFlowNode.Inputs(room, RoomNavigationTarget.Root()) val inputs = JoinedRoomLoadedFlowNode.Inputs(room, RoomNavigationTarget.Root())
val activeRoomsHolder = ActiveRoomsHolder() val activeRoomsHolder = ActiveRoomsHolder()
val roomFlowNode = createJoinedRoomLoadedFlowNode( val roomFlowNode = createJoinedRoomLoadedFlowNode(
plugins = listOf(inputs), plugins = listOf(inputs, FakeJoinedRoomLoadedFlowNodeCallback()),
messagesEntryPoint = fakeMessagesEntryPoint, messagesEntryPoint = fakeMessagesEntryPoint,
roomDetailsEntryPoint = fakeRoomDetailsEntryPoint, roomDetailsEntryPoint = fakeRoomDetailsEntryPoint,
activeRoomsHolder = activeRoomsHolder, activeRoomsHolder = activeRoomsHolder,
@@ -253,7 +226,7 @@ class JoinedRoomLoadedFlowNodeTest {
addRoom(room) addRoom(room)
} }
val roomFlowNode = createJoinedRoomLoadedFlowNode( val roomFlowNode = createJoinedRoomLoadedFlowNode(
plugins = listOf(inputs), plugins = listOf(inputs, FakeJoinedRoomLoadedFlowNodeCallback()),
messagesEntryPoint = fakeMessagesEntryPoint, messagesEntryPoint = fakeMessagesEntryPoint,
roomDetailsEntryPoint = fakeRoomDetailsEntryPoint, roomDetailsEntryPoint = fakeRoomDetailsEntryPoint,
activeRoomsHolder = activeRoomsHolder, activeRoomsHolder = activeRoomsHolder,

View File

@@ -0,0 +1,18 @@
/*
* Copyright 2025 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.appnav.room.joined
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.permalink.PermalinkData
import io.element.android.tests.testutils.lambda.lambdaError
class FakeJoinedRoomLoadedFlowNodeCallback : JoinedRoomLoadedFlowNode.Callback {
override fun navigateToRoom(roomId: RoomId, serverNames: List<String>) = lambdaError()
override fun handlePermalinkClick(data: PermalinkData, pushToBackstack: Boolean) = lambdaError()
override fun navigateToGlobalNotificationSettings() = lambdaError()
}

View File

@@ -15,13 +15,12 @@ import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.JoinedRoom
fun interface ChangeRoomMemberRolesEntryPoint : FeatureEntryPoint { fun interface ChangeRoomMemberRolesEntryPoint : FeatureEntryPoint {
fun builder(parentNode: Node, buildContext: BuildContext): Builder fun createNode(
parentNode: Node,
interface Builder { buildContext: BuildContext,
fun room(room: JoinedRoom): Builder room: JoinedRoom,
fun listType(changeRoomMemberRolesListType: ChangeRoomMemberRolesListType): Builder listType: ChangeRoomMemberRolesListType,
fun build(): Node ): Node
}
interface NodeProxy { interface NodeProxy {
val roomId: RoomId val roomId: RoomId

View File

@@ -18,29 +18,17 @@ import io.element.android.libraries.matrix.api.room.JoinedRoom
@ContributesBinding(SessionScope::class) @ContributesBinding(SessionScope::class)
class DefaultChangeRoomMemberRolesEntyPoint : ChangeRoomMemberRolesEntryPoint { class DefaultChangeRoomMemberRolesEntyPoint : ChangeRoomMemberRolesEntryPoint {
override fun builder(parentNode: Node, buildContext: BuildContext): ChangeRoomMemberRolesEntryPoint.Builder { override fun createNode(
return object : ChangeRoomMemberRolesEntryPoint.Builder { parentNode: Node,
private lateinit var changeRoomMemberRolesListType: ChangeRoomMemberRolesListType buildContext: BuildContext,
private lateinit var room: JoinedRoom room: JoinedRoom,
listType: ChangeRoomMemberRolesListType,
override fun room(room: JoinedRoom): ChangeRoomMemberRolesEntryPoint.Builder { ): Node {
this.room = room return parentNode.createNode<ChangeRoomMemberRolesRootNode>(
return this buildContext = buildContext,
} plugins = listOf(
ChangeRoomMemberRolesRootNode.Inputs(joinedRoom = room, listType = listType),
override fun listType(changeRoomMemberRolesListType: ChangeRoomMemberRolesListType): ChangeRoomMemberRolesEntryPoint.Builder { )
this.changeRoomMemberRolesListType = changeRoomMemberRolesListType )
return this
}
override fun build(): Node {
return parentNode.createNode<ChangeRoomMemberRolesRootNode>(
buildContext = buildContext,
plugins = listOf(
ChangeRoomMemberRolesRootNode.Inputs(joinedRoom = room, listType = changeRoomMemberRolesListType),
)
)
}
}
} }
} }

View File

@@ -31,10 +31,12 @@ class DefaultChangeRoomMemberRolesEntyPointTest {
} }
val room = FakeJoinedRoom() val room = FakeJoinedRoom()
val listType = ChangeRoomMemberRolesListType.Admins val listType = ChangeRoomMemberRolesListType.Admins
val result = entryPoint.builder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.room(FakeJoinedRoom()) parentNode = parentNode,
.listType(listType) buildContext = BuildContext.root(null),
.build() room = FakeJoinedRoom(),
listType = listType,
)
assertThat(result).isInstanceOf(ChangeRoomMemberRolesRootNode::class.java) assertThat(result).isInstanceOf(ChangeRoomMemberRolesRootNode::class.java)
// Search for the Inputs plugin // Search for the Inputs plugin
val input = result.plugins.filterIsInstance<ChangeRoomMemberRolesRootNode.Inputs>().single() val input = result.plugins.filterIsInstance<ChangeRoomMemberRolesRootNode.Inputs>().single()

View File

@@ -14,12 +14,7 @@ import io.element.android.libraries.architecture.FeatureEntryPoint
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
interface CreateRoomEntryPoint : FeatureEntryPoint { interface CreateRoomEntryPoint : FeatureEntryPoint {
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, callback: Callback): Node
interface NodeBuilder {
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
interface Callback : Plugin { interface Callback : Plugin {
fun onRoomCreated(roomId: RoomId) fun onRoomCreated(roomId: RoomId)

View File

@@ -9,7 +9,6 @@ package io.element.android.features.createroom.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.createroom.api.CreateRoomEntryPoint import io.element.android.features.createroom.api.CreateRoomEntryPoint
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
@@ -17,18 +16,7 @@ import io.element.android.libraries.di.SessionScope
@ContributesBinding(SessionScope::class) @ContributesBinding(SessionScope::class)
class DefaultCreateRoomEntryPoint : CreateRoomEntryPoint { class DefaultCreateRoomEntryPoint : CreateRoomEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): CreateRoomEntryPoint.NodeBuilder { override fun createNode(parentNode: Node, buildContext: BuildContext, callback: CreateRoomEntryPoint.Callback): Node {
val plugins = ArrayList<Plugin>() return parentNode.createNode<CreateRoomFlowNode>(buildContext, listOf(callback))
return object : CreateRoomEntryPoint.NodeBuilder {
override fun callback(callback: CreateRoomEntryPoint.Callback): CreateRoomEntryPoint.NodeBuilder {
plugins += callback
return this
}
override fun build(): Node {
return parentNode.createNode<CreateRoomFlowNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -38,9 +38,11 @@ class DefaultCreateRoomEntryPointTest {
val callback = object : CreateRoomEntryPoint.Callback { val callback = object : CreateRoomEntryPoint.Callback {
override fun onRoomCreated(roomId: RoomId) = lambdaError() override fun onRoomCreated(roomId: RoomId) = lambdaError()
} }
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.callback(callback) parentNode = parentNode,
.build() buildContext = BuildContext.root(null),
callback = callback,
)
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)
} }
} }

View File

@@ -17,12 +17,6 @@ import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.timeline.TimelineProvider import io.element.android.libraries.matrix.api.timeline.TimelineProvider
interface ForwardEntryPoint : FeatureEntryPoint { interface ForwardEntryPoint : FeatureEntryPoint {
interface NodeBuilder {
fun params(params: Params): NodeBuilder
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
interface Callback : Plugin { interface Callback : Plugin {
fun onDone(roomIds: List<RoomId>) fun onDone(roomIds: List<RoomId>)
} }
@@ -32,5 +26,5 @@ interface ForwardEntryPoint : FeatureEntryPoint {
val timelineProvider: TimelineProvider, val timelineProvider: TimelineProvider,
) : NodeInputs ) : NodeInputs
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, params: Params, callback: Callback): Node
} }

View File

@@ -9,7 +9,6 @@ package io.element.android.features.forward.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.forward.api.ForwardEntryPoint import io.element.android.features.forward.api.ForwardEntryPoint
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
@@ -17,26 +16,16 @@ import io.element.android.libraries.di.SessionScope
@ContributesBinding(SessionScope::class) @ContributesBinding(SessionScope::class)
class DefaultForwardEntryPoint : ForwardEntryPoint { class DefaultForwardEntryPoint : ForwardEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): ForwardEntryPoint.NodeBuilder { override fun createNode(parentNode: Node, buildContext: BuildContext, params: ForwardEntryPoint.Params, callback: ForwardEntryPoint.Callback): Node {
val plugins = ArrayList<Plugin>() return parentNode.createNode<ForwardMessagesNode>(
buildContext = buildContext,
return object : ForwardEntryPoint.NodeBuilder { plugins = listOf(
override fun params(params: ForwardEntryPoint.Params): ForwardEntryPoint.NodeBuilder { ForwardMessagesNode.Inputs(
plugins += ForwardMessagesNode.Inputs(
eventId = params.eventId, eventId = params.eventId,
timelineProvider = params.timelineProvider, timelineProvider = params.timelineProvider,
) ),
return this callback,
} )
)
override fun callback(callback: ForwardEntryPoint.Callback): ForwardEntryPoint.NodeBuilder {
plugins += callback
return this
}
override fun build(): Node {
return parentNode.createNode<ForwardMessagesNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -70,10 +70,12 @@ class ForwardMessagesNode(
} }
} }
return roomSelectEntryPoint.nodeBuilder(this, buildContext) return roomSelectEntryPoint.createNode(
.callback(callback) parentNode = this,
.params(RoomSelectEntryPoint.Params(mode = RoomSelectMode.Forward)) buildContext = buildContext,
.build() params = RoomSelectEntryPoint.Params(mode = RoomSelectMode.Forward),
callback = callback,
)
} }
@Composable @Composable

View File

@@ -39,9 +39,12 @@ class DefaultForwardEntryPointTest {
plugins = plugins, plugins = plugins,
presenterFactory = { _, _ -> createForwardMessagesPresenter() }, presenterFactory = { _, _ -> createForwardMessagesPresenter() },
roomSelectEntryPoint = object : RoomSelectEntryPoint { roomSelectEntryPoint = object : RoomSelectEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): RoomSelectEntryPoint.NodeBuilder { override fun createNode(
lambdaError() parentNode: Node,
} buildContext: BuildContext,
params: RoomSelectEntryPoint.Params,
callback: RoomSelectEntryPoint.Callback,
) = lambdaError()
} }
) )
} }
@@ -52,10 +55,12 @@ class DefaultForwardEntryPointTest {
eventId = AN_EVENT_ID, eventId = AN_EVENT_ID,
timelineProvider = FakeTimelineProvider(), timelineProvider = FakeTimelineProvider(),
) )
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.params(params) parentNode = parentNode,
.callback(callback) buildContext = BuildContext.root(null),
.build() params = params,
callback = callback,
)
assertThat(result).isInstanceOf(ForwardMessagesNode::class.java) assertThat(result).isInstanceOf(ForwardMessagesNode::class.java)
assertThat(result.plugins).contains( assertThat(result.plugins).contains(
ForwardMessagesNode.Inputs( ForwardMessagesNode.Inputs(

View File

@@ -110,9 +110,12 @@ class FtueFlowNode(
defaultFtueService.updateFtueStep() defaultFtueService.updateFtueStep()
} }
} }
lockScreenEntryPoint.nodeBuilder(this, buildContext, LockScreenEntryPoint.Target.Setup) lockScreenEntryPoint.createNode(
.callback(callback) parentNode = this,
.build() buildContext = buildContext,
navTarget = LockScreenEntryPoint.Target.Setup,
callback = callback,
)
} }
} }
} }

View File

@@ -103,14 +103,14 @@ class FtueSessionVerificationFlowNode(
createNode<ChooseSelfVerificationModeNode>(buildContext, plugins = listOf(callback)) createNode<ChooseSelfVerificationModeNode>(buildContext, plugins = listOf(callback))
} }
is NavTarget.UseAnotherDevice -> { is NavTarget.UseAnotherDevice -> {
outgoingVerificationEntryPoint.nodeBuilder(this, buildContext) outgoingVerificationEntryPoint.createNode(
.params( parentNode = this,
OutgoingVerificationEntryPoint.Params( buildContext = buildContext,
showDeviceVerifiedScreen = true, params = OutgoingVerificationEntryPoint.Params(
verificationRequest = VerificationRequest.Outgoing.CurrentSession, showDeviceVerifiedScreen = true,
) verificationRequest = VerificationRequest.Outgoing.CurrentSession,
) ),
.callback(object : OutgoingVerificationEntryPoint.Callback { callback = object : OutgoingVerificationEntryPoint.Callback {
override fun onDone() { override fun onDone() {
callback.onDone() callback.onDone()
} }
@@ -123,24 +123,28 @@ class FtueSessionVerificationFlowNode(
// Note that this callback is never called. The "Learn more" link is not displayed // Note that this callback is never called. The "Learn more" link is not displayed
// for the self session interactive verification. // for the self session interactive verification.
} }
}) }
.build() )
} }
is NavTarget.EnterRecoveryKey -> { is NavTarget.EnterRecoveryKey -> {
secureBackupEntryPoint.nodeBuilder(this, buildContext) secureBackupEntryPoint.createNode(
.params(SecureBackupEntryPoint.Params(SecureBackupEntryPoint.InitialTarget.EnterRecoveryKey)) parentNode = this,
.callback(secureBackupEntryPointCallback) buildContext = buildContext,
.build() params = SecureBackupEntryPoint.Params(SecureBackupEntryPoint.InitialTarget.EnterRecoveryKey),
callback = secureBackupEntryPointCallback
)
} }
is NavTarget.ResetIdentity -> { is NavTarget.ResetIdentity -> {
secureBackupEntryPoint.nodeBuilder(this, buildContext) secureBackupEntryPoint.createNode(
.params(SecureBackupEntryPoint.Params(SecureBackupEntryPoint.InitialTarget.ResetIdentity)) parentNode = this,
.callback(object : SecureBackupEntryPoint.Callback { buildContext = buildContext,
params = SecureBackupEntryPoint.Params(SecureBackupEntryPoint.InitialTarget.ResetIdentity),
callback = object : SecureBackupEntryPoint.Callback {
override fun onDone() { override fun onDone() {
callback.onDone() callback.onDone()
} }
}) },
.build() )
} }
} }
} }

View File

@@ -11,6 +11,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.testing.junit4.util.MainDispatcherRule import com.bumble.appyx.testing.junit4.util.MainDispatcherRule
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import io.element.android.features.lockscreen.api.LockScreenEntryPoint import io.element.android.features.lockscreen.api.LockScreenEntryPoint
@@ -37,13 +38,12 @@ class DefaultFtueEntryPointTest {
analyticsEntryPoint = { _, _ -> lambdaError() }, analyticsEntryPoint = { _, _ -> lambdaError() },
defaultFtueService = createDefaultFtueService(), defaultFtueService = createDefaultFtueService(),
lockScreenEntryPoint = object : LockScreenEntryPoint { lockScreenEntryPoint = object : LockScreenEntryPoint {
override fun nodeBuilder( override fun createNode(
parentNode: com.bumble.appyx.core.node.Node, parentNode: Node,
buildContext: BuildContext, buildContext: BuildContext,
navTarget: LockScreenEntryPoint.Target navTarget: LockScreenEntryPoint.Target,
): LockScreenEntryPoint.NodeBuilder { callback: LockScreenEntryPoint.Callback,
lambdaError() ) = lambdaError()
}
override fun pinUnlockIntent(context: Context): Intent { override fun pinUnlockIntent(context: Context): Intent {
lambdaError() lambdaError()

View File

@@ -14,11 +14,7 @@ import io.element.android.libraries.architecture.FeatureEntryPoint
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
interface HomeEntryPoint : FeatureEntryPoint { interface HomeEntryPoint : FeatureEntryPoint {
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, callback: Callback): Node
interface NodeBuilder {
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
interface Callback : Plugin { interface Callback : Plugin {
fun navigateToRoom(roomId: RoomId) fun navigateToRoom(roomId: RoomId)

View File

@@ -9,7 +9,6 @@ package io.element.android.features.home.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.home.api.HomeEntryPoint import io.element.android.features.home.api.HomeEntryPoint
@@ -17,18 +16,7 @@ import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultHomeEntryPoint : HomeEntryPoint { class DefaultHomeEntryPoint : HomeEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): HomeEntryPoint.NodeBuilder { override fun createNode(parentNode: Node, buildContext: BuildContext, callback: HomeEntryPoint.Callback): Node {
val plugins = ArrayList<Plugin>() return parentNode.createNode<HomeFlowNode>(buildContext, listOf(callback))
return object : HomeEntryPoint.NodeBuilder {
override fun callback(callback: HomeEntryPoint.Callback): HomeEntryPoint.NodeBuilder {
plugins += callback
return this
}
override fun build(): Node {
return parentNode.createNode<HomeFlowNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -190,10 +190,12 @@ class HomeFlowNode(
is NavTarget.DeclineInviteAndBlockUser -> declineInviteAndBlockUserEntryPoint.createNode(this, buildContext, navTarget.inviteData) is NavTarget.DeclineInviteAndBlockUser -> declineInviteAndBlockUserEntryPoint.createNode(this, buildContext, navTarget.inviteData)
is NavTarget.SelectNewOwnersWhenLeavingRoom -> { is NavTarget.SelectNewOwnersWhenLeavingRoom -> {
val room = runBlocking { matrixClient.getJoinedRoom(navTarget.roomId) } ?: error("Room ${navTarget.roomId} not found") val room = runBlocking { matrixClient.getJoinedRoom(navTarget.roomId) } ?: error("Room ${navTarget.roomId} not found")
changeRoomMemberRolesEntryPoint.builder(this, buildContext) changeRoomMemberRolesEntryPoint.createNode(
.room(room) parentNode = this,
.listType(ChangeRoomMemberRolesListType.SelectNewOwnersWhenLeaving) buildContext = buildContext,
.build() room = room,
listType = ChangeRoomMemberRolesListType.SelectNewOwnersWhenLeaving,
)
} }
NavTarget.Root -> rootNode(buildContext) NavTarget.Root -> rootNode(buildContext)
} }

View File

@@ -36,7 +36,7 @@ class DefaultHomeEntryPointTest {
directLogoutView = { _ -> lambdaError() }, directLogoutView = { _ -> lambdaError() },
reportRoomEntryPoint = { _, _, _ -> lambdaError() }, reportRoomEntryPoint = { _, _, _ -> lambdaError() },
declineInviteAndBlockUserEntryPoint = { _, _, _ -> lambdaError() }, declineInviteAndBlockUserEntryPoint = { _, _, _ -> lambdaError() },
changeRoomMemberRolesEntryPoint = { _, _ -> lambdaError() }, changeRoomMemberRolesEntryPoint = { _, _, _, _ -> lambdaError() },
leaveRoomRenderer = { _, _, _ -> lambdaError() }, leaveRoomRenderer = { _, _, _ -> lambdaError() },
) )
} }
@@ -49,9 +49,11 @@ class DefaultHomeEntryPointTest {
override fun navigateToRoomSettings(roomId: RoomId) = lambdaError() override fun navigateToRoomSettings(roomId: RoomId) = lambdaError()
override fun navigateToBugReport() = lambdaError() override fun navigateToBugReport() = lambdaError()
} }
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.callback(callback) parentNode = parentNode,
.build() buildContext = BuildContext.root(null),
callback = callback,
)
assertThat(result).isInstanceOf(HomeFlowNode::class.java) assertThat(result).isInstanceOf(HomeFlowNode::class.java)
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)
} }

View File

@@ -18,8 +18,9 @@ import io.element.android.libraries.matrix.api.timeline.Timeline
* Allows a user to share a location message within a room. * Allows a user to share a location message within a room.
*/ */
interface SendLocationEntryPoint : FeatureEntryPoint { interface SendLocationEntryPoint : FeatureEntryPoint {
fun builder(timelineMode: Timeline.Mode): Builder fun createNode(
interface Builder { parentNode: Node,
fun build(parentNode: Node, buildContext: BuildContext): Node buildContext: BuildContext,
} timelineMode: Timeline.Mode,
): Node
} }

View File

@@ -17,16 +17,14 @@ import io.element.android.libraries.matrix.api.timeline.Timeline
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultSendLocationEntryPoint : SendLocationEntryPoint { class DefaultSendLocationEntryPoint : SendLocationEntryPoint {
override fun builder(timelineMode: Timeline.Mode): SendLocationEntryPoint.Builder { override fun createNode(
return Builder(timelineMode) parentNode: Node,
} buildContext: BuildContext,
timelineMode: Timeline.Mode,
class Builder(private val timelineMode: Timeline.Mode) : SendLocationEntryPoint.Builder { ): Node {
override fun build(parentNode: Node, buildContext: BuildContext): Node { return parentNode.createNode<SendLocationNode>(
return parentNode.createNode<SendLocationNode>( buildContext = buildContext,
buildContext = buildContext, plugins = listOf(SendLocationNode.Inputs(timelineMode))
plugins = listOf(SendLocationNode.Inputs(timelineMode)) )
)
}
} }
} }

View File

@@ -47,8 +47,11 @@ class DefaultSendLocationEntryPointTest {
) )
} }
val timelineMode = Timeline.Mode.Live val timelineMode = Timeline.Mode.Live
val result = entryPoint.builder(timelineMode) val result = entryPoint.createNode(
.build(parentNode, BuildContext.root(null)) parentNode = parentNode,
buildContext = BuildContext.root(null),
timelineMode = timelineMode,
)
assertThat(result).isInstanceOf(SendLocationNode::class.java) assertThat(result).isInstanceOf(SendLocationNode::class.java)
assertThat(result.plugins).contains(SendLocationNode.Inputs(timelineMode)) assertThat(result.plugins).contains(SendLocationNode.Inputs(timelineMode))
} }

View File

@@ -15,14 +15,9 @@ import com.bumble.appyx.core.plugin.Plugin
import io.element.android.libraries.architecture.FeatureEntryPoint import io.element.android.libraries.architecture.FeatureEntryPoint
interface LockScreenEntryPoint : FeatureEntryPoint { interface LockScreenEntryPoint : FeatureEntryPoint {
fun nodeBuilder(parentNode: Node, buildContext: BuildContext, navTarget: Target): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, navTarget: Target, callback: Callback): Node
fun pinUnlockIntent(context: Context): Intent fun pinUnlockIntent(context: Context): Intent
interface NodeBuilder {
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
interface Callback : Plugin { interface Callback : Plugin {
fun onSetupDone() fun onSetupDone()
} }

View File

@@ -19,26 +19,24 @@ import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultLockScreenEntryPoint : LockScreenEntryPoint { class DefaultLockScreenEntryPoint : LockScreenEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext, navTarget: LockScreenEntryPoint.Target): LockScreenEntryPoint.NodeBuilder { override fun createNode(
val callbacks = mutableListOf<LockScreenEntryPoint.Callback>() parentNode: Node,
buildContext: BuildContext,
return object : LockScreenEntryPoint.NodeBuilder { navTarget: LockScreenEntryPoint.Target,
override fun callback(callback: LockScreenEntryPoint.Callback): LockScreenEntryPoint.NodeBuilder { callback: LockScreenEntryPoint.Callback,
callbacks += callback ): Node {
return this return parentNode.createNode<LockScreenFlowNode>(
} buildContext = buildContext,
plugins = listOf(
override fun build(): Node { LockScreenFlowNode.Inputs(
val inputs = LockScreenFlowNode.Inputs(
when (navTarget) { when (navTarget) {
LockScreenEntryPoint.Target.Setup -> LockScreenFlowNode.NavTarget.Setup LockScreenEntryPoint.Target.Setup -> LockScreenFlowNode.NavTarget.Setup
LockScreenEntryPoint.Target.Settings -> LockScreenFlowNode.NavTarget.Settings LockScreenEntryPoint.Target.Settings -> LockScreenFlowNode.NavTarget.Settings
} }
) ),
val plugins = listOf(inputs) + callbacks callback,
return parentNode.createNode<LockScreenFlowNode>(buildContext, plugins) )
} )
}
} }
override fun pinUnlockIntent(context: Context): Intent { override fun pinUnlockIntent(context: Context): Intent {

View File

@@ -37,9 +37,12 @@ class DefaultLockScreenEntryPointTest {
override fun onSetupDone() = lambdaError() override fun onSetupDone() = lambdaError()
} }
val navTarget = LockScreenEntryPoint.Target.Setup val navTarget = LockScreenEntryPoint.Target.Setup
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null), navTarget) val result = entryPoint.createNode(
.callback(callback) parentNode = parentNode,
.build() buildContext = BuildContext.root(null),
navTarget = navTarget,
callback = callback,
)
assertThat(result).isInstanceOf(LockScreenFlowNode::class.java) assertThat(result).isInstanceOf(LockScreenFlowNode::class.java)
assertThat(result.plugins).contains(LockScreenFlowNode.Inputs(LockScreenFlowNode.NavTarget.Setup)) assertThat(result.plugins).contains(LockScreenFlowNode.Inputs(LockScreenFlowNode.NavTarget.Setup))
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)
@@ -58,9 +61,12 @@ class DefaultLockScreenEntryPointTest {
override fun onSetupDone() = lambdaError() override fun onSetupDone() = lambdaError()
} }
val navTarget = LockScreenEntryPoint.Target.Settings val navTarget = LockScreenEntryPoint.Target.Settings
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null), navTarget) val result = entryPoint.createNode(
.callback(callback) parentNode = parentNode,
.build() buildContext = BuildContext.root(null),
navTarget = navTarget,
callback = callback,
)
assertThat(result).isInstanceOf(LockScreenFlowNode::class.java) assertThat(result).isInstanceOf(LockScreenFlowNode::class.java)
assertThat(result.plugins).contains(LockScreenFlowNode.Inputs(LockScreenFlowNode.NavTarget.Settings)) assertThat(result.plugins).contains(LockScreenFlowNode.Inputs(LockScreenFlowNode.NavTarget.Settings))
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)

View File

@@ -22,11 +22,5 @@ interface LoginEntryPoint : FeatureEntryPoint {
fun navigateToBugReport() fun navigateToBugReport()
} }
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, params: Params, callback: Callback): Node
interface NodeBuilder {
fun params(params: Params): NodeBuilder
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
} }

View File

@@ -9,7 +9,6 @@ package io.element.android.features.login.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.login.api.LoginEntryPoint import io.element.android.features.login.api.LoginEntryPoint
@@ -17,26 +16,16 @@ import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultLoginEntryPoint : LoginEntryPoint { class DefaultLoginEntryPoint : LoginEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): LoginEntryPoint.NodeBuilder { override fun createNode(parentNode: Node, buildContext: BuildContext, params: LoginEntryPoint.Params, callback: LoginEntryPoint.Callback): Node {
val plugins = ArrayList<Plugin>() return parentNode.createNode<LoginFlowNode>(
buildContext = buildContext,
return object : LoginEntryPoint.NodeBuilder { plugins = listOf(
override fun params(params: LoginEntryPoint.Params): LoginEntryPoint.NodeBuilder { LoginFlowNode.Params(
plugins += LoginFlowNode.Params(
accountProvider = params.accountProvider, accountProvider = params.accountProvider,
loginHint = params.loginHint, loginHint = params.loginHint,
) ),
return this callback,
} )
)
override fun callback(callback: LoginEntryPoint.Callback): LoginEntryPoint.NodeBuilder {
plugins += callback
return this
}
override fun build(): Node {
return parentNode.createNode<LoginFlowNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -45,10 +45,12 @@ class DefaultLoginEntryPointTest {
accountProvider = "ac", accountProvider = "ac",
loginHint = "lh", loginHint = "lh",
) )
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.params(params) parentNode = parentNode,
.callback(callback) buildContext = BuildContext.root(null),
.build() params = params,
callback = callback,
)
assertThat(result).isInstanceOf(LoginFlowNode::class.java) assertThat(result).isInstanceOf(LoginFlowNode::class.java)
assertThat(result.plugins).contains(LoginFlowNode.Params(params.accountProvider, params.loginHint)) assertThat(result.plugins).contains(LoginFlowNode.Params(params.accountProvider, params.loginHint))
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)

View File

@@ -13,12 +13,7 @@ import com.bumble.appyx.core.plugin.Plugin
import io.element.android.libraries.architecture.FeatureEntryPoint import io.element.android.libraries.architecture.FeatureEntryPoint
interface LogoutEntryPoint : FeatureEntryPoint { interface LogoutEntryPoint : FeatureEntryPoint {
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, callback: Callback): Node
interface NodeBuilder {
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
interface Callback : Plugin { interface Callback : Plugin {
fun navigateToSecureBackup() fun navigateToSecureBackup()

View File

@@ -9,7 +9,6 @@ package io.element.android.features.logout.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.logout.api.LogoutEntryPoint import io.element.android.features.logout.api.LogoutEntryPoint
@@ -17,18 +16,7 @@ import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultLogoutEntryPoint : LogoutEntryPoint { class DefaultLogoutEntryPoint : LogoutEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): LogoutEntryPoint.NodeBuilder { override fun createNode(parentNode: Node, buildContext: BuildContext, callback: LogoutEntryPoint.Callback): Node {
val plugins = ArrayList<Plugin>() return parentNode.createNode<LogoutNode>(buildContext, listOf(callback))
return object : LogoutEntryPoint.NodeBuilder {
override fun callback(callback: LogoutEntryPoint.Callback): LogoutEntryPoint.NodeBuilder {
plugins += callback
return this
}
override fun build(): Node {
return parentNode.createNode<LogoutNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -34,9 +34,11 @@ class DefaultLogoutEntryPointTest {
val callback = object : LogoutEntryPoint.Callback { val callback = object : LogoutEntryPoint.Callback {
override fun navigateToSecureBackup() = lambdaError() override fun navigateToSecureBackup() = lambdaError()
} }
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.callback(callback) parentNode = parentNode,
.build() buildContext = BuildContext.root(null),
callback = callback,
)
assertThat(result).isInstanceOf(LogoutNode::class.java) assertThat(result).isInstanceOf(LogoutNode::class.java)
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)
} }

View File

@@ -31,12 +31,6 @@ interface MessagesEntryPoint : FeatureEntryPoint {
data object PinnedMessages : InitialTarget data object PinnedMessages : InitialTarget
} }
interface NodeBuilder {
fun params(params: Params): NodeBuilder
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
interface Callback : Plugin { interface Callback : Plugin {
fun navigateToRoomDetails() fun navigateToRoomDetails()
fun navigateToRoomMemberDetails(userId: UserId) fun navigateToRoomMemberDetails(userId: UserId)
@@ -47,7 +41,7 @@ interface MessagesEntryPoint : FeatureEntryPoint {
data class Params(val initialTarget: InitialTarget) : NodeInputs data class Params(val initialTarget: InitialTarget) : NodeInputs
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, params: Params, callback: Callback): Node
} }
interface MessagesEntryPointNode { interface MessagesEntryPointNode {

View File

@@ -9,34 +9,15 @@ package io.element.android.features.messages.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.messages.api.MessagesEntryPoint import io.element.android.features.messages.api.MessagesEntryPoint
import io.element.android.libraries.architecture.NodeFactoriesBindings import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.architecture.bindings
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
@ContributesBinding(SessionScope::class) @ContributesBinding(SessionScope::class)
class DefaultMessagesEntryPoint : MessagesEntryPoint { class DefaultMessagesEntryPoint : MessagesEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): MessagesEntryPoint.NodeBuilder { override fun createNode(parentNode: Node, buildContext: BuildContext, params: MessagesEntryPoint.Params, callback: MessagesEntryPoint.Callback): Node {
val nodeFactories = parentNode.bindings<NodeFactoriesBindings>().nodeFactories() return parentNode.createNode<MessagesFlowNode>(buildContext, listOf(params, callback))
val plugins = ArrayList<Plugin>()
return object : MessagesEntryPoint.NodeBuilder {
override fun params(params: MessagesEntryPoint.Params): MessagesEntryPoint.NodeBuilder {
plugins += MessagesEntryPoint.Params(params.initialTarget)
return this
}
override fun callback(callback: MessagesEntryPoint.Callback): MessagesEntryPoint.NodeBuilder {
plugins += callback
return this
}
override fun build(): Node {
return nodeFactories[MessagesFlowNode::class]!!.create(buildContext, plugins)
}
}
} }
} }

View File

@@ -320,10 +320,12 @@ class MessagesFlowNode(
callback.forwardEvent(eventId) callback.forwardEvent(eventId)
} }
} }
mediaViewerEntryPoint.nodeBuilder(this, buildContext) mediaViewerEntryPoint.createNode(
.params(params) parentNode = this,
.callback(callback) buildContext = buildContext,
.build() params = params,
callback = callback
)
} }
is NavTarget.AttachmentPreview -> { is NavTarget.AttachmentPreview -> {
val inputs = AttachmentsPreviewNode.Inputs( val inputs = AttachmentsPreviewNode.Inputs(
@@ -356,39 +358,43 @@ class MessagesFlowNode(
} }
} }
} }
forwardEntryPoint.nodeBuilder(this, buildContext) forwardEntryPoint.createNode(
.params(params) parentNode = this,
.callback(callback) buildContext = buildContext,
.build() params = params,
callback = callback,
)
} }
is NavTarget.ReportMessage -> { is NavTarget.ReportMessage -> {
val inputs = ReportMessageNode.Inputs(navTarget.eventId, navTarget.senderId) val inputs = ReportMessageNode.Inputs(navTarget.eventId, navTarget.senderId)
createNode<ReportMessageNode>(buildContext, listOf(inputs)) createNode<ReportMessageNode>(buildContext, listOf(inputs))
} }
is NavTarget.SendLocation -> { is NavTarget.SendLocation -> {
sendLocationEntryPoint sendLocationEntryPoint.createNode(
.builder(navTarget.timelineMode) parentNode = this,
.build(this, buildContext) buildContext = buildContext,
timelineMode = navTarget.timelineMode,
)
} }
is NavTarget.CreatePoll -> { is NavTarget.CreatePoll -> {
createPollEntryPoint.nodeBuilder(this, buildContext) createPollEntryPoint.createNode(
.params( parentNode = this,
CreatePollEntryPoint.Params( buildContext = buildContext,
timelineMode = navTarget.timelineMode, params = CreatePollEntryPoint.Params(
mode = CreatePollMode.NewPoll timelineMode = navTarget.timelineMode,
) mode = CreatePollMode.NewPoll
) ),
.build() )
} }
is NavTarget.EditPoll -> { is NavTarget.EditPoll -> {
createPollEntryPoint.nodeBuilder(this, buildContext) createPollEntryPoint.createNode(
.params( parentNode = this,
CreatePollEntryPoint.Params( buildContext = buildContext,
timelineMode = navTarget.timelineMode, params = CreatePollEntryPoint.Params(
mode = CreatePollMode.EditPoll(eventId = navTarget.eventId) timelineMode = navTarget.timelineMode,
) mode = CreatePollMode.EditPoll(eventId = navTarget.eventId)
) ),
.build() )
} }
NavTarget.PinnedMessagesList -> { NavTarget.PinnedMessagesList -> {
val callback = object : PinnedMessagesListNode.Callback { val callback = object : PinnedMessagesListNode.Callback {

View File

@@ -24,6 +24,7 @@ import io.element.android.features.messages.api.MessagesEntryPoint
import io.element.android.features.messages.impl.pinned.banner.createPinnedEventsTimelineProvider import io.element.android.features.messages.impl.pinned.banner.createPinnedEventsTimelineProvider
import io.element.android.features.messages.impl.timeline.createTimelineController import io.element.android.features.messages.impl.timeline.createTimelineController
import io.element.android.features.poll.api.create.CreatePollEntryPoint import io.element.android.features.poll.api.create.CreatePollEntryPoint
import io.element.android.features.poll.api.create.CreatePollEntryPoint.Params
import io.element.android.libraries.dateformatter.test.FakeDateFormatter import io.element.android.libraries.dateformatter.test.FakeDateFormatter
import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
@@ -65,13 +66,21 @@ class DefaultMessagesEntryPointTest {
roomListService = FakeRoomListService(), roomListService = FakeRoomListService(),
sessionId = A_SESSION_ID, sessionId = A_SESSION_ID,
sendLocationEntryPoint = object : SendLocationEntryPoint { sendLocationEntryPoint = object : SendLocationEntryPoint {
override fun builder(timelineMode: Timeline.Mode) = lambdaError() override fun createNode(
parentNode: Node,
buildContext: BuildContext,
timelineMode: Timeline.Mode,
) = lambdaError()
}, },
showLocationEntryPoint = object : ShowLocationEntryPoint { showLocationEntryPoint = object : ShowLocationEntryPoint {
override fun createNode(parentNode: Node, buildContext: BuildContext, inputs: ShowLocationEntryPoint.Inputs) = lambdaError() override fun createNode(parentNode: Node, buildContext: BuildContext, inputs: ShowLocationEntryPoint.Inputs) = lambdaError()
}, },
createPollEntryPoint = object : CreatePollEntryPoint { createPollEntryPoint = object : CreatePollEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError() override fun createNode(
parentNode: Node,
buildContext: BuildContext,
params: Params,
) = lambdaError()
}, },
elementCallEntryPoint = object : ElementCallEntryPoint { elementCallEntryPoint = object : ElementCallEntryPoint {
override fun startCall(callType: CallType) = lambdaError() override fun startCall(callType: CallType) = lambdaError()
@@ -89,10 +98,21 @@ class DefaultMessagesEntryPointTest {
) = lambdaError() ) = lambdaError()
}, },
mediaViewerEntryPoint = object : MediaViewerEntryPoint { mediaViewerEntryPoint = object : MediaViewerEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError() override fun createParamsForAvatar(filename: String, avatarUrl: String) = lambdaError()
override fun createNode(
parentNode: Node,
buildContext: BuildContext,
params: MediaViewerEntryPoint.Params,
callback: MediaViewerEntryPoint.Callback,
) = lambdaError()
}, },
forwardEntryPoint = object : ForwardEntryPoint { forwardEntryPoint = object : ForwardEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError() override fun createNode(
parentNode: Node,
buildContext: BuildContext,
params: ForwardEntryPoint.Params,
callback: ForwardEntryPoint.Callback,
) = lambdaError()
}, },
analyticsService = FakeAnalyticsService(), analyticsService = FakeAnalyticsService(),
locationService = FakeLocationService(), locationService = FakeLocationService(),
@@ -124,10 +144,12 @@ class DefaultMessagesEntryPointTest {
} }
val initialTarget = MessagesEntryPoint.InitialTarget.Messages(focusedEventId = AN_EVENT_ID) val initialTarget = MessagesEntryPoint.InitialTarget.Messages(focusedEventId = AN_EVENT_ID)
val params = MessagesEntryPoint.Params(initialTarget) val params = MessagesEntryPoint.Params(initialTarget)
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.params(params) parentNode = parentNode,
.callback(callback) buildContext = BuildContext.root(null),
.build() params = params,
callback = callback,
)
assertThat(result).isInstanceOf(MessagesFlowNode::class.java) assertThat(result).isInstanceOf(MessagesFlowNode::class.java)
assertThat(result.plugins).contains(MessagesEntryPoint.Params(initialTarget)) assertThat(result.plugins).contains(MessagesEntryPoint.Params(initialTarget))
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)

View File

@@ -18,10 +18,5 @@ interface CreatePollEntryPoint : FeatureEntryPoint {
val mode: CreatePollMode, val mode: CreatePollMode,
) )
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, params: Params): Node
interface NodeBuilder {
fun params(params: Params): NodeBuilder
fun build(): Node
}
} }

View File

@@ -9,7 +9,6 @@ package io.element.android.features.poll.impl.create
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.poll.api.create.CreatePollEntryPoint import io.element.android.features.poll.api.create.CreatePollEntryPoint
@@ -17,18 +16,10 @@ import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultCreatePollEntryPoint : CreatePollEntryPoint { class DefaultCreatePollEntryPoint : CreatePollEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): CreatePollEntryPoint.NodeBuilder { override fun createNode(parentNode: Node, buildContext: BuildContext, params: CreatePollEntryPoint.Params): Node {
val plugins = ArrayList<Plugin>() return parentNode.createNode<CreatePollNode>(
buildContext = buildContext,
return object : CreatePollEntryPoint.NodeBuilder { plugins = listOf(CreatePollNode.Inputs(timelineMode = params.timelineMode, mode = params.mode))
override fun params(params: CreatePollEntryPoint.Params): CreatePollEntryPoint.NodeBuilder { )
plugins += CreatePollNode.Inputs(timelineMode = params.timelineMode, mode = params.mode)
return this
}
override fun build(): Node {
return parentNode.createNode<CreatePollNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -53,14 +53,14 @@ class PollHistoryFlowNode(
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
return when (navTarget) { return when (navTarget) {
is NavTarget.EditPoll -> { is NavTarget.EditPoll -> {
createPollEntryPoint.nodeBuilder(this, buildContext) createPollEntryPoint.createNode(
.params( parentNode = this,
CreatePollEntryPoint.Params( buildContext = buildContext,
params = CreatePollEntryPoint.Params(
timelineMode = Timeline.Mode.Live, timelineMode = Timeline.Mode.Live,
mode = CreatePollMode.EditPoll(eventId = navTarget.pollStartEventId) mode = CreatePollMode.EditPoll(eventId = navTarget.pollStartEventId)
)
) )
.build() )
} }
NavTarget.Root -> { NavTarget.Root -> {
val callback = object : PollHistoryNode.Callback { val callback = object : PollHistoryNode.Callback {

View File

@@ -53,9 +53,11 @@ class DefaultCreatePollEntryPointTest {
timelineMode = Timeline.Mode.Live, timelineMode = Timeline.Mode.Live,
mode = CreatePollMode.NewPoll, mode = CreatePollMode.NewPoll,
) )
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.params(params) parentNode = parentNode,
.build() buildContext = BuildContext.root(null),
params = params,
)
assertThat(result).isInstanceOf(CreatePollNode::class.java) assertThat(result).isInstanceOf(CreatePollNode::class.java)
assertThat(result.plugins).contains(CreatePollNode.Inputs(timelineMode = params.timelineMode, mode = params.mode)) assertThat(result.plugins).contains(CreatePollNode.Inputs(timelineMode = params.timelineMode, mode = params.mode))
} }

View File

@@ -34,7 +34,11 @@ class DefaultPollHistoryEntryPointTest {
buildContext = buildContext, buildContext = buildContext,
plugins = plugins, plugins = plugins,
createPollEntryPoint = object : CreatePollEntryPoint { createPollEntryPoint = object : CreatePollEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError() override fun createNode(
parentNode: Node,
buildContext: BuildContext,
params: CreatePollEntryPoint.Params,
) = lambdaError()
} }
) )
} }

View File

@@ -31,13 +31,7 @@ interface PreferencesEntryPoint : FeatureEntryPoint {
data class Params(val initialElement: InitialTarget) : NodeInputs data class Params(val initialElement: InitialTarget) : NodeInputs
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, params: Params, callback: Callback): Node
interface NodeBuilder {
fun params(params: Params): NodeBuilder
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
interface Callback : Plugin { interface Callback : Plugin {
fun navigateToAddAccount() fun navigateToAddAccount()

View File

@@ -9,7 +9,6 @@ package io.element.android.features.preferences.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.preferences.api.PreferencesEntryPoint import io.element.android.features.preferences.api.PreferencesEntryPoint
@@ -17,24 +16,16 @@ import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultPreferencesEntryPoint : PreferencesEntryPoint { class DefaultPreferencesEntryPoint : PreferencesEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): PreferencesEntryPoint.NodeBuilder { override fun createNode(
return object : PreferencesEntryPoint.NodeBuilder { parentNode: Node,
val plugins = ArrayList<Plugin>() buildContext: BuildContext,
params: PreferencesEntryPoint.Params,
override fun params(params: PreferencesEntryPoint.Params): PreferencesEntryPoint.NodeBuilder { callback: PreferencesEntryPoint.Callback,
plugins += params ): Node {
return this return parentNode.createNode<PreferencesFlowNode>(
} buildContext = buildContext,
plugins = listOf(params, callback)
override fun callback(callback: PreferencesEntryPoint.Callback): PreferencesEntryPoint.NodeBuilder { )
plugins += callback
return this
}
override fun build(): Node {
return parentNode.createNode<PreferencesFlowNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -215,8 +215,10 @@ class PreferencesFlowNode(
createNode<NotificationSettingsNode>(buildContext, listOf(notificationSettingsCallback)) createNode<NotificationSettingsNode>(buildContext, listOf(notificationSettingsCallback))
} }
NavTarget.TroubleshootNotifications -> { NavTarget.TroubleshootNotifications -> {
notificationTroubleShootEntryPoint.nodeBuilder(this, buildContext) notificationTroubleShootEntryPoint.createNode(
.callback(object : NotificationTroubleShootEntryPoint.Callback { parentNode = this,
buildContext = buildContext,
callback = object : NotificationTroubleShootEntryPoint.Callback {
override fun onDone() { override fun onDone() {
if (backstack.canPop()) { if (backstack.canPop()) {
backstack.pop() backstack.pop()
@@ -228,12 +230,14 @@ class PreferencesFlowNode(
override fun navigateToBlockedUsers() { override fun navigateToBlockedUsers() {
backstack.push(NavTarget.BlockedUsers) backstack.push(NavTarget.BlockedUsers)
} }
}) },
.build() )
} }
NavTarget.PushHistory -> { NavTarget.PushHistory -> {
pushHistoryEntryPoint.nodeBuilder(this, buildContext) pushHistoryEntryPoint.createNode(
.callback(object : PushHistoryEntryPoint.Callback { this,
buildContext,
object : PushHistoryEntryPoint.Callback {
override fun onDone() { override fun onDone() {
if (backstack.canPop()) { if (backstack.canPop()) {
backstack.pop() backstack.pop()
@@ -245,8 +249,8 @@ class PreferencesFlowNode(
override fun navigateToEvent(roomId: RoomId, eventId: EventId) { override fun navigateToEvent(roomId: RoomId, eventId: EventId) {
callback.navigateToEvent(roomId, eventId) callback.navigateToEvent(roomId, eventId)
} }
}) },
.build() )
} }
is NavTarget.EditDefaultNotificationSetting -> { is NavTarget.EditDefaultNotificationSetting -> {
val callback = object : EditDefaultNotificationSettingNode.Callback { val callback = object : EditDefaultNotificationSettingNode.Callback {
@@ -265,7 +269,16 @@ class PreferencesFlowNode(
createNode<EditUserProfileNode>(buildContext, listOf(inputs)) createNode<EditUserProfileNode>(buildContext, listOf(inputs))
} }
NavTarget.LockScreenSettings -> { NavTarget.LockScreenSettings -> {
lockScreenEntryPoint.nodeBuilder(this, buildContext, LockScreenEntryPoint.Target.Settings).build() lockScreenEntryPoint.createNode(
parentNode = this,
buildContext = buildContext,
navTarget = LockScreenEntryPoint.Target.Settings,
callback = object : LockScreenEntryPoint.Callback {
override fun onSetupDone() {
// No op
}
}
)
} }
NavTarget.BlockedUsers -> { NavTarget.BlockedUsers -> {
createNode<BlockedUsersNode>(buildContext) createNode<BlockedUsersNode>(buildContext)
@@ -276,9 +289,11 @@ class PreferencesFlowNode(
callback.navigateToSecureBackup() callback.navigateToSecureBackup()
} }
} }
logoutEntryPoint.nodeBuilder(this, buildContext) logoutEntryPoint.createNode(
.callback(callBack) parentNode = this,
.build() buildContext = buildContext,
callback = callBack,
)
} }
is NavTarget.OssLicenses -> { is NavTarget.OssLicenses -> {
openSourceLicensesEntryPoint.createNode(this, buildContext) openSourceLicensesEntryPoint.createNode(this, buildContext)

View File

@@ -42,17 +42,35 @@ class DefaultPreferencesEntryPointTest {
buildContext = buildContext, buildContext = buildContext,
plugins = plugins, plugins = plugins,
lockScreenEntryPoint = object : LockScreenEntryPoint { lockScreenEntryPoint = object : LockScreenEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext, navTarget: LockScreenEntryPoint.Target) = lambdaError() override fun createNode(
parentNode: Node,
buildContext: BuildContext,
navTarget: LockScreenEntryPoint.Target,
callback: LockScreenEntryPoint.Callback,
) = lambdaError()
override fun pinUnlockIntent(context: Context) = lambdaError() override fun pinUnlockIntent(context: Context) = lambdaError()
}, },
notificationTroubleShootEntryPoint = object : NotificationTroubleShootEntryPoint { notificationTroubleShootEntryPoint = object : NotificationTroubleShootEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError() override fun createNode(
parentNode: Node,
buildContext: BuildContext,
callback: NotificationTroubleShootEntryPoint.Callback,
) = lambdaError()
}, },
pushHistoryEntryPoint = object : PushHistoryEntryPoint { pushHistoryEntryPoint = object : PushHistoryEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError() override fun createNode(
parentNode: Node,
buildContext: BuildContext,
callback: PushHistoryEntryPoint.Callback,
) = lambdaError()
}, },
logoutEntryPoint = object : LogoutEntryPoint { logoutEntryPoint = object : LogoutEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError() override fun createNode(
parentNode: Node,
buildContext: BuildContext,
callback: LogoutEntryPoint.Callback,
) = lambdaError()
}, },
openSourceLicensesEntryPoint = object : OpenSourceLicensesEntryPoint { openSourceLicensesEntryPoint = object : OpenSourceLicensesEntryPoint {
override fun createNode(parentNode: Node, buildContext: BuildContext) = lambdaError() override fun createNode(parentNode: Node, buildContext: BuildContext) = lambdaError()
@@ -72,10 +90,12 @@ class DefaultPreferencesEntryPointTest {
val params = PreferencesEntryPoint.Params( val params = PreferencesEntryPoint.Params(
initialElement = PreferencesEntryPoint.InitialTarget.NotificationSettings, initialElement = PreferencesEntryPoint.InitialTarget.NotificationSettings,
) )
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.params(params) parentNode = parentNode,
.callback(callback) buildContext = BuildContext.root(null),
.build() params = params,
callback = callback,
)
assertThat(result).isInstanceOf(PreferencesFlowNode::class.java) assertThat(result).isInstanceOf(PreferencesFlowNode::class.java)
assertThat(result.plugins).contains(params) assertThat(result.plugins).contains(params)
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)

View File

@@ -13,12 +13,7 @@ import com.bumble.appyx.core.plugin.Plugin
import io.element.android.libraries.architecture.FeatureEntryPoint import io.element.android.libraries.architecture.FeatureEntryPoint
interface BugReportEntryPoint : FeatureEntryPoint { interface BugReportEntryPoint : FeatureEntryPoint {
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, callback: Callback): Node
interface NodeBuilder {
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
interface Callback : Plugin { interface Callback : Plugin {
fun onDone() fun onDone()

View File

@@ -77,11 +77,12 @@ class BugReportFlowNode(
val params = ViewFolderEntryPoint.Params( val params = ViewFolderEntryPoint.Params(
rootPath = navTarget.rootPath, rootPath = navTarget.rootPath,
) )
viewFolderEntryPoint viewFolderEntryPoint.createNode(
.nodeBuilder(this, buildContext) parentNode = this,
.params(params) buildContext = buildContext,
.callback(callback) params = params,
.build() callback = callback,
)
} }
} }
} }

View File

@@ -9,7 +9,6 @@ package io.element.android.features.rageshake.impl.bugreport
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.rageshake.api.bugreport.BugReportEntryPoint import io.element.android.features.rageshake.api.bugreport.BugReportEntryPoint
@@ -17,18 +16,7 @@ import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultBugReportEntryPoint : BugReportEntryPoint { class DefaultBugReportEntryPoint : BugReportEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): BugReportEntryPoint.NodeBuilder { override fun createNode(parentNode: Node, buildContext: BuildContext, callback: BugReportEntryPoint.Callback): Node {
val plugins = ArrayList<Plugin>() return parentNode.createNode<BugReportFlowNode>(buildContext, listOf(callback))
return object : BugReportEntryPoint.NodeBuilder {
override fun callback(callback: BugReportEntryPoint.Callback): BugReportEntryPoint.NodeBuilder {
plugins += callback
return this
}
override fun build(): Node {
return parentNode.createNode<BugReportFlowNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -35,16 +35,23 @@ class DefaultBugReportEntryPointTest {
buildContext = buildContext, buildContext = buildContext,
plugins = plugins, plugins = plugins,
viewFolderEntryPoint = object : ViewFolderEntryPoint { viewFolderEntryPoint = object : ViewFolderEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError() override fun createNode(
parentNode: Node,
buildContext: BuildContext,
params: ViewFolderEntryPoint.Params,
callback: ViewFolderEntryPoint.Callback,
) = lambdaError()
}, },
) )
} }
val callback = object : BugReportEntryPoint.Callback { val callback = object : BugReportEntryPoint.Callback {
override fun onDone() = lambdaError() override fun onDone() = lambdaError()
} }
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.callback(callback) parentNode = parentNode,
.build() buildContext = BuildContext.root(null),
callback = callback,
)
assertThat(result).isInstanceOf(BugReportFlowNode::class.java) assertThat(result).isInstanceOf(BugReportFlowNode::class.java)
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)
} }

View File

@@ -16,13 +16,7 @@ import io.element.android.libraries.matrix.api.core.RoomAlias
import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias
interface RoomAliasResolverEntryPoint : FeatureEntryPoint { interface RoomAliasResolverEntryPoint : FeatureEntryPoint {
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, params: Params, callback: Callback): Node
interface NodeBuilder {
fun callback(callback: Callback): NodeBuilder
fun params(params: Params): NodeBuilder
fun build(): Node
}
interface Callback : Plugin { interface Callback : Plugin {
fun onAliasResolved(data: ResolvedRoomAlias) fun onAliasResolved(data: ResolvedRoomAlias)

View File

@@ -9,7 +9,6 @@ package io.element.android.features.roomaliasresolver.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.roomaliasesolver.api.RoomAliasResolverEntryPoint import io.element.android.features.roomaliasesolver.api.RoomAliasResolverEntryPoint
@@ -17,23 +16,15 @@ import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultRoomAliasResolverEntryPoint : RoomAliasResolverEntryPoint { class DefaultRoomAliasResolverEntryPoint : RoomAliasResolverEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): RoomAliasResolverEntryPoint.NodeBuilder { override fun createNode(
val plugins = ArrayList<Plugin>() parentNode: Node,
buildContext: BuildContext,
return object : RoomAliasResolverEntryPoint.NodeBuilder { params: RoomAliasResolverEntryPoint.Params,
override fun callback(callback: RoomAliasResolverEntryPoint.Callback): RoomAliasResolverEntryPoint.NodeBuilder { callback: RoomAliasResolverEntryPoint.Callback,
plugins += callback ): Node {
return this return parentNode.createNode<RoomAliasResolverNode>(
} buildContext = buildContext,
plugins = listOf(params, callback),
override fun params(params: RoomAliasResolverEntryPoint.Params): RoomAliasResolverEntryPoint.NodeBuilder { )
plugins += params
return this
}
override fun build(): Node {
return parentNode.createNode<RoomAliasResolverNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -43,10 +43,12 @@ class DefaultRoomAliasResolverEntryPointTest {
val params = RoomAliasResolverEntryPoint.Params( val params = RoomAliasResolverEntryPoint.Params(
roomAlias = A_ROOM_ALIAS roomAlias = A_ROOM_ALIAS
) )
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.params(params) parentNode = parentNode,
.callback(callback) buildContext = BuildContext.root(null),
.build() params = params,
callback = callback,
)
assertThat(result).isInstanceOf(RoomAliasResolverNode::class.java) assertThat(result).isInstanceOf(RoomAliasResolverNode::class.java)
assertThat(result.plugins).contains(params) assertThat(result.plugins).contains(params)
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)

View File

@@ -43,11 +43,5 @@ interface RoomDetailsEntryPoint : FeatureEntryPoint {
fun startForwardEventFlow(eventId: EventId) fun startForwardEventFlow(eventId: EventId)
} }
interface NodeBuilder { fun createNode(parentNode: Node, buildContext: BuildContext, params: Params, callback: Callback): Node
fun params(params: Params): NodeBuilder
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder
} }

View File

@@ -9,7 +9,6 @@ package io.element.android.features.roomdetails.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.roomdetails.api.RoomDetailsEntryPoint import io.element.android.features.roomdetails.api.RoomDetailsEntryPoint
@@ -19,24 +18,16 @@ import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultRoomDetailsEntryPoint : RoomDetailsEntryPoint { class DefaultRoomDetailsEntryPoint : RoomDetailsEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): RoomDetailsEntryPoint.NodeBuilder { override fun createNode(
return object : RoomDetailsEntryPoint.NodeBuilder { parentNode: Node,
val plugins = ArrayList<Plugin>() buildContext: BuildContext,
params: RoomDetailsEntryPoint.Params,
override fun params(params: RoomDetailsEntryPoint.Params): RoomDetailsEntryPoint.NodeBuilder { callback: RoomDetailsEntryPoint.Callback,
plugins += params ): Node {
return this return parentNode.createNode<RoomDetailsFlowNode>(
} buildContext = buildContext,
plugins = listOf(params, callback)
override fun callback(callback: RoomDetailsEntryPoint.Callback): RoomDetailsEntryPoint.NodeBuilder { )
plugins += callback
return this
}
override fun build(): Node {
return parentNode.createNode<RoomDetailsFlowNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -303,13 +303,16 @@ class RoomDetailsFlowNode(
// Cannot happen // Cannot happen
} }
} }
mediaViewerEntryPoint.nodeBuilder(this, buildContext) val params = mediaViewerEntryPoint.createParamsForAvatar(
.avatar( filename = navTarget.name,
navTarget.name, avatarUrl = navTarget.avatarUrl,
navTarget.avatarUrl, )
) mediaViewerEntryPoint.createNode(
.callback(callback) parentNode = this,
.build() buildContext = buildContext,
params = params,
callback = callback,
)
} }
is NavTarget.PollHistory -> { is NavTarget.PollHistory -> {
pollHistoryEntryPoint.createNode(this, buildContext) pollHistoryEntryPoint.createNode(this, buildContext)
@@ -332,9 +335,11 @@ class RoomDetailsFlowNode(
callback.startForwardEventFlow(eventId) callback.startForwardEventFlow(eventId)
} }
} }
mediaGalleryEntryPoint.nodeBuilder(this, buildContext) mediaGalleryEntryPoint.createNode(
.callback(callback) parentNode = this,
.build() buildContext = buildContext,
callback = callback,
)
} }
is NavTarget.AdminSettings -> { is NavTarget.AdminSettings -> {
@@ -361,10 +366,12 @@ class RoomDetailsFlowNode(
callback.navigateToRoom(roomId, emptyList()) callback.navigateToRoom(roomId, emptyList())
} }
} }
return messagesEntryPoint.nodeBuilder(this, buildContext) return messagesEntryPoint.createNode(
.params(params) parentNode = this,
.callback(callback) buildContext = buildContext,
.build() params = params,
callback = callback,
)
} }
NavTarget.KnockRequestsList -> { NavTarget.KnockRequestsList -> {
knockRequestsListEntryPoint.createNode(this, buildContext) knockRequestsListEntryPoint.createNode(this, buildContext)
@@ -377,9 +384,11 @@ class RoomDetailsFlowNode(
showDeviceVerifiedScreen = true, showDeviceVerifiedScreen = true,
verificationRequest = VerificationRequest.Outgoing.User(userId = navTarget.userId) verificationRequest = VerificationRequest.Outgoing.User(userId = navTarget.userId)
) )
outgoingVerificationEntryPoint.nodeBuilder(this, buildContext) outgoingVerificationEntryPoint.createNode(
.params(params) parentNode = this,
.callback(object : OutgoingVerificationEntryPoint.Callback { buildContext = buildContext,
params = params,
callback = object : OutgoingVerificationEntryPoint.Callback {
override fun onDone() { override fun onDone() {
backstack.pop() backstack.pop()
} }
@@ -391,18 +400,20 @@ class RoomDetailsFlowNode(
override fun navigateToLearnMoreAboutEncryption() { override fun navigateToLearnMoreAboutEncryption() {
learnMoreUrl.value = LearnMoreConfig.ENCRYPTION_URL learnMoreUrl.value = LearnMoreConfig.ENCRYPTION_URL
} }
}) },
.build() )
} }
is NavTarget.ReportRoom -> { is NavTarget.ReportRoom -> {
reportRoomEntryPoint.createNode(this, buildContext, room.roomId) reportRoomEntryPoint.createNode(this, buildContext, room.roomId)
} }
is NavTarget.SelectNewOwnersWhenLeaving -> { is NavTarget.SelectNewOwnersWhenLeaving -> {
changeRoomMemberRolesEntryPoint.builder(this, buildContext) changeRoomMemberRolesEntryPoint.createNode(
.room(room) parentNode = this,
.listType(ChangeRoomMemberRolesListType.SelectNewOwnersWhenLeaving) buildContext = buildContext,
.build() room = room,
listType = ChangeRoomMemberRolesListType.SelectNewOwnersWhenLeaving,
)
} }
} }
} }

View File

@@ -101,16 +101,20 @@ class RolesAndPermissionsFlowNode(
) )
} }
is NavTarget.AdminList -> { is NavTarget.AdminList -> {
changeRoomMemberRolesEntryPoint.builder(this, buildContext) changeRoomMemberRolesEntryPoint.createNode(
.room(joinedRoom) parentNode = this,
.listType(ChangeRoomMemberRolesListType.Admins) buildContext = buildContext,
.build() room = joinedRoom,
listType = ChangeRoomMemberRolesListType.Admins,
)
} }
is NavTarget.ModeratorList -> { is NavTarget.ModeratorList -> {
changeRoomMemberRolesEntryPoint.builder(this, buildContext) changeRoomMemberRolesEntryPoint.createNode(
.room(joinedRoom) parentNode = this,
.listType(ChangeRoomMemberRolesListType.Moderators) buildContext = buildContext,
.build() room = joinedRoom,
listType = ChangeRoomMemberRolesListType.Moderators,
)
} }
is NavTarget.ChangeRoomPermissions -> { is NavTarget.ChangeRoomPermissions -> {
val inputs = ChangeRoomPermissionsNode.Inputs(navTarget.section) val inputs = ChangeRoomPermissionsNode.Inputs(navTarget.section)

View File

@@ -15,6 +15,7 @@ import com.google.common.truth.Truth.assertThat
import io.element.android.features.call.api.CallType import io.element.android.features.call.api.CallType
import io.element.android.features.call.api.ElementCallEntryPoint import io.element.android.features.call.api.ElementCallEntryPoint
import io.element.android.features.changeroommemberroes.api.ChangeRoomMemberRolesEntryPoint import io.element.android.features.changeroommemberroes.api.ChangeRoomMemberRolesEntryPoint
import io.element.android.features.changeroommemberroes.api.ChangeRoomMemberRolesListType
import io.element.android.features.knockrequests.api.list.KnockRequestsListEntryPoint import io.element.android.features.knockrequests.api.list.KnockRequestsListEntryPoint
import io.element.android.features.messages.api.MessagesEntryPoint import io.element.android.features.messages.api.MessagesEntryPoint
import io.element.android.features.poll.api.history.PollHistoryEntryPoint import io.element.android.features.poll.api.history.PollHistoryEntryPoint
@@ -25,6 +26,7 @@ import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.permalink.PermalinkData import io.element.android.libraries.matrix.api.permalink.PermalinkData
import io.element.android.libraries.matrix.api.room.JoinedRoom
import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.A_USER_ID
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
import io.element.android.libraries.mediaviewer.api.MediaGalleryEntryPoint import io.element.android.libraries.mediaviewer.api.MediaGalleryEntryPoint
@@ -71,25 +73,50 @@ class DefaultRoomDetailsEntryPointTest {
room = FakeJoinedRoom(), room = FakeJoinedRoom(),
analyticsService = FakeAnalyticsService(), analyticsService = FakeAnalyticsService(),
messagesEntryPoint = object : MessagesEntryPoint { messagesEntryPoint = object : MessagesEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError() override fun createNode(
parentNode: Node,
buildContext: BuildContext,
params: MessagesEntryPoint.Params,
callback: MessagesEntryPoint.Callback,
) = lambdaError()
}, },
knockRequestsListEntryPoint = object : KnockRequestsListEntryPoint { knockRequestsListEntryPoint = object : KnockRequestsListEntryPoint {
override fun createNode(parentNode: Node, buildContext: BuildContext) = lambdaError() override fun createNode(parentNode: Node, buildContext: BuildContext) = lambdaError()
}, },
mediaViewerEntryPoint = object : MediaViewerEntryPoint { mediaViewerEntryPoint = object : MediaViewerEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError() override fun createParamsForAvatar(filename: String, avatarUrl: String) = lambdaError()
override fun createNode(
parentNode: Node,
buildContext: BuildContext,
params: MediaViewerEntryPoint.Params,
callback: MediaViewerEntryPoint.Callback,
) = lambdaError()
}, },
mediaGalleryEntryPoint = object : MediaGalleryEntryPoint { mediaGalleryEntryPoint = object : MediaGalleryEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError() override fun createNode(
parentNode: Node,
buildContext: BuildContext,
callback: MediaGalleryEntryPoint.Callback,
) = lambdaError()
}, },
outgoingVerificationEntryPoint = object : OutgoingVerificationEntryPoint { outgoingVerificationEntryPoint = object : OutgoingVerificationEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError() override fun createNode(
parentNode: Node,
buildContext: BuildContext,
params: OutgoingVerificationEntryPoint.Params,
callback: OutgoingVerificationEntryPoint.Callback,
) = lambdaError()
}, },
reportRoomEntryPoint = object : ReportRoomEntryPoint { reportRoomEntryPoint = object : ReportRoomEntryPoint {
override fun createNode(parentNode: Node, buildContext: BuildContext, roomId: RoomId) = lambdaError() override fun createNode(parentNode: Node, buildContext: BuildContext, roomId: RoomId) = lambdaError()
}, },
changeRoomMemberRolesEntryPoint = object : ChangeRoomMemberRolesEntryPoint { changeRoomMemberRolesEntryPoint = object : ChangeRoomMemberRolesEntryPoint {
override fun builder(parentNode: Node, buildContext: BuildContext) = lambdaError() override fun createNode(
parentNode: Node,
buildContext: BuildContext,
room: JoinedRoom,
listType: ChangeRoomMemberRolesListType,
) = lambdaError()
}, },
) )
} }
@@ -102,10 +129,12 @@ class DefaultRoomDetailsEntryPointTest {
val params = RoomDetailsEntryPoint.Params( val params = RoomDetailsEntryPoint.Params(
initialElement = RoomDetailsEntryPoint.InitialTarget.RoomDetails, initialElement = RoomDetailsEntryPoint.InitialTarget.RoomDetails,
) )
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.params(params) parentNode = parentNode,
.callback(callback) buildContext = BuildContext.root(null),
.build() params = params,
callback = callback,
)
assertThat(result).isInstanceOf(RoomDetailsFlowNode::class.java) assertThat(result).isInstanceOf(RoomDetailsFlowNode::class.java)
assertThat(result.plugins).contains(params) assertThat(result.plugins).contains(params)
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)

View File

@@ -13,12 +13,7 @@ import com.bumble.appyx.core.plugin.Plugin
import io.element.android.libraries.architecture.FeatureEntryPoint import io.element.android.libraries.architecture.FeatureEntryPoint
interface RoomDirectoryEntryPoint : FeatureEntryPoint { interface RoomDirectoryEntryPoint : FeatureEntryPoint {
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, callback: Callback): Node
interface NodeBuilder {
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
interface Callback : Plugin { interface Callback : Plugin {
fun navigateToRoom(roomDescription: RoomDescription) fun navigateToRoom(roomDescription: RoomDescription)

View File

@@ -9,7 +9,6 @@ package io.element.android.features.roomdirectory.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.roomdirectory.api.RoomDirectoryEntryPoint import io.element.android.features.roomdirectory.api.RoomDirectoryEntryPoint
@@ -18,18 +17,7 @@ import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultRoomDirectoryEntryPoint : RoomDirectoryEntryPoint { class DefaultRoomDirectoryEntryPoint : RoomDirectoryEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): RoomDirectoryEntryPoint.NodeBuilder { override fun createNode(parentNode: Node, buildContext: BuildContext, callback: RoomDirectoryEntryPoint.Callback): Node {
val plugins = ArrayList<Plugin>() return parentNode.createNode<RoomDirectoryNode>(buildContext, listOf(callback))
return object : RoomDirectoryEntryPoint.NodeBuilder {
override fun callback(callback: RoomDirectoryEntryPoint.Callback): RoomDirectoryEntryPoint.NodeBuilder {
plugins += callback
return this
}
override fun build(): Node {
return parentNode.createNode<RoomDirectoryNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -37,9 +37,11 @@ class DefaultRoomDirectoryEntryPointTest {
val callback = object : RoomDirectoryEntryPoint.Callback { val callback = object : RoomDirectoryEntryPoint.Callback {
override fun navigateToRoom(roomDescription: RoomDescription) = lambdaError() override fun navigateToRoom(roomDescription: RoomDescription) = lambdaError()
} }
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.callback(callback) parentNode = parentNode,
.build() buildContext = BuildContext.root(null),
callback = callback,
)
assertThat(result).isInstanceOf(RoomDirectoryNode::class.java) assertThat(result).isInstanceOf(RoomDirectoryNode::class.java)
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)
} }

View File

@@ -32,15 +32,9 @@ interface SecureBackupEntryPoint : FeatureEntryPoint {
data class Params(val initialElement: InitialTarget) : NodeInputs data class Params(val initialElement: InitialTarget) : NodeInputs
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, params: Params, callback: Callback): Node
interface Callback : Plugin { interface Callback : Plugin {
fun onDone() fun onDone()
} }
interface NodeBuilder {
fun params(params: Params): NodeBuilder
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
} }

View File

@@ -9,7 +9,6 @@ package io.element.android.features.securebackup.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.securebackup.api.SecureBackupEntryPoint import io.element.android.features.securebackup.api.SecureBackupEntryPoint
@@ -17,23 +16,15 @@ import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultSecureBackupEntryPoint : SecureBackupEntryPoint { class DefaultSecureBackupEntryPoint : SecureBackupEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): SecureBackupEntryPoint.NodeBuilder { override fun createNode(
val plugins = ArrayList<Plugin>() parentNode: Node,
buildContext: BuildContext,
return object : SecureBackupEntryPoint.NodeBuilder { params: SecureBackupEntryPoint.Params,
override fun params(params: SecureBackupEntryPoint.Params): SecureBackupEntryPoint.NodeBuilder { callback: SecureBackupEntryPoint.Callback,
plugins += params ): Node {
return this return parentNode.createNode<SecureBackupFlowNode>(
} buildContext = buildContext,
plugins = listOf(params, callback)
override fun callback(callback: SecureBackupEntryPoint.Callback): SecureBackupEntryPoint.NodeBuilder { )
plugins += callback
return this
}
override fun build(): Node {
return parentNode.createNode<SecureBackupFlowNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -37,10 +37,12 @@ class DefaultSecureBackupEntryPointTest {
override fun onDone() = lambdaError() override fun onDone() = lambdaError()
} }
val params = SecureBackupEntryPoint.Params(SecureBackupEntryPoint.InitialTarget.ResetIdentity) val params = SecureBackupEntryPoint.Params(SecureBackupEntryPoint.InitialTarget.ResetIdentity)
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.params(params) parentNode = parentNode,
.callback(callback) buildContext = BuildContext.root(null),
.build() params = params,
callback = callback,
)
assertThat(result).isInstanceOf(SecureBackupFlowNode::class.java) assertThat(result).isInstanceOf(SecureBackupFlowNode::class.java)
assertThat(result.plugins).contains(params) assertThat(result.plugins).contains(params)
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)

View File

@@ -12,21 +12,14 @@ import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.Plugin
import io.element.android.libraries.architecture.FeatureEntryPoint import io.element.android.libraries.architecture.FeatureEntryPoint
import io.element.android.libraries.architecture.NodeInputs
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
interface ShareEntryPoint : FeatureEntryPoint { interface ShareEntryPoint : FeatureEntryPoint {
data class Params(val intent: Intent) : NodeInputs data class Params(val intent: Intent)
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, params: Params, callback: Callback): Node
interface Callback : Plugin { interface Callback : Plugin {
fun onDone(roomIds: List<RoomId>) fun onDone(roomIds: List<RoomId>)
} }
interface NodeBuilder {
fun params(params: Params): NodeBuilder
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
} }

View File

@@ -9,7 +9,6 @@ package io.element.android.features.share.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.share.api.ShareEntryPoint import io.element.android.features.share.api.ShareEntryPoint
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
@@ -17,23 +16,13 @@ import io.element.android.libraries.di.SessionScope
@ContributesBinding(SessionScope::class) @ContributesBinding(SessionScope::class)
class DefaultShareEntryPoint : ShareEntryPoint { class DefaultShareEntryPoint : ShareEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): ShareEntryPoint.NodeBuilder { override fun createNode(parentNode: Node, buildContext: BuildContext, params: ShareEntryPoint.Params, callback: ShareEntryPoint.Callback): Node {
val plugins = ArrayList<Plugin>() return parentNode.createNode<ShareNode>(
buildContext = buildContext,
return object : ShareEntryPoint.NodeBuilder { plugins = listOf(
override fun params(params: ShareEntryPoint.Params): ShareEntryPoint.NodeBuilder { ShareNode.Inputs(intent = params.intent),
plugins += ShareNode.Inputs(intent = params.intent) callback,
return this )
} )
override fun callback(callback: ShareEntryPoint.Callback): ShareEntryPoint.NodeBuilder {
plugins += callback
return this
}
override fun build(): Node {
return parentNode.createNode<ShareNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -66,10 +66,12 @@ class ShareNode(
} }
} }
return roomSelectEntryPoint.nodeBuilder(this, buildContext) return roomSelectEntryPoint.createNode(
.callback(callback) parentNode = this,
.params(RoomSelectEntryPoint.Params(mode = RoomSelectMode.Share)) buildContext = buildContext,
.build() params = RoomSelectEntryPoint.Params(mode = RoomSelectMode.Share),
callback = callback,
)
} }
@Composable @Composable

View File

@@ -38,9 +38,12 @@ class DefaultShareEntryPointTest {
plugins = plugins, plugins = plugins,
presenterFactory = { createSharePresenter() }, presenterFactory = { createSharePresenter() },
roomSelectEntryPoint = object : RoomSelectEntryPoint { roomSelectEntryPoint = object : RoomSelectEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): RoomSelectEntryPoint.NodeBuilder { override fun createNode(
lambdaError() parentNode: Node,
} buildContext: BuildContext,
params: RoomSelectEntryPoint.Params,
callback: RoomSelectEntryPoint.Callback,
) = lambdaError()
}, },
) )
} }
@@ -50,10 +53,12 @@ class DefaultShareEntryPointTest {
val params = ShareEntryPoint.Params( val params = ShareEntryPoint.Params(
intent = Intent(), intent = Intent(),
) )
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.params(params) parentNode = parentNode,
.callback(callback) buildContext = BuildContext.root(null),
.build() params = params,
callback = callback,
)
assertThat(result).isInstanceOf(ShareNode::class.java) assertThat(result).isInstanceOf(ShareNode::class.java)
assertThat(result.plugins).contains(ShareNode.Inputs(params.intent)) assertThat(result.plugins).contains(ShareNode.Inputs(params.intent))
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)

View File

@@ -17,10 +17,5 @@ interface SignedOutEntryPoint : FeatureEntryPoint {
val sessionId: SessionId, val sessionId: SessionId,
) )
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, params: Params): Node
interface NodeBuilder {
fun params(params: Params): NodeBuilder
fun build(): Node
}
} }

View File

@@ -9,7 +9,6 @@ package io.element.android.features.signedout.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.signedout.api.SignedOutEntryPoint import io.element.android.features.signedout.api.SignedOutEntryPoint
@@ -17,18 +16,10 @@ import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultSignedOutEntryPoint : SignedOutEntryPoint { class DefaultSignedOutEntryPoint : SignedOutEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): SignedOutEntryPoint.NodeBuilder { override fun createNode(parentNode: Node, buildContext: BuildContext, params: SignedOutEntryPoint.Params): Node {
val plugins = ArrayList<Plugin>() return parentNode.createNode<SignedOutNode>(
buildContext = buildContext,
return object : SignedOutEntryPoint.NodeBuilder { plugins = listOf(SignedOutNode.Inputs(params.sessionId))
override fun params(params: SignedOutEntryPoint.Params): SignedOutEntryPoint.NodeBuilder { )
plugins += SignedOutNode.Inputs(params.sessionId)
return this
}
override fun build(): Node {
return parentNode.createNode<SignedOutNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -34,9 +34,11 @@ class DefaultSignedOutEntryPointTest {
) )
} }
val params = SignedOutEntryPoint.Params(A_SESSION_ID) val params = SignedOutEntryPoint.Params(A_SESSION_ID)
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.params(params) parentNode = parentNode,
.build() buildContext = BuildContext.root(null),
params = params,
)
assertThat(result).isInstanceOf(SignedOutNode::class.java) assertThat(result).isInstanceOf(SignedOutNode::class.java)
assertThat(result.plugins).contains(SignedOutNode.Inputs(params.sessionId)) assertThat(result.plugins).contains(SignedOutNode.Inputs(params.sessionId))
} }

View File

@@ -15,16 +15,12 @@ import io.element.android.libraries.architecture.NodeInputs
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
interface SpaceEntryPoint : FeatureEntryPoint { interface SpaceEntryPoint : FeatureEntryPoint {
fun nodeBuilder( fun createNode(
parentNode: Node, parentNode: Node,
buildContext: BuildContext, buildContext: BuildContext,
): NodeBuilder inputs: Inputs,
callback: Callback
interface NodeBuilder { ): Node
fun inputs(inputs: Inputs): NodeBuilder
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
data class Inputs( data class Inputs(
val roomId: RoomId val roomId: RoomId

View File

@@ -9,7 +9,6 @@ package io.element.android.features.space.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.space.api.SpaceEntryPoint import io.element.android.features.space.api.SpaceEntryPoint
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
@@ -17,22 +16,10 @@ import io.element.android.libraries.di.SessionScope
@ContributesBinding(SessionScope::class) @ContributesBinding(SessionScope::class)
class DefaultSpaceEntryPoint : SpaceEntryPoint { class DefaultSpaceEntryPoint : SpaceEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): SpaceEntryPoint.NodeBuilder { override fun createNode(parentNode: Node, buildContext: BuildContext, inputs: SpaceEntryPoint.Inputs, callback: SpaceEntryPoint.Callback): Node {
val plugins = mutableSetOf<Plugin>() return parentNode.createNode<SpaceFlowNode>(
return object : SpaceEntryPoint.NodeBuilder { buildContext = buildContext,
override fun inputs(inputs: SpaceEntryPoint.Inputs): SpaceEntryPoint.NodeBuilder { plugins = listOf(inputs, callback),
plugins.add(inputs) )
return this
}
override fun callback(callback: SpaceEntryPoint.Callback): SpaceEntryPoint.NodeBuilder {
plugins.add(callback)
return this
}
override fun build(): Node {
return parentNode.createNode<SpaceFlowNode>(buildContext, plugins = plugins.toList())
}
}
} }
} }

View File

@@ -48,10 +48,12 @@ class DefaultSpaceEntryPointTest {
override fun navigateToRoomDetails() = lambdaError() override fun navigateToRoomDetails() = lambdaError()
override fun navigateToRoomMemberList() = lambdaError() override fun navigateToRoomMemberList() = lambdaError()
} }
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.inputs(nodeInputs) parentNode = parentNode,
.callback(callback) buildContext = BuildContext.root(null),
.build() inputs = nodeInputs,
callback = callback,
)
assertThat(result).isInstanceOf(SpaceFlowNode::class.java) assertThat(result).isInstanceOf(SpaceFlowNode::class.java)
assertThat(result.plugins).contains(nodeInputs) assertThat(result.plugins).contains(nodeInputs)
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)

View File

@@ -14,11 +14,7 @@ import io.element.android.libraries.architecture.FeatureEntryPoint
import io.element.android.libraries.matrix.api.core.RoomIdOrAlias import io.element.android.libraries.matrix.api.core.RoomIdOrAlias
interface StartChatEntryPoint : FeatureEntryPoint { interface StartChatEntryPoint : FeatureEntryPoint {
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, callback: Callback): Node
interface NodeBuilder {
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
interface Callback : Plugin { interface Callback : Plugin {
fun onRoomCreated(roomIdOrAlias: RoomIdOrAlias, serverNames: List<String>) fun onRoomCreated(roomIdOrAlias: RoomIdOrAlias, serverNames: List<String>)

View File

@@ -9,7 +9,6 @@ package io.element.android.features.startchat.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.startchat.api.StartChatEntryPoint import io.element.android.features.startchat.api.StartChatEntryPoint
@@ -17,18 +16,7 @@ import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultStartChatEntryPoint : StartChatEntryPoint { class DefaultStartChatEntryPoint : StartChatEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): StartChatEntryPoint.NodeBuilder { override fun createNode(parentNode: Node, buildContext: BuildContext, callback: StartChatEntryPoint.Callback): Node {
val plugins = ArrayList<Plugin>() return parentNode.createNode<StartChatFlowNode>(buildContext, listOf(callback))
return object : StartChatEntryPoint.NodeBuilder {
override fun callback(callback: StartChatEntryPoint.Callback): StartChatEntryPoint.NodeBuilder {
plugins += callback
return this
}
override fun build(): Node {
return parentNode.createNode<StartChatFlowNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -79,9 +79,11 @@ class StartChatFlowNode(
navigator.onRoomCreated(roomId.toRoomIdOrAlias(), emptyList()) navigator.onRoomCreated(roomId.toRoomIdOrAlias(), emptyList())
} }
} }
createRoomEntryPoint.nodeBuilder(parentNode = this, buildContext = buildContext) createRoomEntryPoint.createNode(
.callback(callback) parentNode = this,
.build() buildContext = buildContext,
callback = callback,
)
} }
NavTarget.JoinByAddress -> { NavTarget.JoinByAddress -> {
createNode<JoinRoomByAddressNode>(buildContext = buildContext, plugins = listOf(navigator)) createNode<JoinRoomByAddressNode>(buildContext = buildContext, plugins = listOf(navigator))

View File

@@ -35,7 +35,11 @@ class DefaultStartChatEntryPointTest {
buildContext = buildContext, buildContext = buildContext,
plugins = plugins, plugins = plugins,
createRoomEntryPoint = object : CreateRoomEntryPoint { createRoomEntryPoint = object : CreateRoomEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError() override fun createNode(
parentNode: Node,
buildContext: BuildContext,
callback: CreateRoomEntryPoint.Callback,
) = lambdaError()
}, },
) )
} }
@@ -43,9 +47,11 @@ class DefaultStartChatEntryPointTest {
override fun onRoomCreated(roomIdOrAlias: RoomIdOrAlias, serverNames: List<String>) = lambdaError() override fun onRoomCreated(roomIdOrAlias: RoomIdOrAlias, serverNames: List<String>) = lambdaError()
override fun navigateToRoomDirectory() = lambdaError() override fun navigateToRoomDirectory() = lambdaError()
} }
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.callback(callback) parentNode = parentNode,
.build() buildContext = BuildContext.root(null),
callback = callback,
)
assertThat(result).isInstanceOf(StartChatFlowNode::class.java) assertThat(result).isInstanceOf(StartChatFlowNode::class.java)
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)
} }

View File

@@ -22,11 +22,5 @@ interface UserProfileEntryPoint : FeatureEntryPoint {
fun navigateToRoom(roomId: RoomId) fun navigateToRoom(roomId: RoomId)
} }
interface NodeBuilder { fun createNode(parentNode: Node, buildContext: BuildContext, params: Params, callback: Callback): Node
fun params(params: Params): NodeBuilder
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder
} }

View File

@@ -9,7 +9,6 @@ package io.element.android.features.userprofile.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.userprofile.api.UserProfileEntryPoint import io.element.android.features.userprofile.api.UserProfileEntryPoint
@@ -17,23 +16,15 @@ import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultUserProfileEntryPoint : UserProfileEntryPoint { class DefaultUserProfileEntryPoint : UserProfileEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): UserProfileEntryPoint.NodeBuilder { override fun createNode(
return object : UserProfileEntryPoint.NodeBuilder { parentNode: Node,
val plugins = ArrayList<Plugin>() buildContext: BuildContext,
params: UserProfileEntryPoint.Params,
override fun params(params: UserProfileEntryPoint.Params): UserProfileEntryPoint.NodeBuilder { callback: UserProfileEntryPoint.Callback,
plugins += params ): Node {
return this return parentNode.createNode<UserProfileFlowNode>(
} buildContext = buildContext,
plugins = listOf(params, callback),
override fun callback(callback: UserProfileEntryPoint.Callback): UserProfileEntryPoint.NodeBuilder { )
plugins += callback
return this
}
override fun build(): Node {
return parentNode.createNode<UserProfileFlowNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -107,22 +107,40 @@ class UserProfileFlowNode(
// Cannot happen // Cannot happen
} }
} }
mediaViewerEntryPoint.nodeBuilder(this, buildContext) val params = mediaViewerEntryPoint.createParamsForAvatar(
.avatar( filename = navTarget.name,
filename = navTarget.name, avatarUrl = navTarget.avatarUrl,
avatarUrl = navTarget.avatarUrl )
) mediaViewerEntryPoint.createNode(
.callback(callback) parentNode = this,
.build() buildContext = buildContext,
params = params,
callback = callback,
)
} }
is NavTarget.VerifyUser -> { is NavTarget.VerifyUser -> {
val params = OutgoingVerificationEntryPoint.Params( val params = OutgoingVerificationEntryPoint.Params(
showDeviceVerifiedScreen = false, showDeviceVerifiedScreen = false,
verificationRequest = VerificationRequest.Outgoing.User(userId = navTarget.userId) verificationRequest = VerificationRequest.Outgoing.User(userId = navTarget.userId)
) )
outgoingVerificationEntryPoint.nodeBuilder(this, buildContext) outgoingVerificationEntryPoint.createNode(
.params(params) parentNode = this,
.build() buildContext = buildContext,
params = params,
callback = object : OutgoingVerificationEntryPoint.Callback {
override fun navigateToLearnMoreAboutEncryption() {
// No op
}
override fun onBack() {
// No op
}
override fun onDone() {
// No op
}
}
)
} }
} }
} }

View File

@@ -59,10 +59,21 @@ class DefaultUserProfileEntryPointTest {
) = lambdaError() ) = lambdaError()
}, },
mediaViewerEntryPoint = object : MediaViewerEntryPoint { mediaViewerEntryPoint = object : MediaViewerEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError() override fun createParamsForAvatar(filename: String, avatarUrl: String) = lambdaError()
override fun createNode(
parentNode: Node,
buildContext: BuildContext,
params: MediaViewerEntryPoint.Params,
callback: MediaViewerEntryPoint.Callback
) = lambdaError()
}, },
outgoingVerificationEntryPoint = object : OutgoingVerificationEntryPoint { outgoingVerificationEntryPoint = object : OutgoingVerificationEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError() override fun createNode(
parentNode: Node,
buildContext: BuildContext,
params: OutgoingVerificationEntryPoint.Params,
callback: OutgoingVerificationEntryPoint.Callback,
) = lambdaError()
}, },
) )
} }
@@ -74,10 +85,12 @@ class DefaultUserProfileEntryPointTest {
val params = UserProfileEntryPoint.Params( val params = UserProfileEntryPoint.Params(
userId = A_USER_ID, userId = A_USER_ID,
) )
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.params(params) parentNode = parentNode,
.callback(callback) buildContext = BuildContext.root(null),
.build() params = params,
callback = callback,
)
assertThat(result).isInstanceOf(UserProfileFlowNode::class.java) assertThat(result).isInstanceOf(UserProfileFlowNode::class.java)
assertThat(result.plugins).contains(params) assertThat(result.plugins).contains(params)
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)

View File

@@ -19,13 +19,7 @@ interface IncomingVerificationEntryPoint : FeatureEntryPoint {
val verificationRequest: VerificationRequest.Incoming, val verificationRequest: VerificationRequest.Incoming,
) : NodeInputs ) : NodeInputs
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, params: Params, callback: Callback): Node
interface NodeBuilder {
fun callback(callback: Callback): NodeBuilder
fun params(params: Params): NodeBuilder
fun build(): Node
}
interface Callback : Plugin { interface Callback : Plugin {
fun onDone() fun onDone()

View File

@@ -20,13 +20,7 @@ interface OutgoingVerificationEntryPoint : FeatureEntryPoint {
val verificationRequest: VerificationRequest.Outgoing, val verificationRequest: VerificationRequest.Outgoing,
) : NodeInputs ) : NodeInputs
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, params: Params, callback: Callback): Node
interface NodeBuilder {
fun callback(callback: Callback): NodeBuilder
fun params(params: Params): NodeBuilder
fun build(): Node
}
interface Callback : Plugin { interface Callback : Plugin {
fun navigateToLearnMoreAboutEncryption() fun navigateToLearnMoreAboutEncryption()

View File

@@ -9,7 +9,6 @@ package io.element.android.features.verifysession.impl.incoming
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.verifysession.api.IncomingVerificationEntryPoint import io.element.android.features.verifysession.api.IncomingVerificationEntryPoint
@@ -17,23 +16,12 @@ import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultIncomingVerificationEntryPoint : IncomingVerificationEntryPoint { class DefaultIncomingVerificationEntryPoint : IncomingVerificationEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): IncomingVerificationEntryPoint.NodeBuilder { override fun createNode(
val plugins = ArrayList<Plugin>() parentNode: Node,
buildContext: BuildContext,
return object : IncomingVerificationEntryPoint.NodeBuilder { params: IncomingVerificationEntryPoint.Params,
override fun callback(callback: IncomingVerificationEntryPoint.Callback): IncomingVerificationEntryPoint.NodeBuilder { callback: IncomingVerificationEntryPoint.Callback,
plugins += callback ): Node {
return this return parentNode.createNode<IncomingVerificationNode>(buildContext, listOf(params, callback))
}
override fun params(params: IncomingVerificationEntryPoint.Params): IncomingVerificationEntryPoint.NodeBuilder {
plugins += params
return this
}
override fun build(): Node {
return parentNode.createNode<IncomingVerificationNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -9,7 +9,6 @@ package io.element.android.features.verifysession.impl.outgoing
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.verifysession.api.OutgoingVerificationEntryPoint import io.element.android.features.verifysession.api.OutgoingVerificationEntryPoint
@@ -17,23 +16,12 @@ import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultOutgoingVerificationEntryPoint : OutgoingVerificationEntryPoint { class DefaultOutgoingVerificationEntryPoint : OutgoingVerificationEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): OutgoingVerificationEntryPoint.NodeBuilder { override fun createNode(
val plugins = ArrayList<Plugin>() parentNode: Node,
buildContext: BuildContext,
return object : OutgoingVerificationEntryPoint.NodeBuilder { params: OutgoingVerificationEntryPoint.Params,
override fun callback(callback: OutgoingVerificationEntryPoint.Callback): OutgoingVerificationEntryPoint.NodeBuilder { callback: OutgoingVerificationEntryPoint.Callback,
plugins += callback ): Node {
return this return parentNode.createNode<OutgoingVerificationNode>(buildContext, listOf(params, callback))
}
override fun params(params: OutgoingVerificationEntryPoint.Params): OutgoingVerificationEntryPoint.NodeBuilder {
plugins += params
return this
}
override fun build(): Node {
return parentNode.createNode<OutgoingVerificationNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -37,10 +37,12 @@ class DefaultIncomingVerificationEntryPointTest {
val params = IncomingVerificationEntryPoint.Params( val params = IncomingVerificationEntryPoint.Params(
verificationRequest = anIncomingSessionVerificationRequest() verificationRequest = anIncomingSessionVerificationRequest()
) )
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.params(params) parentNode = parentNode,
.callback(callback) buildContext = BuildContext.root(null),
.build() params = params,
callback = callback,
)
assertThat(result).isInstanceOf(IncomingVerificationNode::class.java) assertThat(result).isInstanceOf(IncomingVerificationNode::class.java)
assertThat(result.plugins).contains(params) assertThat(result.plugins).contains(params)
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)

View File

@@ -42,10 +42,12 @@ class DefaultOutgoingVerificationEntryPointTest {
showDeviceVerifiedScreen = true, showDeviceVerifiedScreen = true,
verificationRequest = anOutgoingSessionVerificationRequest(), verificationRequest = anOutgoingSessionVerificationRequest(),
) )
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.params(params) parentNode = parentNode,
.callback(callback) buildContext = BuildContext.root(null),
.build() params = params,
callback = callback,
)
assertThat(result).isInstanceOf(OutgoingVerificationNode::class.java) assertThat(result).isInstanceOf(OutgoingVerificationNode::class.java)
assertThat(result.plugins).contains(params) assertThat(result.plugins).contains(params)
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)

View File

@@ -17,13 +17,7 @@ interface ViewFolderEntryPoint : FeatureEntryPoint {
val rootPath: String, val rootPath: String,
) )
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, params: Params, callback: Callback): Node
interface NodeBuilder {
fun params(params: Params): NodeBuilder
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
interface Callback : Plugin { interface Callback : Plugin {
fun onDone() fun onDone()

View File

@@ -9,7 +9,6 @@ package io.element.android.features.viewfolder.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.viewfolder.api.ViewFolderEntryPoint import io.element.android.features.viewfolder.api.ViewFolderEntryPoint
@@ -18,23 +17,13 @@ import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultViewFolderEntryPoint : ViewFolderEntryPoint { class DefaultViewFolderEntryPoint : ViewFolderEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): ViewFolderEntryPoint.NodeBuilder { override fun createNode(parentNode: Node, buildContext: BuildContext, params: ViewFolderEntryPoint.Params, callback: ViewFolderEntryPoint.Callback): Node {
val plugins = ArrayList<Plugin>() return parentNode.createNode<ViewFolderFlowNode>(
buildContext = buildContext,
return object : ViewFolderEntryPoint.NodeBuilder { plugins = listOf(
override fun params(params: ViewFolderEntryPoint.Params): ViewFolderEntryPoint.NodeBuilder { ViewFolderFlowNode.Inputs(params.rootPath),
plugins += ViewFolderFlowNode.Inputs(params.rootPath) callback,
return this ),
} )
override fun callback(callback: ViewFolderEntryPoint.Callback): ViewFolderEntryPoint.NodeBuilder {
plugins += callback
return this
}
override fun build(): Node {
return parentNode.createNode<ViewFolderFlowNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -40,10 +40,12 @@ class DefaultViewFolderEntryPointTest {
val params = ViewFolderEntryPoint.Params( val params = ViewFolderEntryPoint.Params(
rootPath = "path", rootPath = "path",
) )
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.params(params) parentNode = parentNode,
.callback(callback) buildContext = BuildContext.root(null),
.build() params = params,
callback = callback,
)
assertThat(result).isInstanceOf(ViewFolderFlowNode::class.java) assertThat(result).isInstanceOf(ViewFolderFlowNode::class.java)
assertThat(result.plugins).contains(ViewFolderFlowNode.Inputs(params.rootPath)) assertThat(result.plugins).contains(ViewFolderFlowNode.Inputs(params.rootPath))
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)

View File

@@ -14,12 +14,7 @@ import io.element.android.libraries.architecture.FeatureEntryPoint
import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.SessionId
interface AccountSelectEntryPoint : FeatureEntryPoint { interface AccountSelectEntryPoint : FeatureEntryPoint {
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, callback: Callback): Node
interface NodeBuilder {
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
interface Callback : Plugin { interface Callback : Plugin {
fun onAccountSelected(sessionId: SessionId) fun onAccountSelected(sessionId: SessionId)

View File

@@ -9,7 +9,6 @@ package io.element.android.libraries.accountselect.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.accountselect.api.AccountSelectEntryPoint import io.element.android.libraries.accountselect.api.AccountSelectEntryPoint
@@ -17,18 +16,7 @@ import io.element.android.libraries.architecture.createNode
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultAccountSelectEntryPoint : AccountSelectEntryPoint { class DefaultAccountSelectEntryPoint : AccountSelectEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): AccountSelectEntryPoint.NodeBuilder { override fun createNode(parentNode: Node, buildContext: BuildContext, callback: AccountSelectEntryPoint.Callback): Node {
val plugins = ArrayList<Plugin>() return parentNode.createNode<AccountSelectNode>(buildContext, listOf(callback))
return object : AccountSelectEntryPoint.NodeBuilder {
override fun callback(callback: AccountSelectEntryPoint.Callback): AccountSelectEntryPoint.NodeBuilder {
plugins += callback
return this
}
override fun build(): Node {
return parentNode.createNode<AccountSelectNode>(buildContext, plugins)
}
}
} }
} }

View File

@@ -35,9 +35,11 @@ class DefaultAccountSelectEntryPointTest {
override fun onAccountSelected(sessionId: SessionId) = lambdaError() override fun onAccountSelected(sessionId: SessionId) = lambdaError()
override fun onCancel() = lambdaError() override fun onCancel() = lambdaError()
} }
val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) val result = entryPoint.createNode(
.callback(callback) parentNode = parentNode,
.build() buildContext = BuildContext.root(null),
callback = callback,
)
assertThat(result).isInstanceOf(AccountSelectNode::class.java) assertThat(result).isInstanceOf(AccountSelectNode::class.java)
assertThat(result.plugins).contains(callback) assertThat(result.plugins).contains(callback)
} }

View File

@@ -14,12 +14,7 @@ import io.element.android.libraries.architecture.FeatureEntryPoint
import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.EventId
interface MediaGalleryEntryPoint : FeatureEntryPoint { interface MediaGalleryEntryPoint : FeatureEntryPoint {
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, callback: Callback): Node
interface NodeBuilder {
fun callback(callback: Callback): NodeBuilder
fun build(): Node
}
interface Callback : Plugin { interface Callback : Plugin {
fun onBackClick() fun onBackClick()

View File

@@ -19,14 +19,9 @@ import io.element.android.libraries.matrix.api.timeline.Timeline
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
interface MediaViewerEntryPoint : FeatureEntryPoint { interface MediaViewerEntryPoint : FeatureEntryPoint {
fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder fun createNode(parentNode: Node, buildContext: BuildContext, params: Params, callback: Callback): Node
interface NodeBuilder { fun createParamsForAvatar(filename: String, avatarUrl: String): Params
fun callback(callback: Callback): NodeBuilder
fun params(params: Params): NodeBuilder
fun avatar(filename: String, avatarUrl: String): NodeBuilder
fun build(): Node
}
interface Callback : Plugin { interface Callback : Plugin {
fun onDone() fun onDone()

View File

@@ -9,7 +9,6 @@ package io.element.android.libraries.mediaviewer.impl
import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.architecture.createNode import io.element.android.libraries.architecture.createNode
@@ -18,18 +17,10 @@ import io.element.android.libraries.mediaviewer.impl.gallery.root.MediaGalleryFl
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultMediaGalleryEntryPoint : MediaGalleryEntryPoint { class DefaultMediaGalleryEntryPoint : MediaGalleryEntryPoint {
override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): MediaGalleryEntryPoint.NodeBuilder { override fun createNode(parentNode: Node, buildContext: BuildContext, callback: MediaGalleryEntryPoint.Callback): Node {
val plugins = ArrayList<Plugin>() return parentNode.createNode<MediaGalleryFlowNode>(
buildContext = buildContext,
return object : MediaGalleryEntryPoint.NodeBuilder { plugins = listOf(callback),
override fun callback(callback: MediaGalleryEntryPoint.Callback): MediaGalleryEntryPoint.NodeBuilder { )
plugins += callback
return this
}
override fun build(): Node {
return parentNode.createNode<MediaGalleryFlowNode>(buildContext, plugins)
}
}
} }
} }

Some files were not shown because too many files have changed in this diff Show More