Read marker: test if local echo before hitting the SDK to change read marker id + reduce a bit delay

This commit is contained in:
ganfra 2019-10-23 16:13:35 +02:00
parent 3196dcb57e
commit 8b1411f533
8 changed files with 30 additions and 15 deletions

View File

@ -0,0 +1,9 @@
package im.vector.matrix.android.api.session.events.model
object LocalEcho {
const val PREFIX = "local."
fun isLocalEchoId(eventId: String): Boolean = eventId.startsWith(PREFIX)
}

View File

@ -16,6 +16,7 @@
package im.vector.matrix.android.internal.database.query
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.events.model.LocalEcho
import im.vector.matrix.android.internal.database.model.ChunkEntity
import im.vector.matrix.android.internal.database.model.ReadReceiptEntity
import im.vector.matrix.android.internal.session.room.send.LocalEchoEventFactory
@ -27,7 +28,7 @@ internal fun isEventRead(monarchy: Monarchy,
if (userId.isNullOrBlank() || roomId.isNullOrBlank() || eventId.isNullOrBlank()) {
return false
}
if (LocalEchoEventFactory.isLocalEchoId(eventId)) {
if (LocalEcho.isLocalEchoId(eventId)) {
return true
}
var isEventRead = false

View File

@ -71,7 +71,7 @@ internal class DefaultEventRelationsAggregationTask @Inject constructor(
Timber.w("Event has no room id ${event.eventId}")
return@forEach
}
val isLocalEcho = LocalEchoEventFactory.isLocalEchoId(event.eventId ?: "")
val isLocalEcho = LocalEcho.isLocalEchoId(event.eventId ?: "")
when (event.type) {
EventType.REACTION -> {
// we got a reaction!!

View File

@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.session.room.prune
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.EventType
import im.vector.matrix.android.api.session.events.model.LocalEcho
import im.vector.matrix.android.api.session.events.model.UnsignedData
import im.vector.matrix.android.internal.database.helper.updateSenderData
import im.vector.matrix.android.internal.database.mapper.ContentMapper
@ -59,7 +60,7 @@ internal class DefaultPruneEventTask @Inject constructor(private val monarchy: M
// Check that we know this event
EventEntity.where(realm, eventId = redactionEvent.eventId ?: "").findFirst() ?: return
val isLocalEcho = LocalEchoEventFactory.isLocalEchoId(redactionEvent.eventId ?: "")
val isLocalEcho = LocalEcho.isLocalEchoId(redactionEvent.eventId ?: "")
Timber.v("Redact event for ${redactionEvent.redacts} localEcho=$isLocalEcho")
val eventToPrune = EventEntity.where(realm, eventId = redactionEvent.redacts).findFirst()

View File

@ -17,6 +17,7 @@
package im.vector.matrix.android.internal.session.room.read
import com.zhuinden.monarchy.Monarchy
import im.vector.matrix.android.api.session.events.model.LocalEcho
import im.vector.matrix.android.internal.database.model.ReadMarkerEntity
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
import im.vector.matrix.android.internal.database.model.TimelineEventEntity
@ -73,7 +74,7 @@ internal class DefaultSetReadMarkersTask @Inject constructor(private val roomAPI
}
if (fullyReadEventId != null && isReadMarkerMoreRecent(params.roomId, fullyReadEventId)) {
if (LocalEchoEventFactory.isLocalEchoId(fullyReadEventId)) {
if (LocalEcho.isLocalEchoId(fullyReadEventId)) {
Timber.w("Can't set read marker for local event $fullyReadEventId")
} else {
markers[READ_MARKER] = fullyReadEventId
@ -82,7 +83,7 @@ internal class DefaultSetReadMarkersTask @Inject constructor(private val roomAPI
if (readReceiptEventId != null
&& !isEventRead(monarchy, userId, params.roomId, readReceiptEventId)) {
if (LocalEchoEventFactory.isLocalEchoId(readReceiptEventId)) {
if (LocalEcho.isLocalEchoId(readReceiptEventId)) {
Timber.w("Can't set read receipt for local event $readReceiptEventId")
} else {
markers[READ_RECEIPT] = readReceiptEventId

View File

@ -281,7 +281,7 @@ internal class LocalEchoEventFactory @Inject constructor(@UserId private val use
}
private fun dummyEventId(): String {
return "$LOCAL_ID_PREFIX${UUID.randomUUID()}"
return "${LocalEcho.PREFIX}${UUID.randomUUID()}"
}
fun createReplyTextEvent(roomId: String, eventReplied: TimelineEvent, replyText: String, autoMarkdown: Boolean): Event? {
@ -407,8 +407,6 @@ internal class LocalEchoEventFactory @Inject constructor(@UserId private val use
}
companion object {
const val LOCAL_ID_PREFIX = "local."
// <mx-reply>
// <blockquote>
// <a href="https://matrix.to/#/!somewhere:domain.com/$event:domain.com">In reply to</a>
@ -419,7 +417,5 @@ internal class LocalEchoEventFactory @Inject constructor(@UserId private val use
// </mx-reply>
// No whitespace because currently breaks temporary formatted text to Span
const val REPLY_PATTERN = """<mx-reply><blockquote><a href="%s">%s</a><a href="%s">%s</a><br />%s</blockquote></mx-reply>%s"""
fun isLocalEchoId(eventId: String): Boolean = eventId.startsWith(LOCAL_ID_PREFIX)
}
}

View File

@ -26,7 +26,7 @@ import android.view.animation.AnimationUtils
import im.vector.riotx.R
import kotlinx.coroutines.*
private const val DELAY_IN_MS = 1_500L
private const val DELAY_IN_MS = 1_000L
class ReadMarkerView @JvmOverloads constructor(
context: Context,

View File

@ -61,6 +61,7 @@ import com.otaliastudios.autocomplete.CharPolicy
import im.vector.matrix.android.api.permalinks.PermalinkFactory
import im.vector.matrix.android.api.session.Session
import im.vector.matrix.android.api.session.events.model.Event
import im.vector.matrix.android.api.session.events.model.LocalEcho
import im.vector.matrix.android.api.session.room.model.Membership
import im.vector.matrix.android.api.session.room.model.message.*
import im.vector.matrix.android.api.session.room.send.SendState
@ -1023,10 +1024,16 @@ class RoomDetailFragment :
return
}
val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()
val firstVisibleItem = timelineEventController.adapter.getModelAtPosition(firstVisibleItemPosition)
val nextReadMarkerId = when (firstVisibleItem) {
is BaseEventItem -> firstVisibleItem.getEventIds().firstOrNull()
else -> null
var nextReadMarkerId: String? = null
for (itemPosition in firstVisibleItemPosition until lastVisibleItemPosition) {
val timelineItem = timelineEventController.adapter.getModelAtPosition(itemPosition)
if (timelineItem is BaseEventItem) {
val eventId = timelineItem.getEventIds().firstOrNull() ?: continue
if (!LocalEcho.isLocalEchoId(eventId)) {
nextReadMarkerId = eventId
break
}
}
}
if (nextReadMarkerId != null) {
roomDetailViewModel.process(RoomDetailActions.SetReadMarkerAction(nextReadMarkerId))