diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/send/SendState.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/send/SendState.kt index e9f22da4..aaa7020b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/send/SendState.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/room/send/SendState.kt @@ -16,6 +16,7 @@ package im.vector.matrix.android.api.session.room.send + enum class SendState { UNKNOWN, // the event has not been sent @@ -33,16 +34,19 @@ enum class SendState { // the event failed to be sent because some unknown devices have been found while encrypting it FAILED_UNKNOWN_DEVICES; - fun isSent(): Boolean { - return this == SENT || this == SYNCED + internal companion object { + val HAS_FAILED_STATES = listOf(UNDELIVERED, FAILED_UNKNOWN_DEVICES) + val IS_SENT_STATES = listOf(SENT, SYNCED) + val IS_SENDING_STATES = listOf(UNSENT, ENCRYPTING, SENDING) + val PENDING_STATES = IS_SENDING_STATES + HAS_FAILED_STATES } - fun hasFailed(): Boolean { - return this == UNDELIVERED || this == FAILED_UNKNOWN_DEVICES - } + fun isSent() = IS_SENT_STATES.contains(this) - fun isSending(): Boolean { - return this == UNSENT || this == ENCRYPTING || this == SENDING - } + fun hasFailed() = HAS_FAILED_STATES.contains(this) + + fun isSending() = IS_SENDING_STATES.contains(this) } + + diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventEntityQueries.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventEntityQueries.kt index 5a48e022..182e58a3 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventEntityQueries.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/TimelineEventEntityQueries.kt @@ -16,12 +16,10 @@ package im.vector.matrix.android.internal.database.query +import im.vector.matrix.android.api.session.room.send.SendState import im.vector.matrix.android.internal.database.model.* import im.vector.matrix.android.internal.database.model.EventEntity.LinkFilterMode.* -import io.realm.Realm -import io.realm.RealmList -import io.realm.RealmQuery -import io.realm.Sort +import io.realm.* import io.realm.kotlin.where internal fun TimelineEventEntity.Companion.where(realm: Realm, eventId: String): RealmQuery { @@ -114,3 +112,15 @@ internal fun RealmList.find(eventId: String): TimelineEvent .equalTo(TimelineEventEntityFields.ROOT.EVENT_ID, eventId) .findFirst() } + +internal fun TimelineEventEntity.Companion.findAllInRoomWithSendStates(realm: Realm, + roomId: String, + sendStates: List) + : RealmResults { + + val sendStatesStr = sendStates.map { it.name }.toTypedArray() + return realm.where() + .equalTo(TimelineEventEntityFields.ROOM_ID, roomId) + .`in`(TimelineEventEntityFields.ROOT.SEND_STATE_STR,sendStatesStr) + .findAll() +} \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt index 8b65be24..d822e949 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/DefaultSendService.kt @@ -34,6 +34,7 @@ import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.model.EventEntity import im.vector.matrix.android.internal.database.model.RoomEntity import im.vector.matrix.android.internal.database.model.TimelineEventEntity +import im.vector.matrix.android.internal.database.query.findAllInRoomWithSendStates import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.session.content.UploadContentWorker import im.vector.matrix.android.internal.session.room.timeline.TimelineSendEventWorkCommon @@ -188,48 +189,47 @@ internal class DefaultSendService @Inject constructor(private val context: Conte override fun resendAllFailedMessages() { monarchy.writeAsync { realm -> - RoomEntity.where(realm, roomId).findFirst()?.let { room -> - room.sendingTimelineEvents.filter { - it.root?.sendState?.hasFailed() ?: false - }.sortedBy { it.root?.originServerTs ?: 0 }.forEach { timelineEventEntity -> - timelineEventEntity.root?.let { - val event = it.asDomain() - when (event.getClearType()) { - EventType.MESSAGE, - EventType.REDACTION, - EventType.REACTION -> { - val content = event.getClearContent().toModel() - if (content != null) { - when (content.type) { - MessageType.MSGTYPE_EMOTE, - MessageType.MSGTYPE_NOTICE, - MessageType.MSGTYPE_LOCATION, - MessageType.MSGTYPE_TEXT -> { - it.sendState = SendState.UNSENT - sendEvent(event) - } - MessageType.MSGTYPE_FILE, - MessageType.MSGTYPE_VIDEO, - MessageType.MSGTYPE_IMAGE, - MessageType.MSGTYPE_AUDIO -> { - //need to resend the attachement - } - else -> { - Timber.e("Cannot resend message ${event.type} / ${content.type}") - } + TimelineEventEntity + .findAllInRoomWithSendStates(realm, roomId, SendState.HAS_FAILED_STATES) + .sortedBy { it.root?.originServerTs ?: 0 } + .forEach { timelineEventEntity -> + timelineEventEntity.root?.let { + val event = it.asDomain() + when (event.getClearType()) { + EventType.MESSAGE, + EventType.REDACTION, + EventType.REACTION -> { + val content = event.getClearContent().toModel() + if (content != null) { + when (content.type) { + MessageType.MSGTYPE_EMOTE, + MessageType.MSGTYPE_NOTICE, + MessageType.MSGTYPE_LOCATION, + MessageType.MSGTYPE_TEXT -> { + it.sendState = SendState.UNSENT + sendEvent(event) + } + MessageType.MSGTYPE_FILE, + MessageType.MSGTYPE_VIDEO, + MessageType.MSGTYPE_IMAGE, + MessageType.MSGTYPE_AUDIO -> { + //need to resend the attachement + } + else -> { + Timber.e("Cannot resend message ${event.type} / ${content.type}") + } + } + } else { + Timber.e("Unsupported message to resend ${event.type}") } - } else { + } + else -> { Timber.e("Unsupported message to resend ${event.type}") } } - else -> { - Timber.e("Unsupported message to resend ${event.type}") - } } } - } - } } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt index b2a58472..10f4874f 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/timeline/DefaultTimeline.kt @@ -19,16 +19,14 @@ package im.vector.matrix.android.internal.session.room.timeline import im.vector.matrix.android.api.MatrixCallback import im.vector.matrix.android.api.session.crypto.CryptoService import im.vector.matrix.android.api.session.events.model.EventType +import im.vector.matrix.android.api.session.room.send.SendState import im.vector.matrix.android.api.session.room.timeline.Timeline import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.matrix.android.api.util.CancelableBag import im.vector.matrix.android.internal.database.mapper.asDomain import im.vector.matrix.android.internal.database.model.* import im.vector.matrix.android.internal.database.model.EventEntity -import im.vector.matrix.android.internal.database.query.findIncludingEvent -import im.vector.matrix.android.internal.database.query.findLastLiveChunkFromRoom -import im.vector.matrix.android.internal.database.query.where -import im.vector.matrix.android.internal.database.query.whereInRoom +import im.vector.matrix.android.internal.database.query.* import im.vector.matrix.android.internal.task.TaskConstraints import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.configureWith @@ -208,21 +206,15 @@ internal class DefaultTimeline( } override fun pendingEventCount(): Int { - var count = 0 - Realm.getInstance(realmConfiguration).use { - count = RoomEntity.where(it, roomId).findFirst()?.sendingTimelineEvents?.count() ?: 0 + return Realm.getInstance(realmConfiguration).use { + RoomEntity.where(it, roomId).findFirst()?.sendingTimelineEvents?.count() ?: 0 } - return count } override fun failedToDeliverEventCount(): Int { - var count = 0 - Realm.getInstance(realmConfiguration).use { - count = RoomEntity.where(it, roomId).findFirst()?.sendingTimelineEvents?.filter { - it.root?.sendState?.hasFailed() ?: false - }?.count() ?: 0 + return Realm.getInstance(realmConfiguration).use { + TimelineEventEntity.findAllInRoomWithSendStates(it, roomId, SendState.HAS_FAILED_STATES).count() } - return count } override fun start() {