Forward several events at once

This commit is contained in:
ganfra
2026-09-25 18:47:17 +02:00
parent 51c06b4bec
commit 93831ffcbc
11 changed files with 50 additions and 62 deletions
@@ -23,7 +23,7 @@ interface ForwardEntryPoint : FeatureEntryPoint {
}
data class Params(
val eventId: EventId,
val eventIds: List<EventId>,
val timelineProvider: TimelineProvider,
) : NodeInputs
@@ -27,7 +27,7 @@ class DefaultForwardEntryPoint : ForwardEntryPoint {
buildContext = buildContext,
plugins = listOf(
ForwardMessagesNode.Inputs(
eventId = params.eventId,
eventIds = params.eventIds,
timelineProvider = params.timelineProvider,
),
callback,
@@ -52,13 +52,13 @@ class ForwardMessagesNode(
object NavTarget : Parcelable
data class Inputs(
val eventId: EventId,
val eventIds: List<EventId>,
val timelineProvider: TimelineProvider,
) : NodeInputs
private val inputs = inputs<Inputs>()
private val callback: ForwardEntryPoint.Callback = callback()
private val presenter = presenterFactory.create(inputs.eventId.value, inputs.timelineProvider)
private val presenter = presenterFactory.create(inputs.eventIds, inputs.timelineProvider)
override fun resolve(navTarget: NavTarget, buildContext: BuildContext): Node {
val callback = object : RoomSelectEntryPoint.Callback {
@@ -28,22 +28,20 @@ import timber.log.Timber
@AssistedInject
class ForwardMessagesPresenter(
@Assisted eventId: String,
@Assisted private val eventIds: List<EventId>,
@Assisted private val timelineProvider: TimelineProvider,
@SessionCoroutineScope
private val sessionCoroutineScope: CoroutineScope,
) : Presenter<ForwardMessagesState> {
private val eventId: EventId = EventId(eventId)
@AssistedFactory
fun interface Factory {
fun create(eventId: String, timelineProvider: TimelineProvider): ForwardMessagesPresenter
fun create(eventIds: List<EventId>, timelineProvider: TimelineProvider): ForwardMessagesPresenter
}
private val forwardingActionState: MutableState<AsyncAction<List<RoomId>>> = mutableStateOf(AsyncAction.Uninitialized)
fun onRoomSelected(roomIds: List<RoomId>) {
sessionCoroutineScope.forwardEvent(eventId, roomIds)
sessionCoroutineScope.forwardEvents(eventIds, roomIds)
}
@Composable
@@ -60,14 +58,14 @@ class ForwardMessagesPresenter(
)
}
private fun CoroutineScope.forwardEvent(
eventId: EventId,
private fun CoroutineScope.forwardEvents(
eventIds: List<EventId>,
roomIds: List<RoomId>,
) = launch {
suspend {
timelineProvider.getActiveTimeline().forwardEvent(eventId, roomIds)
timelineProvider.getActiveTimeline().forwardEvents(eventIds, roomIds)
.onFailure {
Timber.e(it, "Error while forwarding event")
Timber.e(it, "Error while forwarding events")
}
.getOrThrow()
roomIds
@@ -45,7 +45,7 @@ class DefaultForwardEntryPointTest {
override fun onDone(roomIds: List<RoomId>) = lambdaError()
}
val params = ForwardEntryPoint.Params(
eventId = AN_EVENT_ID,
eventIds = listOf(AN_EVENT_ID),
timelineProvider = FakeTimelineProvider(),
)
val result = entryPoint.createNode(
@@ -57,7 +57,7 @@ class DefaultForwardEntryPointTest {
assertThat(result).isInstanceOf(ForwardMessagesNode::class.java)
assertThat(result.plugins).contains(
ForwardMessagesNode.Inputs(
eventId = params.eventId,
eventIds = params.eventIds,
timelineProvider = params.timelineProvider,
)
)
@@ -44,11 +44,11 @@ class ForwardMessagesPresenterTest {
@Test
fun `present - forward successful`() = runTest {
val forwardEventLambda = lambdaRecorder { _: EventId, _: List<RoomId> ->
val forwardEventsLambda = lambdaRecorder { _: List<EventId>, _: List<RoomId> ->
Result.success(Unit)
}
val timeline = FakeTimeline().apply {
this.forwardEventLambda = forwardEventLambda
this.forwardEventsLambda = forwardEventsLambda
}
val room = FakeJoinedRoom(liveTimeline = timeline)
val presenter = createForwardMessagesPresenter(fakeRoom = room)
@@ -62,17 +62,17 @@ class ForwardMessagesPresenterTest {
assertThat(forwardingState.forwardAction.isLoading()).isTrue()
val successfulForwardState = awaitItem()
assertThat(successfulForwardState.forwardAction).isEqualTo(AsyncAction.Success(listOf(summary.roomId)))
forwardEventLambda.assertions().isCalledOnce()
forwardEventsLambda.assertions().isCalledOnce()
}
}
@Test
fun `present - select a room and forward failed, then clear`() = runTest {
val forwardEventLambda = lambdaRecorder { _: EventId, _: List<RoomId> ->
val forwardEventsLambda = lambdaRecorder { _: List<EventId>, _: List<RoomId> ->
Result.failure<Unit>(IllegalStateException("error"))
}
val timeline = FakeTimeline().apply {
this.forwardEventLambda = forwardEventLambda
this.forwardEventsLambda = forwardEventsLambda
}
val room = FakeJoinedRoom(liveTimeline = timeline)
val presenter = createForwardMessagesPresenter(fakeRoom = room)
@@ -88,16 +88,16 @@ class ForwardMessagesPresenterTest {
// Then clear error
failedForwardState.eventSink(ForwardMessagesEvent.ClearError)
assertThat(awaitItem().forwardAction.isUninitialized()).isTrue()
forwardEventLambda.assertions().isCalledOnce()
forwardEventsLambda.assertions().isCalledOnce()
}
}
}
fun TestScope.createForwardMessagesPresenter(
eventId: EventId = AN_EVENT_ID,
eventIds: List<EventId> = listOf(AN_EVENT_ID),
fakeRoom: FakeJoinedRoom = FakeJoinedRoom(),
) = ForwardMessagesPresenter(
eventId = eventId.value,
eventIds = eventIds,
timelineProvider = LiveTimelineProvider(fakeRoom),
sessionCoroutineScope = this,
)