From e9cfce915ad9e9b9d9cf0c2228f5fbd62fb25d40 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 28 Oct 2025 13:28:39 +0100 Subject: [PATCH] Extract code for forwarding Event to its own modules. --- features/forward/api/build.gradle.kts | 19 ++++++ .../features/forward/api/ForwardEntryPoint.kt | 36 ++++++++++ features/forward/impl/build.gradle.kts | 38 +++++++++++ .../forward/impl/DefaultForwardEntryPoint.kt | 42 ++++++++++++ .../forward/impl}/ForwardMessagesEvents.kt | 2 +- .../forward/impl}/ForwardMessagesNode.kt | 9 +-- .../forward/impl}/ForwardMessagesPresenter.kt | 4 +- .../forward/impl}/ForwardMessagesState.kt | 2 +- .../impl}/ForwardMessagesStateProvider.kt | 2 +- .../forward/impl}/ForwardMessagesView.kt | 2 +- .../impl/DefaultForwardEntryPointTest.kt | 68 +++++++++++++++++++ .../impl}/ForwardMessagesPresenterTest.kt | 26 +++---- .../forward/impl}/ForwardMessagesViewTest.kt | 2 +- features/messages/impl/build.gradle.kts | 1 + .../messages/impl/MessagesFlowNode.kt | 12 ++-- .../impl/DefaultMessagesEntryPointTest.kt | 4 ++ .../test/timeline/FakeTimelineProvider.kt | 24 +++++++ 17 files changed, 263 insertions(+), 30 deletions(-) create mode 100644 features/forward/api/build.gradle.kts create mode 100644 features/forward/api/src/main/kotlin/io/element/android/features/forward/api/ForwardEntryPoint.kt create mode 100644 features/forward/impl/build.gradle.kts create mode 100644 features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/DefaultForwardEntryPoint.kt rename features/{messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward => forward/impl/src/main/kotlin/io/element/android/features/forward/impl}/ForwardMessagesEvents.kt (83%) rename features/{messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward => forward/impl/src/main/kotlin/io/element/android/features/forward/impl}/ForwardMessagesNode.kt (94%) rename features/{messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward => forward/impl/src/main/kotlin/io/element/android/features/forward/impl}/ForwardMessagesPresenter.kt (97%) rename features/{messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward => forward/impl/src/main/kotlin/io/element/android/features/forward/impl}/ForwardMessagesState.kt (88%) rename features/{messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward => forward/impl/src/main/kotlin/io/element/android/features/forward/impl}/ForwardMessagesStateProvider.kt (95%) rename features/{messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward => forward/impl/src/main/kotlin/io/element/android/features/forward/impl}/ForwardMessagesView.kt (95%) create mode 100644 features/forward/impl/src/test/kotlin/io/element/android/features/forward/impl/DefaultForwardEntryPointTest.kt rename features/{messages/impl/src/test/kotlin/io/element/android/features/messages/impl/forward => forward/impl/src/test/kotlin/io/element/android/features/forward/impl}/ForwardMessagesPresenterTest.kt (86%) rename features/{messages/impl/src/test/kotlin/io/element/android/features/messages/impl/forward => forward/impl/src/test/kotlin/io/element/android/features/forward/impl}/ForwardMessagesViewTest.kt (97%) create mode 100644 libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimelineProvider.kt diff --git a/features/forward/api/build.gradle.kts b/features/forward/api/build.gradle.kts new file mode 100644 index 0000000000..b5c73539d7 --- /dev/null +++ b/features/forward/api/build.gradle.kts @@ -0,0 +1,19 @@ +/* + * 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. + */ + +plugins { + id("io.element.android-library") +} + +android { + namespace = "io.element.android.features.forward.api" +} + +dependencies { + implementation(projects.libraries.architecture) + implementation(projects.libraries.matrix.api) +} diff --git a/features/forward/api/src/main/kotlin/io/element/android/features/forward/api/ForwardEntryPoint.kt b/features/forward/api/src/main/kotlin/io/element/android/features/forward/api/ForwardEntryPoint.kt new file mode 100644 index 0000000000..f0deaffa95 --- /dev/null +++ b/features/forward/api/src/main/kotlin/io/element/android/features/forward/api/ForwardEntryPoint.kt @@ -0,0 +1,36 @@ +/* + * 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.features.forward.api + +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import io.element.android.libraries.architecture.FeatureEntryPoint +import io.element.android.libraries.architecture.NodeInputs +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.timeline.TimelineProvider + +interface ForwardEntryPoint : FeatureEntryPoint { + interface NodeBuilder { + fun params(params: Params): NodeBuilder + fun callback(callback: Callback): NodeBuilder + fun build(): Node + } + + interface Callback : Plugin { + fun onForwardedToSingleRoom(roomId: RoomId) + } + + data class Params( + val eventId: EventId, + val timelineProvider: TimelineProvider, + ) : NodeInputs + + fun nodeBuilder(parentNode: Node, buildContext: BuildContext): NodeBuilder +} diff --git a/features/forward/impl/build.gradle.kts b/features/forward/impl/build.gradle.kts new file mode 100644 index 0000000000..32da0ed7a2 --- /dev/null +++ b/features/forward/impl/build.gradle.kts @@ -0,0 +1,38 @@ +import extension.setupDependencyInjection +import extension.testCommonDependencies + +/* + * 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. + */ + +plugins { + id("io.element.android-compose-library") + id("kotlin-parcelize") +} + +android { + namespace = "io.element.android.features.forward.impl" + + testOptions { + unitTests { + isIncludeAndroidResources = true + } + } +} + +setupDependencyInjection() + +dependencies { + api(projects.features.forward.api) + implementation(projects.libraries.architecture) + implementation(projects.libraries.designsystem) + implementation(projects.libraries.matrix.api) + implementation(projects.libraries.roomselect.api) + + testCommonDependencies(libs, true) + testImplementation(projects.libraries.matrix.test) + testImplementation(projects.libraries.testtags) +} diff --git a/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/DefaultForwardEntryPoint.kt b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/DefaultForwardEntryPoint.kt new file mode 100644 index 0000000000..bdb10c38a3 --- /dev/null +++ b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/DefaultForwardEntryPoint.kt @@ -0,0 +1,42 @@ +/* + * 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.features.forward.impl + +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.core.plugin.Plugin +import dev.zacsweers.metro.ContributesBinding +import io.element.android.features.forward.api.ForwardEntryPoint +import io.element.android.libraries.architecture.createNode +import io.element.android.libraries.di.RoomScope + +@ContributesBinding(RoomScope::class) +class DefaultForwardEntryPoint : ForwardEntryPoint { + override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): ForwardEntryPoint.NodeBuilder { + val plugins = ArrayList() + + return object : ForwardEntryPoint.NodeBuilder { + override fun params(params: ForwardEntryPoint.Params): ForwardEntryPoint.NodeBuilder { + plugins += ForwardMessagesNode.Inputs( + eventId = params.eventId, + timelineProvider = params.timelineProvider, + ) + return this + } + + override fun callback(callback: ForwardEntryPoint.Callback): ForwardEntryPoint.NodeBuilder { + plugins += callback + return this + } + + override fun build(): Node { + return parentNode.createNode(buildContext, plugins) + } + } + } +} diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesEvents.kt b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesEvents.kt similarity index 83% rename from features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesEvents.kt rename to features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesEvents.kt index 05a77b61a7..06495cfc24 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesEvents.kt +++ b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesEvents.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.messages.impl.forward +package io.element.android.features.forward.impl sealed interface ForwardMessagesEvents { data object ClearError : ForwardMessagesEvents diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesNode.kt b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesNode.kt similarity index 94% rename from features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesNode.kt rename to features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesNode.kt index 2cf0c6e1e7..ba4e2f2cc6 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesNode.kt +++ b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesNode.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.messages.impl.forward +package io.element.android.features.forward.impl import android.os.Parcelable import androidx.compose.foundation.layout.Box @@ -20,6 +20,7 @@ import com.bumble.appyx.core.plugin.Plugin import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode +import io.element.android.features.forward.api.ForwardEntryPoint import io.element.android.libraries.architecture.NodeInputs import io.element.android.libraries.architecture.inputs import io.element.android.libraries.di.RoomScope @@ -48,10 +49,6 @@ class ForwardMessagesNode( @Parcelize object NavTarget : Parcelable - interface Callback : Plugin { - fun onForwardedToSingleRoom(roomId: RoomId) - } - data class Inputs( val eventId: EventId, val timelineProvider: TimelineProvider, @@ -59,7 +56,7 @@ class ForwardMessagesNode( private val inputs = inputs() private val presenter = presenterFactory.create(inputs.eventId.value, inputs.timelineProvider) - private val callbacks = plugins.filterIsInstance() + private val callbacks = plugins.filterIsInstance() override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node { val callback = object : RoomSelectEntryPoint.Callback { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesPresenter.kt b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesPresenter.kt similarity index 97% rename from features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesPresenter.kt rename to features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesPresenter.kt index 3e3860db3e..d7ffd9b398 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesPresenter.kt +++ b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesPresenter.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.messages.impl.forward +package io.element.android.features.forward.impl import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState @@ -36,7 +36,7 @@ class ForwardMessagesPresenter( private val eventId: EventId = EventId(eventId) @AssistedFactory - interface Factory { + fun interface Factory { fun create(eventId: String, timelineProvider: TimelineProvider): ForwardMessagesPresenter } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesState.kt b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesState.kt similarity index 88% rename from features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesState.kt rename to features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesState.kt index a1de911c72..a6d93f39da 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesState.kt +++ b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesState.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.messages.impl.forward +package io.element.android.features.forward.impl import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.core.RoomId diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesStateProvider.kt b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesStateProvider.kt similarity index 95% rename from features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesStateProvider.kt rename to features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesStateProvider.kt index b1728f4657..f5789549c5 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesStateProvider.kt +++ b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesStateProvider.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.messages.impl.forward +package io.element.android.features.forward.impl import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.libraries.architecture.AsyncAction diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesView.kt b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesView.kt similarity index 95% rename from features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesView.kt rename to features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesView.kt index 9ea76d754f..214c795851 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesView.kt +++ b/features/forward/impl/src/main/kotlin/io/element/android/features/forward/impl/ForwardMessagesView.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.messages.impl.forward +package io.element.android.features.forward.impl import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.PreviewParameter diff --git a/features/forward/impl/src/test/kotlin/io/element/android/features/forward/impl/DefaultForwardEntryPointTest.kt b/features/forward/impl/src/test/kotlin/io/element/android/features/forward/impl/DefaultForwardEntryPointTest.kt new file mode 100644 index 0000000000..c6bc78dbe8 --- /dev/null +++ b/features/forward/impl/src/test/kotlin/io/element/android/features/forward/impl/DefaultForwardEntryPointTest.kt @@ -0,0 +1,68 @@ +/* + * 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.features.forward.impl + +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import com.bumble.appyx.testing.junit4.util.MainDispatcherRule +import com.google.common.truth.Truth.assertThat +import io.element.android.features.forward.api.ForwardEntryPoint +import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.test.AN_EVENT_ID +import io.element.android.libraries.matrix.test.timeline.FakeTimelineProvider +import io.element.android.libraries.roomselect.api.RoomSelectEntryPoint +import io.element.android.tests.testutils.lambda.lambdaError +import io.element.android.tests.testutils.node.TestParentNode +import kotlinx.coroutines.test.runTest +import org.junit.Rule +import org.junit.Test + +class DefaultForwardEntryPointTest { + @get:Rule + val instantTaskExecutorRule = InstantTaskExecutorRule() + + @get:Rule + val mainDispatcherRule = MainDispatcherRule() + + @Test + fun `test node builder`() = runTest { + val entryPoint = DefaultForwardEntryPoint() + val parentNode = TestParentNode.create { buildContext, plugins -> + ForwardMessagesNode( + buildContext = buildContext, + plugins = plugins, + presenterFactory = { _, _ -> createForwardMessagesPresenter() }, + roomSelectEntryPoint = object : RoomSelectEntryPoint { + override fun nodeBuilder(parentNode: Node, buildContext: BuildContext): RoomSelectEntryPoint.NodeBuilder { + lambdaError() + } + } + ) + } + val callback = object : ForwardEntryPoint.Callback { + override fun onForwardedToSingleRoom(roomId: RoomId) = lambdaError() + } + val params = ForwardEntryPoint.Params( + eventId = AN_EVENT_ID, + timelineProvider = FakeTimelineProvider(), + ) + val result = entryPoint.nodeBuilder(parentNode, BuildContext.root(null)) + .params(params) + .callback(callback) + .build() + assertThat(result).isInstanceOf(ForwardMessagesNode::class.java) + assertThat(result.plugins).contains( + ForwardMessagesNode.Inputs( + eventId = params.eventId, + timelineProvider = params.timelineProvider, + ) + ) + assertThat(result.plugins).contains(callback) + } +} diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesPresenterTest.kt b/features/forward/impl/src/test/kotlin/io/element/android/features/forward/impl/ForwardMessagesPresenterTest.kt similarity index 86% rename from features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesPresenterTest.kt rename to features/forward/impl/src/test/kotlin/io/element/android/features/forward/impl/ForwardMessagesPresenterTest.kt index 757e682592..6850a5ef07 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesPresenterTest.kt +++ b/features/forward/impl/src/test/kotlin/io/element/android/features/forward/impl/ForwardMessagesPresenterTest.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.messages.impl.forward +package io.element.android.features.forward.impl import app.cash.molecule.RecompositionMode import app.cash.molecule.moleculeFlow @@ -32,7 +32,7 @@ class ForwardMessagesPresenterTest { @Test fun `present - initial state`() = runTest { - val presenter = aForwardMessagesPresenter() + val presenter = createForwardMessagesPresenter() moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { @@ -50,7 +50,7 @@ class ForwardMessagesPresenterTest { this.forwardEventLambda = forwardEventLambda } val room = FakeJoinedRoom(liveTimeline = timeline) - val presenter = aForwardMessagesPresenter(fakeRoom = room) + val presenter = createForwardMessagesPresenter(fakeRoom = room) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { @@ -74,7 +74,7 @@ class ForwardMessagesPresenterTest { this.forwardEventLambda = forwardEventLambda } val room = FakeJoinedRoom(liveTimeline = timeline) - val presenter = aForwardMessagesPresenter(fakeRoom = room) + val presenter = createForwardMessagesPresenter(fakeRoom = room) moleculeFlow(RecompositionMode.Immediate) { presenter.present() }.test { @@ -90,13 +90,13 @@ class ForwardMessagesPresenterTest { forwardEventLambda.assertions().isCalledOnce() } } - - private fun TestScope.aForwardMessagesPresenter( - eventId: EventId = AN_EVENT_ID, - fakeRoom: FakeJoinedRoom = FakeJoinedRoom(), - ) = ForwardMessagesPresenter( - eventId = eventId.value, - timelineProvider = LiveTimelineProvider(fakeRoom), - sessionCoroutineScope = this, - ) } + +fun TestScope.createForwardMessagesPresenter( + eventId: EventId = AN_EVENT_ID, + fakeRoom: FakeJoinedRoom = FakeJoinedRoom(), +) = ForwardMessagesPresenter( + eventId = eventId.value, + timelineProvider = LiveTimelineProvider(fakeRoom), + sessionCoroutineScope = this, +) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesViewTest.kt b/features/forward/impl/src/test/kotlin/io/element/android/features/forward/impl/ForwardMessagesViewTest.kt similarity index 97% rename from features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesViewTest.kt rename to features/forward/impl/src/test/kotlin/io/element/android/features/forward/impl/ForwardMessagesViewTest.kt index 0912fcc75c..9cecda6973 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/forward/ForwardMessagesViewTest.kt +++ b/features/forward/impl/src/test/kotlin/io/element/android/features/forward/impl/ForwardMessagesViewTest.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.messages.impl.forward +package io.element.android.features.forward.impl import androidx.activity.ComponentActivity import androidx.compose.ui.test.junit4.AndroidComposeTestRule diff --git a/features/messages/impl/build.gradle.kts b/features/messages/impl/build.gradle.kts index 43efad9da0..ee2d7f48b0 100644 --- a/features/messages/impl/build.gradle.kts +++ b/features/messages/impl/build.gradle.kts @@ -29,6 +29,7 @@ dependencies { implementation(projects.appconfig) implementation(projects.features.call.api) implementation(projects.features.enterprise.api) + implementation(projects.features.forward.api) implementation(projects.features.location.api) implementation(projects.features.poll.api) implementation(projects.features.roomcall.api) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt index 82aafcf545..f08afd7d9d 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesFlowNode.kt @@ -25,6 +25,7 @@ import im.vector.app.features.analytics.plan.Interaction import io.element.android.annotations.ContributesNode import io.element.android.features.call.api.CallType import io.element.android.features.call.api.ElementCallEntryPoint +import io.element.android.features.forward.api.ForwardEntryPoint import io.element.android.features.knockrequests.api.list.KnockRequestsListEntryPoint import io.element.android.features.location.api.Location import io.element.android.features.location.api.LocationService @@ -33,7 +34,6 @@ import io.element.android.features.location.api.ShowLocationEntryPoint import io.element.android.features.messages.api.MessagesEntryPoint import io.element.android.features.messages.impl.attachments.Attachment import io.element.android.features.messages.impl.attachments.preview.AttachmentsPreviewNode -import io.element.android.features.messages.impl.forward.ForwardMessagesNode import io.element.android.features.messages.impl.pinned.PinnedEventsTimelineProvider import io.element.android.features.messages.impl.pinned.list.PinnedMessagesListNode import io.element.android.features.messages.impl.report.ReportMessageNode @@ -103,6 +103,7 @@ class MessagesFlowNode( private val createPollEntryPoint: CreatePollEntryPoint, private val elementCallEntryPoint: ElementCallEntryPoint, private val mediaViewerEntryPoint: MediaViewerEntryPoint, + private val forwardEntryPoint: ForwardEntryPoint, private val analyticsService: AnalyticsService, private val locationService: LocationService, private val room: BaseRoom, @@ -333,13 +334,16 @@ class MessagesFlowNode( } else { timelineController } - val inputs = ForwardMessagesNode.Inputs(navTarget.eventId, timelineProvider) - val callback = object : ForwardMessagesNode.Callback { + val params = ForwardEntryPoint.Params(navTarget.eventId, timelineProvider) + val callback = object : ForwardEntryPoint.Callback { override fun onForwardedToSingleRoom(roomId: RoomId) { callbacks.forEach { it.onForwardedToSingleRoom(roomId) } } } - createNode(buildContext, listOf(inputs, callback)) + forwardEntryPoint.nodeBuilder(this, buildContext) + .params(params) + .callback(callback) + .build() } is NavTarget.ReportMessage -> { val inputs = ReportMessageNode.Inputs(navTarget.eventId, navTarget.senderId) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/DefaultMessagesEntryPointTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/DefaultMessagesEntryPointTest.kt index 2de761ad69..fed52f7840 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/DefaultMessagesEntryPointTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/DefaultMessagesEntryPointTest.kt @@ -15,6 +15,7 @@ import com.bumble.appyx.testing.junit4.util.MainDispatcherRule import com.google.common.truth.Truth.assertThat import io.element.android.features.call.api.CallType import io.element.android.features.call.api.ElementCallEntryPoint +import io.element.android.features.forward.api.ForwardEntryPoint import io.element.android.features.knockrequests.api.list.KnockRequestsListEntryPoint import io.element.android.features.location.api.SendLocationEntryPoint import io.element.android.features.location.api.ShowLocationEntryPoint @@ -90,6 +91,9 @@ class DefaultMessagesEntryPointTest { mediaViewerEntryPoint = object : MediaViewerEntryPoint { override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError() }, + forwardEntryPoint = object : ForwardEntryPoint { + override fun nodeBuilder(parentNode: Node, buildContext: BuildContext) = lambdaError() + }, analyticsService = FakeAnalyticsService(), locationService = FakeLocationService(), room = FakeBaseRoom(), diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimelineProvider.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimelineProvider.kt new file mode 100644 index 0000000000..519789c003 --- /dev/null +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/FakeTimelineProvider.kt @@ -0,0 +1,24 @@ +/* + * 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.libraries.matrix.test.timeline + +import io.element.android.libraries.matrix.api.timeline.Timeline +import io.element.android.libraries.matrix.api.timeline.TimelineProvider +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow + +class FakeTimelineProvider( + initialTimeline: Timeline? = null, +) : TimelineProvider { + private val timelineFlow = MutableStateFlow(initialTimeline) + + override fun activeTimelineFlow(): StateFlow { + return timelineFlow.asStateFlow() + } +}