[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:
parent
9f2d6bde0e
commit
7ddf93ed09
41 changed files with 641 additions and 37 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue