From 919ebaa82e43aa2f1906f54b213ae15b0b56f5ef Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 24 Jun 2021 12:41:23 +0200 Subject: [PATCH 1/2] Fix some issues with timeline cache invalidation and visibility. --- changelog.d/3542.bugfix | 1 + .../detail/timeline/TimelineEventController.kt | 18 ++++++++++++++++-- .../factory/TimelineItemFactoryParams.kt | 1 + .../helper/MessageInformationDataFactory.kt | 15 ++++++++------- 4 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 changelog.d/3542.bugfix diff --git a/changelog.d/3542.bugfix b/changelog.d/3542.bugfix new file mode 100644 index 0000000000..8e133e1e30 --- /dev/null +++ b/changelog.d/3542.bugfix @@ -0,0 +1 @@ +Fix some issues with timeline cache invalidation and visibility. \ No newline at end of file diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt index a0f87b9749..bbb1b7a06f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt @@ -39,13 +39,13 @@ import im.vector.app.features.home.room.detail.UnreadState import im.vector.app.features.home.room.detail.timeline.factory.MergedHeaderItemFactory import im.vector.app.features.home.room.detail.timeline.factory.ReadReceiptsItemFactory import im.vector.app.features.home.room.detail.timeline.factory.TimelineItemFactory +import im.vector.app.features.home.room.detail.timeline.factory.TimelineItemFactoryParams import im.vector.app.features.home.room.detail.timeline.helper.ContentDownloadStateTrackerBinder import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder import im.vector.app.features.home.room.detail.timeline.helper.TimelineControllerInterceptorHelper import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventDiffUtilCallback import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventVisibilityHelper import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventVisibilityStateChangedListener -import im.vector.app.features.home.room.detail.timeline.factory.TimelineItemFactoryParams import im.vector.app.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider import im.vector.app.features.home.room.detail.timeline.item.AbsMessageItem import im.vector.app.features.home.room.detail.timeline.item.BasedMergedItem @@ -163,10 +163,19 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec override fun onChanged(position: Int, count: Int, payload: Any?) { synchronized(modelCache) { assertUpdateCallbacksAllowed() - (position until (position + count)).forEach { + (position until position + count).forEach { // Invalidate cache modelCache[it] = null } + // Also invalidate the first previous displayable event if + // it's sent by the same user so we are sure we have up to date information. + val invalidatedSenderId: String? = currentSnapshot.getOrNull(position)?.senderInfo?.userId + val prevDisplayableEventIndex = currentSnapshot.subList(0, position).indexOfLast { + timelineEventVisibilityHelper.shouldShowEvent(it, eventIdToHighlight) + } + if (prevDisplayableEventIndex != -1 && currentSnapshot[prevDisplayableEventIndex].senderInfo.userId == invalidatedSenderId) { + modelCache[prevDisplayableEventIndex] = null + } requestModelBuild() } } @@ -209,6 +218,7 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec ) init { + isDebugLoggingEnabled = true addInterceptor(this) requestModelBuild() } @@ -340,10 +350,14 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec val event = currentSnapshot[position] val nextEvent = currentSnapshot.nextOrNull(position) val prevEvent = currentSnapshot.prevOrNull(position) + val nextDisplayableEvent = currentSnapshot.subList(position + 1, currentSnapshot.size).firstOrNull { + timelineEventVisibilityHelper.shouldShowEvent(it, eventIdToHighlight) + } val params = TimelineItemFactoryParams( event = event, prevEvent = prevEvent, nextEvent = nextEvent, + nextDisplayableEvent = nextDisplayableEvent, highlightedEventId = eventIdToHighlight, lastSentEventIdWithoutReadReceipts = lastSentEventWithoutReadReceipts, callback = callback diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/TimelineItemFactoryParams.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/TimelineItemFactoryParams.kt index f92cd2800a..0e595ba30e 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/TimelineItemFactoryParams.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/TimelineItemFactoryParams.kt @@ -23,6 +23,7 @@ data class TimelineItemFactoryParams( val event: TimelineEvent, val prevEvent: TimelineEvent? = null, val nextEvent: TimelineEvent? = null, + val nextDisplayableEvent: TimelineEvent? = null, val highlightedEventId: String? = null, val lastSentEventIdWithoutReadReceipts: String? = null, val callback: TimelineEventController.Callback? = null diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt index 124b196f72..221149aced 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt @@ -50,27 +50,28 @@ import javax.inject.Inject class MessageInformationDataFactory @Inject constructor(private val session: Session, private val roomSummariesHolder: RoomSummariesHolder, private val dateFormatter: VectorDateFormatter, + private val visibilityHelper: TimelineEventVisibilityHelper, private val vectorPreferences: VectorPreferences) { fun create(params: TimelineItemFactoryParams): MessageInformationData { val event = params.event - val nextEvent = params.nextEvent + val nextDisplayableEvent = params.nextDisplayableEvent val eventId = event.eventId val date = event.root.localDateTime() - val nextDate = nextEvent?.root?.localDateTime() + val nextDate = nextDisplayableEvent?.root?.localDateTime() val addDaySeparator = date.toLocalDate() != nextDate?.toLocalDate() val isNextMessageReceivedMoreThanOneHourAgo = nextDate?.isBefore(date.minusMinutes(60)) ?: false val showInformation = addDaySeparator - || event.senderInfo.avatarUrl != nextEvent?.senderInfo?.avatarUrl - || event.senderInfo.disambiguatedDisplayName != nextEvent?.senderInfo?.disambiguatedDisplayName - || nextEvent.root.getClearType() !in listOf(EventType.MESSAGE, EventType.STICKER, EventType.ENCRYPTED) + || event.senderInfo.avatarUrl != nextDisplayableEvent?.senderInfo?.avatarUrl + || event.senderInfo.disambiguatedDisplayName != nextDisplayableEvent?.senderInfo?.disambiguatedDisplayName + || nextDisplayableEvent.root.getClearType() !in listOf(EventType.MESSAGE, EventType.STICKER, EventType.ENCRYPTED) || isNextMessageReceivedMoreThanOneHourAgo - || isTileTypeMessage(nextEvent) - || nextEvent.isEdition() + || isTileTypeMessage(nextDisplayableEvent) + || nextDisplayableEvent.isEdition() val time = dateFormatter.format(event.root.originServerTs, DateFormatKind.MESSAGE_SIMPLE) val e2eDecoration = getE2EDecoration(event) From d4009476f9bcfd76f3e449886765185cac281a35 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 2 Jul 2021 09:39:32 +0200 Subject: [PATCH 2/2] Cleanup --- .../home/room/detail/timeline/TimelineEventController.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt index bbb1b7a06f..95d7acb571 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt @@ -218,7 +218,6 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec ) init { - isDebugLoggingEnabled = true addInterceptor(this) requestModelBuild() }