From 23ff74d2e4fdafb12529c245fefdcbdc26de3cd5 Mon Sep 17 00:00:00 2001 From: kyori19 Date: Mon, 7 Mar 2022 16:18:19 +0900 Subject: [PATCH] Fix network timeline gap loading --- .../viewmodel/NetworkTimelineViewModel.kt | 54 +++++++++++++------ 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineViewModel.kt b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineViewModel.kt index 642ab333f..553fbf49b 100644 --- a/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineViewModel.kt +++ b/app/src/main/java/com/keylesspalace/tusky/components/timeline/viewmodel/NetworkTimelineViewModel.kt @@ -136,6 +136,10 @@ class NetworkTimelineViewModel @Inject constructor( override fun loadMore(placeholderId: String) { viewModelScope.launch { try { + val placeholderIndex = + statusData.indexOfFirst { it is StatusViewData.Placeholder && it.id == placeholderId } + statusData[placeholderIndex] = StatusViewData.Placeholder(placeholderId, isLoading = true) + val statusResponse = fetchStatusesForKind( fromId = placeholderId.inc(), uptoId = null, @@ -148,28 +152,46 @@ class NetworkTimelineViewModel @Inject constructor( return@launch } + statusData.removeAt(placeholderIndex) + val activeAccount = accountManager.activeAccount!! - val data = statuses.map { status -> - val oldStatus = statusData.find { s -> - s.asStatusOrNull()?.id == status.id - }?.asStatusOrNull() - - val contentShowing = oldStatus?.isShowingContent ?: activeAccount.alwaysShowSensitiveMedia || !status.actionableStatus.sensitive - val expanded = oldStatus?.isExpanded ?: activeAccount.alwaysOpenSpoiler - val contentCollapsed = oldStatus?.isCollapsed ?: true - status.toViewData( - isShowingContent = contentShowing, - isExpanded = expanded, - isCollapsed = contentCollapsed + isShowingContent = activeAccount.alwaysShowSensitiveMedia || !status.actionableStatus.sensitive, + isExpanded = activeAccount.alwaysOpenSpoiler, + isCollapsed = true ) + }.toMutableList() + + if (statuses.isNotEmpty()) { + val firstId = statuses.first().id.hashCode().toLong() + val lastId = statuses.last().id.hashCode().toLong() + val overlappedFrom = statusData.indexOfFirst { it.viewDataId <= firstId } + val overlappedTo = statusData.indexOfFirst { it.viewDataId < lastId } + + if (overlappedFrom < overlappedTo) { + repeat(overlappedTo - overlappedFrom) { + statusData[overlappedFrom].asStatusOrNull()?.let { oldStatus -> + val dataIndex = statuses.indexOfFirst { it.id == oldStatus.id } + if (dataIndex == -1) { + return@let + } + data[dataIndex] = data[dataIndex] + .copy( + isShowingContent = oldStatus.isShowingContent, + isExpanded = oldStatus.isExpanded, + isCollapsed = oldStatus.isCollapsed, + ) + } + + statusData.removeAt(overlappedFrom) + } + } else { + statusData.add(overlappedFrom, StatusViewData.Placeholder(statuses.last().id.dec(), isLoading = false)) + } } - val index = - statusData.indexOfFirst { it is StatusViewData.Placeholder && it.id == placeholderId } - statusData.removeAt(index) - statusData.addAll(index, data) + statusData.addAll(placeholderIndex, data) currentSource?.invalidate() } catch (e: Exception) {