Merge pull request #3553 from vector-im/feature/fga/fix_timeline_visibility
Fix some issues with timeline cache invalidation and visibility.
This commit is contained in:
commit
b0f7268d13
|
@ -0,0 +1 @@
|
||||||
|
Fix some issues with timeline cache invalidation and visibility.
|
|
@ -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.MergedHeaderItemFactory
|
||||||
import im.vector.app.features.home.room.detail.timeline.factory.ReadReceiptsItemFactory
|
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.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.ContentDownloadStateTrackerBinder
|
||||||
import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder
|
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.TimelineControllerInterceptorHelper
|
||||||
import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventDiffUtilCallback
|
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.TimelineEventVisibilityHelper
|
||||||
import im.vector.app.features.home.room.detail.timeline.helper.TimelineEventVisibilityStateChangedListener
|
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.helper.TimelineMediaSizeProvider
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.AbsMessageItem
|
import im.vector.app.features.home.room.detail.timeline.item.AbsMessageItem
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.BasedMergedItem
|
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?) {
|
override fun onChanged(position: Int, count: Int, payload: Any?) {
|
||||||
synchronized(modelCache) {
|
synchronized(modelCache) {
|
||||||
assertUpdateCallbacksAllowed()
|
assertUpdateCallbacksAllowed()
|
||||||
(position until (position + count)).forEach {
|
(position until position + count).forEach {
|
||||||
// Invalidate cache
|
// Invalidate cache
|
||||||
modelCache[it] = null
|
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()
|
requestModelBuild()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -340,10 +349,14 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
|
||||||
val event = currentSnapshot[position]
|
val event = currentSnapshot[position]
|
||||||
val nextEvent = currentSnapshot.nextOrNull(position)
|
val nextEvent = currentSnapshot.nextOrNull(position)
|
||||||
val prevEvent = currentSnapshot.prevOrNull(position)
|
val prevEvent = currentSnapshot.prevOrNull(position)
|
||||||
|
val nextDisplayableEvent = currentSnapshot.subList(position + 1, currentSnapshot.size).firstOrNull {
|
||||||
|
timelineEventVisibilityHelper.shouldShowEvent(it, eventIdToHighlight)
|
||||||
|
}
|
||||||
val params = TimelineItemFactoryParams(
|
val params = TimelineItemFactoryParams(
|
||||||
event = event,
|
event = event,
|
||||||
prevEvent = prevEvent,
|
prevEvent = prevEvent,
|
||||||
nextEvent = nextEvent,
|
nextEvent = nextEvent,
|
||||||
|
nextDisplayableEvent = nextDisplayableEvent,
|
||||||
highlightedEventId = eventIdToHighlight,
|
highlightedEventId = eventIdToHighlight,
|
||||||
lastSentEventIdWithoutReadReceipts = lastSentEventWithoutReadReceipts,
|
lastSentEventIdWithoutReadReceipts = lastSentEventWithoutReadReceipts,
|
||||||
callback = callback
|
callback = callback
|
||||||
|
|
|
@ -23,6 +23,7 @@ data class TimelineItemFactoryParams(
|
||||||
val event: TimelineEvent,
|
val event: TimelineEvent,
|
||||||
val prevEvent: TimelineEvent? = null,
|
val prevEvent: TimelineEvent? = null,
|
||||||
val nextEvent: TimelineEvent? = null,
|
val nextEvent: TimelineEvent? = null,
|
||||||
|
val nextDisplayableEvent: TimelineEvent? = null,
|
||||||
val highlightedEventId: String? = null,
|
val highlightedEventId: String? = null,
|
||||||
val lastSentEventIdWithoutReadReceipts: String? = null,
|
val lastSentEventIdWithoutReadReceipts: String? = null,
|
||||||
val callback: TimelineEventController.Callback? = null
|
val callback: TimelineEventController.Callback? = null
|
||||||
|
|
|
@ -50,27 +50,28 @@ import javax.inject.Inject
|
||||||
class MessageInformationDataFactory @Inject constructor(private val session: Session,
|
class MessageInformationDataFactory @Inject constructor(private val session: Session,
|
||||||
private val roomSummariesHolder: RoomSummariesHolder,
|
private val roomSummariesHolder: RoomSummariesHolder,
|
||||||
private val dateFormatter: VectorDateFormatter,
|
private val dateFormatter: VectorDateFormatter,
|
||||||
|
private val visibilityHelper: TimelineEventVisibilityHelper,
|
||||||
private val vectorPreferences: VectorPreferences) {
|
private val vectorPreferences: VectorPreferences) {
|
||||||
|
|
||||||
fun create(params: TimelineItemFactoryParams): MessageInformationData {
|
fun create(params: TimelineItemFactoryParams): MessageInformationData {
|
||||||
val event = params.event
|
val event = params.event
|
||||||
val nextEvent = params.nextEvent
|
val nextDisplayableEvent = params.nextDisplayableEvent
|
||||||
val eventId = event.eventId
|
val eventId = event.eventId
|
||||||
|
|
||||||
val date = event.root.localDateTime()
|
val date = event.root.localDateTime()
|
||||||
val nextDate = nextEvent?.root?.localDateTime()
|
val nextDate = nextDisplayableEvent?.root?.localDateTime()
|
||||||
val addDaySeparator = date.toLocalDate() != nextDate?.toLocalDate()
|
val addDaySeparator = date.toLocalDate() != nextDate?.toLocalDate()
|
||||||
val isNextMessageReceivedMoreThanOneHourAgo = nextDate?.isBefore(date.minusMinutes(60))
|
val isNextMessageReceivedMoreThanOneHourAgo = nextDate?.isBefore(date.minusMinutes(60))
|
||||||
?: false
|
?: false
|
||||||
|
|
||||||
val showInformation =
|
val showInformation =
|
||||||
addDaySeparator
|
addDaySeparator
|
||||||
|| event.senderInfo.avatarUrl != nextEvent?.senderInfo?.avatarUrl
|
|| event.senderInfo.avatarUrl != nextDisplayableEvent?.senderInfo?.avatarUrl
|
||||||
|| event.senderInfo.disambiguatedDisplayName != nextEvent?.senderInfo?.disambiguatedDisplayName
|
|| event.senderInfo.disambiguatedDisplayName != nextDisplayableEvent?.senderInfo?.disambiguatedDisplayName
|
||||||
|| nextEvent.root.getClearType() !in listOf(EventType.MESSAGE, EventType.STICKER, EventType.ENCRYPTED)
|
|| nextDisplayableEvent.root.getClearType() !in listOf(EventType.MESSAGE, EventType.STICKER, EventType.ENCRYPTED)
|
||||||
|| isNextMessageReceivedMoreThanOneHourAgo
|
|| isNextMessageReceivedMoreThanOneHourAgo
|
||||||
|| isTileTypeMessage(nextEvent)
|
|| isTileTypeMessage(nextDisplayableEvent)
|
||||||
|| nextEvent.isEdition()
|
|| nextDisplayableEvent.isEdition()
|
||||||
|
|
||||||
val time = dateFormatter.format(event.root.originServerTs, DateFormatKind.MESSAGE_SIMPLE)
|
val time = dateFormatter.format(event.root.originServerTs, DateFormatKind.MESSAGE_SIMPLE)
|
||||||
val e2eDecoration = getE2EDecoration(event)
|
val e2eDecoration = getE2EDecoration(event)
|
||||||
|
|
Loading…
Reference in New Issue