From 40a68c3e9f30b84b31eaba309df43f2aafd739ef Mon Sep 17 00:00:00 2001 From: Valere Date: Fri, 19 Jul 2019 16:13:35 +0200 Subject: [PATCH] Show pending edits by fading the event body #193 + Fix issues with edits local echo management in aggregation --- .../room/EventRelationsAggregationTask.kt | 48 ++++++++++++------- .../detail/timeline/item/AbsMessageItem.kt | 5 +- .../timeline/item/MessageInformationData.kt | 3 +- .../util/MessageInformationDataFactory.kt | 3 +- 4 files changed, 39 insertions(+), 20 deletions(-) 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 867ca2874f..2e1a4273e5 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 @@ -83,21 +83,21 @@ internal class DefaultEventRelationsAggregationTask @Inject constructor( if (event.unsignedData?.relations?.annotations != null) { Timber.v("###REACTION Agreggation in room $roomId for event ${event.eventId}") handleInitialAggregatedRelations(event, roomId, event.unsignedData.relations.annotations, realm) - } else { - val content: MessageContent? = event.content.toModel() - if (content?.relatesTo?.type == RelationType.REPLACE) { - Timber.v("###REPLACE in room $roomId for event ${event.eventId}") - //A replace! - handleReplace(realm, event, content, roomId, isLocalEcho) + + EventAnnotationsSummaryEntity.where(realm, event.eventId + ?: "").findFirst()?.let { + TimelineEventEntity.where(realm, eventId = event.eventId + ?: "").findFirst()?.let { tet -> + tet.annotations = it + } } } - EventAnnotationsSummaryEntity.where(realm, event.eventId - ?: "").findFirst()?.let { - TimelineEventEntity.where(realm, eventId = event.eventId - ?: "").findFirst()?.let { tet -> - tet.annotations = it - } + val content: MessageContent? = event.content.toModel() + if (content?.relatesTo?.type == RelationType.REPLACE) { + Timber.v("###REPLACE in room $roomId for event ${event.eventId}") + //A replace! + handleReplace(realm, event, content, roomId, isLocalEcho) } @@ -178,11 +178,12 @@ internal class DefaultEventRelationsAggregationTask @Inject constructor( Timber.v("###REPLACE new edit summary for ${targetEventId}, creating one (localEcho:$isLocalEcho)") //create the edit summary val editSummary = realm.createObject(EditAggregatedSummaryEntity::class.java) - editSummary.lastEditTs = event.originServerTs ?: System.currentTimeMillis() editSummary.aggregatedContent = ContentMapper.map(newContent) if (isLocalEcho) { + editSummary.lastEditTs = 0 editSummary.sourceLocalEchoEvents.add(eventId) } else { + editSummary.lastEditTs = event.originServerTs ?: 0 editSummary.sourceEvents.add(eventId) } @@ -200,13 +201,26 @@ internal class DefaultEventRelationsAggregationTask @Inject constructor( Timber.v("###REPLACE Receiving remote echo of edit (edit already done)") existingSummary.sourceLocalEchoEvents.remove(txId) existingSummary.sourceEvents.add(event.eventId) - } else if (event.originServerTs ?: 0 > existingSummary.lastEditTs) { + } else if ( + isLocalEcho // do not rely on ts for local echo, take it + || event.originServerTs ?: 0 >= existingSummary.lastEditTs + ) { Timber.v("###REPLACE Computing aggregated edit summary (isLocalEcho:$isLocalEcho)") - existingSummary.lastEditTs = event.originServerTs ?: System.currentTimeMillis() + if (!isLocalEcho) { + //Do not take local echo originServerTs here, could mess up ordering (keep old ts) + existingSummary.lastEditTs = event.originServerTs ?: System.currentTimeMillis() + } existingSummary.aggregatedContent = ContentMapper.map(newContent) - existingSummary.sourceEvents.add(eventId) + if (isLocalEcho) { + existingSummary.sourceLocalEchoEvents.add(eventId) + } else { + existingSummary.sourceEvents.add(eventId) + } } else { - //ignore this event for the summary + //ignore this event for the summary (back paginate) + if (!isLocalEcho) { + existingSummary.sourceEvents.add(eventId) + } Timber.v("###REPLACE ignoring event for summary, it's to old $eventId") } } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsMessageItem.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsMessageItem.kt index 88697db4dc..6e4f499486 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsMessageItem.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/AbsMessageItem.kt @@ -29,6 +29,7 @@ import androidx.core.view.children import androidx.core.view.isGone import androidx.core.view.isVisible import com.airbnb.epoxy.EpoxyAttribute +import im.vector.matrix.android.api.session.room.send.SendState import im.vector.riotx.R import im.vector.riotx.core.resources.ColorProvider import im.vector.riotx.core.utils.DebouncedClickListener @@ -163,7 +164,9 @@ abstract class AbsMessageItem : BaseEventItem() { protected fun renderSendState(root: View, textView: TextView?) { root.isClickable = informationData.sendState.isSent() - textView?.setTextColor(colorProvider.getMessageTextColor(informationData.sendState)) + val state = SendState.UNSENT.takeIf { informationData.hasPendingEdits } + ?: informationData.sendState + textView?.setTextColor(colorProvider.getMessageTextColor(state)) } abstract class Holder(@IdRes stubId: Int) : BaseHolder(stubId) { diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageInformationData.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageInformationData.kt index 5f49fdc360..092f8ce745 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageInformationData.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/item/MessageInformationData.kt @@ -31,7 +31,8 @@ data class MessageInformationData( val showInformation: Boolean = true, /*List of reactions (emoji,count,isSelected)*/ var orderedReactionList: List? = null, - var hasBeenEdited: Boolean = false + var hasBeenEdited: Boolean = false, + var hasPendingEdits: Boolean = false ) : Parcelable diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/util/MessageInformationDataFactory.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/util/MessageInformationDataFactory.kt index d17c8de62f..eb13ac7b33 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/util/MessageInformationDataFactory.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/timeline/util/MessageInformationDataFactory.kt @@ -74,7 +74,8 @@ class MessageInformationDataFactory @Inject constructor(private val timelineDate ?.map { ReactionInfoData(it.key, it.count, it.addedByMe, it.localEchoEvents.isEmpty()) }, - hasBeenEdited = hasBeenEdited + hasBeenEdited = hasBeenEdited, + hasPendingEdits = event.annotations?.editSummary?.localEchos?.any() ?: false ) } } \ No newline at end of file