[Message Actions] Retry sending failed messages (#596)

* Add `RetrySendMessageMenu` to retry sending failed messages or removing its local echo.

* Fix initial event being retrieved, not the updated one

---------

Co-authored-by: ElementBot <benoitm+elementbot@element.io>
This commit is contained in:
Jorge Martin Espinosa 2023-06-15 11:27:37 +02:00 committed by GitHub
parent 9f2d6bde0e
commit 7ddf93ed09
41 changed files with 641 additions and 37 deletions

View file

@ -83,6 +83,10 @@ interface MatrixRoom : Closeable {
suspend fun sendReaction(emoji: String, eventId: EventId): Result<Unit>
suspend fun retrySendMessage(transactionId: String): Result<Unit>
suspend fun cancelSend(transactionId: String): Result<Unit>
suspend fun leave(): Result<Unit>
suspend fun acceptInvitation(): Result<Unit>

View file

@ -24,6 +24,7 @@ sealed interface MatrixTimelineItem {
data class Event(val event: EventTimelineItem) : MatrixTimelineItem {
val uniqueId: String = event.uniqueIdentifier
val eventId: EventId? = event.eventId
val transactionId: String? = event.transactionId
}
data class Virtual(val virtual: VirtualTimelineItem) : MatrixTimelineItem

View file

@ -23,6 +23,7 @@ import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugIn
data class EventTimelineItem(
val uniqueIdentifier: String,
val eventId: EventId?,
val transactionId: String?,
val isEditable: Boolean,
val isLocal: Boolean,
val isOwn: Boolean,

View file

@ -34,6 +34,7 @@ import io.element.android.libraries.matrix.impl.media.map
import io.element.android.libraries.matrix.impl.timeline.RustMatrixTimeline
import io.element.android.services.toolbox.api.systemclock.SystemClock
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
@ -264,6 +265,20 @@ class RustMatrixRoom(
}
}
override suspend fun retrySendMessage(transactionId: String): Result<Unit> =
withContext(coroutineDispatchers.io) {
runCatching {
innerRoom.retrySend(transactionId)
}
}
override suspend fun cancelSend(transactionId: String): Result<Unit> =
withContext(coroutineDispatchers.io) {
runCatching {
innerRoom.cancelSend(transactionId)
}
}
@OptIn(ExperimentalUnsignedTypes::class)
override suspend fun updateAvatar(mimeType: String, data: ByteArray): Result<Unit> =
withContext(coroutineDispatchers.io) {

View file

@ -35,6 +35,7 @@ class EventTimelineItemMapper(private val contentMapper: TimelineEventContentMap
EventTimelineItem(
uniqueIdentifier = it.uniqueIdentifier(),
eventId = it.eventId()?.let(::EventId),
transactionId = it.transactionId(),
isEditable = it.isEditable(),
isLocal = it.isLocal(),
isOwn = it.isOwn(),

View file

@ -37,6 +37,7 @@ val A_ROOM_ID_2 = RoomId("!aRoomId2:domain")
val A_THREAD_ID = ThreadId("\$aThreadId")
val AN_EVENT_ID = EventId("\$anEventId")
val AN_EVENT_ID_2 = EventId("\$anEventId2")
const val A_TRANSACTION_ID = "aTransactionId"
const val A_UNIQUE_ID = "aUniqueId"
const val A_ROOM_NAME = "A room name"

View file

@ -71,6 +71,8 @@ class FakeMatrixRoom(
private var updateAvatarResult = Result.success(Unit)
private var removeAvatarResult = Result.success(Unit)
private var sendReactionResult = Result.success(Unit)
private var retrySendMessageResult = Result.success(Unit)
private var cancelSendResult = Result.success(Unit)
var sendMediaCount = 0
private set
@ -78,6 +80,12 @@ class FakeMatrixRoom(
var sendReactionCount = 0
private set
var retrySendMessageCount: Int = 0
private set
var cancelSendCount: Int = 0
private set
var isInviteAccepted: Boolean = false
private set
@ -133,6 +141,16 @@ class FakeMatrixRoom(
return sendReactionResult
}
override suspend fun retrySendMessage(transactionId: String): Result<Unit> {
retrySendMessageCount++
return retrySendMessageResult
}
override suspend fun cancelSend(transactionId: String): Result<Unit> {
cancelSendCount++
return cancelSendResult
}
var editMessageParameter: String? = null
private set
@ -292,4 +310,12 @@ class FakeMatrixRoom(
fun givenSendReactionResult(result: Result<Unit>) {
sendReactionResult = result
}
fun givenRetrySendMessageResult(result: Result<Unit>) {
retrySendMessageResult = result
}
fun givenCancelSendResult(result: Result<Unit>) {
cancelSendResult = result
}
}

View file

@ -89,6 +89,7 @@ fun aRoomMessage(
fun anEventTimelineItem(
uniqueIdentifier: String = A_UNIQUE_ID,
eventId: EventId = AN_EVENT_ID,
transactionId: String? = null,
isEditable: Boolean = false,
isLocal: Boolean = false,
isOwn: Boolean = false,
@ -103,6 +104,7 @@ fun anEventTimelineItem(
) = EventTimelineItem(
uniqueIdentifier = uniqueIdentifier,
eventId = eventId,
transactionId = transactionId,
isEditable = isEditable,
isLocal = isLocal,
isOwn = isOwn,