mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 20:38:40 +00:00
Forward several events at once
This commit is contained in:
+19
-17
@@ -14,7 +14,6 @@ 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.room.ForwardEventException
|
||||
import io.element.android.libraries.matrix.impl.roomlist.roomOrNull
|
||||
import io.element.android.libraries.matrix.impl.timeline.runWithTimelineListenerRegistered
|
||||
import kotlinx.coroutines.withTimeout
|
||||
import org.matrix.rustcomponents.sdk.MsgLikeKind
|
||||
import org.matrix.rustcomponents.sdk.RoomListService
|
||||
@@ -31,33 +30,36 @@ class RoomContentForwarder(
|
||||
private val roomListService: RoomListService,
|
||||
) {
|
||||
/**
|
||||
* Forwards the event with the given [eventId] from the [fromTimeline] to the given [toRoomIds].
|
||||
* @param fromTimeline the room to forward the event from
|
||||
* @param eventId the id of the event to forward
|
||||
* @param toRoomIds the ids of the rooms to forward the event to
|
||||
* @param timeoutMs the maximum time in milliseconds to wait for the event to be sent to a room
|
||||
* Forwards the events with the given [eventIds] from the [fromTimeline] to the given [toRoomIds].
|
||||
* The events are sent to each room in the order they are provided in [eventIds], it is up to the caller to sort them.
|
||||
* @param fromTimeline the room to forward the events from
|
||||
* @param eventIds the ids of the events to forward, in the order they must be sent
|
||||
* @param toRoomIds the ids of the rooms to forward the events to
|
||||
* @param timeoutMs the maximum time in milliseconds to wait for an event to be sent to a room
|
||||
*/
|
||||
suspend fun forward(
|
||||
fromTimeline: Timeline,
|
||||
eventId: EventId,
|
||||
eventIds: List<EventId>,
|
||||
toRoomIds: List<RoomId>,
|
||||
timeoutMs: Long = 5000L
|
||||
) {
|
||||
val messageLikeContent = (fromTimeline.getEventTimelineItemByEventId(eventId.value).content as? TimelineItemContent.MsgLike)?.content
|
||||
?: throw ForwardEventException(toRoomIds)
|
||||
|
||||
val content = (messageLikeContent.kind as? MsgLikeKind.Message)?.content
|
||||
?: throw ForwardEventException(toRoomIds)
|
||||
|
||||
val contents = eventIds.map { eventId ->
|
||||
val timelineEvent = fromTimeline.getEventTimelineItemByEventId(eventId.value)
|
||||
val content = timelineEvent.content as? TimelineItemContent.MsgLike ?: throw ForwardEventException(toRoomIds)
|
||||
val message = content.content.kind as? MsgLikeKind.Message ?: throw ForwardEventException(toRoomIds)
|
||||
contentWithoutRelationFromMessage(message.content)
|
||||
}
|
||||
val targetRooms = toRoomIds.toSet().mapNotNull { roomId -> roomListService.roomOrNull(roomId.value) }
|
||||
val failedForwardingTo = mutableSetOf<RoomId>()
|
||||
targetRooms.parallelMap { room ->
|
||||
room.use { targetRoom ->
|
||||
runCatchingExceptions {
|
||||
// Sending a message requires a registered timeline listener
|
||||
targetRoom.timeline().runWithTimelineListenerRegistered {
|
||||
withTimeout(timeoutMs.milliseconds) {
|
||||
targetRoom.timeline().send(contentWithoutRelationFromMessage(content))
|
||||
targetRoom.timeline().use { timeline ->
|
||||
// Send the contents sequentially, so that they are received in the same order
|
||||
contents.forEach { content ->
|
||||
withTimeout(timeoutMs.milliseconds) {
|
||||
timeline.send(content)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-13
@@ -53,16 +53,3 @@ internal fun TimelineInterface.timelineDiffFlow(): Flow<List<TimelineDiff>> =
|
||||
}.catch {
|
||||
Timber.d(it, "timelineDiffFlow() failed")
|
||||
}.buffer(Channel.UNLIMITED)
|
||||
|
||||
internal suspend fun TimelineInterface.runWithTimelineListenerRegistered(action: suspend () -> Unit) {
|
||||
val result = addListener(NoOpTimelineListener)
|
||||
try {
|
||||
action()
|
||||
} finally {
|
||||
result.cancelAndDestroy()
|
||||
}
|
||||
}
|
||||
|
||||
private object NoOpTimelineListener : TimelineListener {
|
||||
override fun onUpdate(diff: List<TimelineDiff>) = Unit
|
||||
}
|
||||
|
||||
+2
-2
@@ -489,9 +489,9 @@ class RustTimeline(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit> = withContext(dispatcher) {
|
||||
override suspend fun forwardEvents(eventIds: List<EventId>, roomIds: List<RoomId>): Result<Unit> = withContext(dispatcher) {
|
||||
runCatchingExceptions {
|
||||
roomContentForwarder.forward(fromTimeline = inner, eventId = eventId, toRoomIds = roomIds)
|
||||
roomContentForwarder.forward(fromTimeline = inner, eventIds = eventIds, toRoomIds = roomIds)
|
||||
}.onFailure {
|
||||
Timber.tag(loggerTag).e(it)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user