Ensure a Callback and only one is provided in the Plugin. Also reduce boilerplate code in Nodes.

This commit is contained in:
Benoit Marty 2025-10-30 09:14:41 +01:00 committed by Benoit Marty
parent 596b7f00fc
commit 5197154f54
76 changed files with 374 additions and 741 deletions

View file

@ -16,7 +16,6 @@ import androidx.lifecycle.coroutineScope
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins
import com.bumble.appyx.navmodel.backstack.BackStack
import com.bumble.appyx.navmodel.backstack.operation.pop
import com.bumble.appyx.navmodel.backstack.operation.push
@ -45,6 +44,7 @@ import io.element.android.features.userprofile.shared.UserProfileNodeHelper
import io.element.android.features.verifysession.api.OutgoingVerificationEntryPoint
import io.element.android.libraries.architecture.BackstackWithOverlayBox
import io.element.android.libraries.architecture.BaseFlowNode
import io.element.android.libraries.architecture.callback
import io.element.android.libraries.architecture.createNode
import io.element.android.libraries.architecture.overlay.operation.hide
import io.element.android.libraries.architecture.overlay.operation.show
@ -146,6 +146,8 @@ class RoomDetailsFlowNode(
data object SelectNewOwnersWhenLeaving : NavTarget
}
private val callback: RoomDetailsEntryPoint.Callback = callback()
override fun onBuilt() {
super.onBuilt()
whenChildrenAttached {
@ -260,7 +262,7 @@ class RoomDetailsFlowNode(
val input = RoomNotificationSettingsNode.RoomNotificationSettingInput(navTarget.showUserDefinedSettingStyle)
val callback = object : RoomNotificationSettingsNode.Callback {
override fun navigateToGlobalNotificationSettings() {
plugins<RoomDetailsEntryPoint.Callback>().forEach { it.navigateToGlobalNotificationSettings() }
callback.navigateToGlobalNotificationSettings()
}
}
createNode<RoomNotificationSettingsNode>(buildContext, listOf(input, callback))
@ -273,7 +275,7 @@ class RoomDetailsFlowNode(
}
override fun navigateToRoom(roomId: RoomId) {
plugins<RoomDetailsEntryPoint.Callback>().forEach { it.navigateToRoom(roomId, emptyList()) }
callback.navigateToRoom(roomId, emptyList())
}
override fun startCall(dmRoomId: RoomId) {
@ -323,13 +325,11 @@ class RoomDetailsFlowNode(
roomIdOrAlias = room.roomId.toRoomIdOrAlias(),
eventId = eventId,
)
plugins<RoomDetailsEntryPoint.Callback>().forEach {
it.handlePermalinkClick(permalinkData, pushToBackstack = false)
}
callback.handlePermalinkClick(permalinkData, pushToBackstack = false)
}
override fun forward(eventId: EventId) {
plugins<RoomDetailsEntryPoint.Callback>().forEach { it.startForwardEventFlow(eventId) }
callback.startForwardEventFlow(eventId)
}
}
mediaGalleryEntryPoint.nodeBuilder(this, buildContext)
@ -350,15 +350,15 @@ class RoomDetailsFlowNode(
override fun navigateToRoomMemberDetails(userId: UserId) = Unit
override fun handlePermalinkClick(data: PermalinkData, pushToBackstack: Boolean) {
plugins<RoomDetailsEntryPoint.Callback>().forEach { it.handlePermalinkClick(data, pushToBackstack) }
callback.handlePermalinkClick(data, pushToBackstack)
}
override fun forwardEvent(eventId: EventId) {
plugins<RoomDetailsEntryPoint.Callback>().forEach { it.startForwardEventFlow(eventId) }
callback.startForwardEventFlow(eventId)
}
override fun navigateToRoom(roomId: RoomId) {
plugins<RoomDetailsEntryPoint.Callback>().forEach { it.navigateToRoom(roomId, emptyList()) }
callback.navigateToRoom(roomId, emptyList())
}
}
return messagesEntryPoint.nodeBuilder(this, buildContext)

View file

@ -18,7 +18,6 @@ import com.bumble.appyx.core.lifecycle.subscribe
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.AssistedInject
import im.vector.app.features.analytics.plan.MobileScreen
@ -26,6 +25,7 @@ import io.element.android.annotations.ContributesNode
import io.element.android.features.leaveroom.api.LeaveRoomRenderer
import io.element.android.libraries.androidutils.system.startSharePlainTextIntent
import io.element.android.libraries.architecture.appyx.launchMolecule
import io.element.android.libraries.architecture.callback
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.libraries.matrix.api.room.BaseRoom
@ -63,7 +63,7 @@ class RoomDetailsNode(
fun navigateToSelectNewOwnersWhenLeaving()
}
private val callback = plugins<Callback>().single()
private val callback: Callback = callback()
init {
lifecycle.subscribe(

View file

@ -13,7 +13,6 @@ import com.bumble.appyx.core.lifecycle.subscribe
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.AssistedInject
import im.vector.app.features.analytics.plan.MobileScreen
@ -21,6 +20,7 @@ import io.element.android.annotations.ContributesNode
import io.element.android.features.roommembermoderation.api.ModerationAction
import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvents
import io.element.android.features.roommembermoderation.api.RoomMemberModerationRenderer
import io.element.android.libraries.architecture.callback
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.matrix.api.core.UserId
import io.element.android.services.analytics.api.AnalyticsService
@ -39,7 +39,7 @@ class RoomMemberListNode(
fun navigateToInviteMembers()
}
private val callbacks = plugins<Callback>()
private val callback: Callback = callback()
init {
lifecycle.subscribe(
@ -50,15 +50,11 @@ class RoomMemberListNode(
}
override fun openRoomMemberDetails(roomMemberId: UserId) {
callbacks.forEach {
it.navigateToRoomMemberDetails(roomMemberId)
}
callback.navigateToRoomMemberDetails(roomMemberId)
}
override fun openInviteMembers() {
callbacks.forEach {
it.navigateToInviteMembers()
}
callback.navigateToInviteMembers()
}
override fun exitRoomMemberList() {

View file

@ -13,12 +13,12 @@ import com.bumble.appyx.core.lifecycle.subscribe
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.AssistedInject
import im.vector.app.features.analytics.plan.MobileScreen
import io.element.android.annotations.ContributesNode
import io.element.android.libraries.architecture.NodeInputs
import io.element.android.libraries.architecture.callback
import io.element.android.libraries.architecture.inputs
import io.element.android.libraries.di.RoomScope
import io.element.android.services.analytics.api.AnalyticsService
@ -34,17 +34,16 @@ class RoomNotificationSettingsNode(
data class RoomNotificationSettingInput(
val showUserDefinedSettingStyle: Boolean
) : NodeInputs
interface Callback : Plugin {
fun navigateToGlobalNotificationSettings()
}
private val inputs = inputs<RoomNotificationSettingInput>()
private val callbacks = plugins<Callback>()
private fun navigateToGlobalNotificationSettings() {
callbacks.forEach { it.navigateToGlobalNotificationSettings() }
}
private val callback: Callback = callback()
private val inputs = inputs<RoomNotificationSettingInput>()
private val presenter = presenterFactory.create(inputs.showUserDefinedSettingStyle)
init {
lifecycle.subscribe(
onResume = {
@ -59,8 +58,8 @@ class RoomNotificationSettingsNode(
RoomNotificationSettingsView(
state = state,
modifier = modifier,
onShowGlobalNotifications = this::navigateToGlobalNotificationSettings,
onBackClick = this::navigateUp,
onShowGlobalNotifications = callback::navigateToGlobalNotificationSettings,
onBackClick = ::navigateUp,
)
}
}

View file

@ -14,10 +14,10 @@ import androidx.lifecycle.lifecycleScope
import com.bumble.appyx.core.modality.BuildContext
import com.bumble.appyx.core.node.Node
import com.bumble.appyx.core.plugin.Plugin
import com.bumble.appyx.core.plugin.plugins
import dev.zacsweers.metro.Assisted
import dev.zacsweers.metro.AssistedInject
import io.element.android.annotations.ContributesNode
import io.element.android.libraries.architecture.callback
import io.element.android.libraries.di.RoomScope
import io.element.android.libraries.matrix.api.room.BaseRoom
import io.element.android.libraries.matrix.api.room.RoomMember
@ -45,7 +45,7 @@ class RolesAndPermissionsNode(
override fun onBackClick() {}
}
private val callback = plugins<Callback>().first()
private val callback: Callback = callback()
@Stable
private val navigator = object : RolesAndPermissionsNavigator by callback {