From 8b1411f533830543915ee70bac0bd34e92536e2d Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 23 Oct 2019 16:13:35 +0200 Subject: [PATCH] Read marker: test if local echo before hitting the SDK to change read marker id + reduce a bit delay --- .../android/api/session/events/model/LocalEcho.kt | 9 +++++++++ .../internal/database/query/ReadQueries.kt | 3 ++- .../session/room/EventRelationsAggregationTask.kt | 2 +- .../internal/session/room/prune/PruneEventTask.kt | 3 ++- .../session/room/read/SetReadMarkersTask.kt | 5 +++-- .../session/room/send/LocalEchoEventFactory.kt | 6 +----- .../vector/riotx/core/ui/views/ReadMarkerView.kt | 2 +- .../home/room/detail/RoomDetailFragment.kt | 15 +++++++++++---- 8 files changed, 30 insertions(+), 15 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/LocalEcho.kt diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/LocalEcho.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/LocalEcho.kt new file mode 100644 index 0000000000..a34791856d --- /dev/null +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/session/events/model/LocalEcho.kt @@ -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) + +} diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadQueries.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadQueries.kt index b52f35fa92..65f20a5d41 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadQueries.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/database/query/ReadQueries.kt @@ -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 diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/EventRelationsAggregationTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/EventRelationsAggregationTask.kt index 00d6619ce7..f181494e1d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/EventRelationsAggregationTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/EventRelationsAggregationTask.kt @@ -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!! diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/prune/PruneEventTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/prune/PruneEventTask.kt index c55007c54a..06fb403f86 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/prune/PruneEventTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/prune/PruneEventTask.kt @@ -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() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/read/SetReadMarkersTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/read/SetReadMarkersTask.kt index 3ed322b483..1fd771cf0b 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/read/SetReadMarkersTask.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/read/SetReadMarkersTask.kt @@ -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 diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt index a4ce62e1f0..1d3f4def19 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/room/send/LocalEchoEventFactory.kt @@ -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." - // //
// In reply to @@ -419,7 +417,5 @@ internal class LocalEchoEventFactory @Inject constructor(@UserId private val use // // No whitespace because currently breaks temporary formatted text to Span const val REPLY_PATTERN = """
%s%s
%s
%s""" - - fun isLocalEchoId(eventId: String): Boolean = eventId.startsWith(LOCAL_ID_PREFIX) } } diff --git a/vector/src/main/java/im/vector/riotx/core/ui/views/ReadMarkerView.kt b/vector/src/main/java/im/vector/riotx/core/ui/views/ReadMarkerView.kt index ba21d250d8..0fb8b55250 100644 --- a/vector/src/main/java/im/vector/riotx/core/ui/views/ReadMarkerView.kt +++ b/vector/src/main/java/im/vector/riotx/core/ui/views/ReadMarkerView.kt @@ -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, diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt index 9aa2f3cccd..6d80b4a3b7 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt @@ -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))