Timeline : fix 4959

This commit is contained in:
ganfra 2022-01-17 19:16:32 +01:00 committed by Benoit Marty
parent 576931c21a
commit cc89a8fc77
2 changed files with 15 additions and 2 deletions

1
changelog.d/4959.bugfix Normal file
View File

@ -0,0 +1 @@
Prevent crash in Timeline and add more logs.

View File

@ -72,6 +72,7 @@ import org.matrix.android.sdk.api.session.room.timeline.Timeline
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
import timber.log.Timber
import javax.inject.Inject
import kotlin.math.min
import kotlin.system.measureTimeMillis
class TimelineEventController @Inject constructor(private val dateFormatter: VectorDateFormatter,
@ -185,6 +186,8 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
override fun onChanged(position: Int, count: Int, payload: Any?) {
synchronized(modelCache) {
assertUpdateCallbacksAllowed()
Timber.v("listUpdateCallback.onChanged(position: $position, count: $count). " +
"\ncurrentSnapshot has size of ${currentSnapshot.size} items")
(position until position + count).forEach {
// Invalidate cache
modelCache[it] = null
@ -192,10 +195,12 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
// 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 {
// In some cases onChanged will be called before onRemoved and onInserted so position will be smaller than currentSnapshot.size.
val prevList = currentSnapshot.subList(0, min(position, currentSnapshot.size))
val prevDisplayableEventIndex = prevList.indexOfLast {
timelineEventVisibilityHelper.shouldShowEvent(it, partialState.highlightedEventId)
}
if (prevDisplayableEventIndex != -1 && currentSnapshot[prevDisplayableEventIndex].senderInfo.userId == invalidatedSenderId) {
if (prevDisplayableEventIndex != -1 && currentSnapshot.getOrNull(prevDisplayableEventIndex)?.senderInfo?.userId == invalidatedSenderId) {
modelCache[prevDisplayableEventIndex] = null
}
requestModelBuild()
@ -205,6 +210,8 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
override fun onMoved(fromPosition: Int, toPosition: Int) {
synchronized(modelCache) {
assertUpdateCallbacksAllowed()
Timber.v("listUpdateCallback.onMoved(fromPosition: $fromPosition, toPosition: $toPosition). " +
"\ncurrentSnapshot has size of ${currentSnapshot.size} items")
val model = modelCache.removeAt(fromPosition)
modelCache.add(toPosition, model)
requestModelBuild()
@ -214,6 +221,8 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
override fun onInserted(position: Int, count: Int) {
synchronized(modelCache) {
assertUpdateCallbacksAllowed()
Timber.v("listUpdateCallback.onInserted(position: $position, count: $count). " +
"\ncurrentSnapshot has size of ${currentSnapshot.size} items")
repeat(count) {
modelCache.add(position, null)
}
@ -224,6 +233,8 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
override fun onRemoved(position: Int, count: Int) {
synchronized(modelCache) {
assertUpdateCallbacksAllowed()
Timber.v("listUpdateCallback.onRemoved(position: $position, count: $count). " +
"\ncurrentSnapshot has size of ${currentSnapshot.size} items")
repeat(count) {
modelCache.removeAt(position)
}
@ -306,6 +317,7 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
inSubmitList = true
val diffCallback = TimelineEventDiffUtilCallback(currentSnapshot, newSnapshot)
currentSnapshot = newSnapshot
Timber.v("Submit a new snapshot of ${currentSnapshot.size} items.")
val diffResult = DiffUtil.calculateDiff(diffCallback)
diffResult.dispatchUpdatesTo(listUpdateCallback)
requestDelayedModelBuild(0)