From fcd6e9c67ba49c3d0e4968ff25e890fa98ced1d1 Mon Sep 17 00:00:00 2001 From: Konrad Pozniak Date: Fri, 12 Jul 2024 08:59:43 +0200 Subject: [PATCH] fix updating boosts in network timeline (#4549) re: https://infosec.exchange/@webhat/112745609655586468 Boost were not correctly handled here, probably because they are only on profile timelines which I rarely check. This makes sure likes and boosts get correctly set to posts even when they are boosts. --- .../viewmodel/NetworkTimelineViewModel.kt | 38 +++++++------------ 1 file changed, 13 insertions(+), 25 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 a40bb418e..61552e95e 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 @@ -295,13 +295,7 @@ class NetworkTimelineViewModel @Inject constructor( } private fun handleStatusChangedEvent(status: Status) { - updateStatusById(status.id) { oldViewData -> - status.toViewData( - isShowingContent = oldViewData.isShowingContent, - isExpanded = oldViewData.isExpanded, - isCollapsed = oldViewData.isCollapsed - ) - } + updateStatusByActionableId(status.id) { status } } override fun fullReload() { @@ -311,7 +305,7 @@ class NetworkTimelineViewModel @Inject constructor( } override fun clearWarning(status: StatusViewData.Concrete) { - updateActionableStatusById(status.id) { + updateStatusByActionableId(status.id) { it.copy(filtered = emptyList()) } } @@ -399,23 +393,17 @@ class NetworkTimelineViewModel @Inject constructor( currentSource?.invalidate() } - private inline fun updateStatusById( - id: String, - updater: (StatusViewData.Concrete) -> StatusViewData.Concrete - ) { - val pos = statusData.indexOfFirst { it.asStatusOrNull()?.id == id } - if (pos == -1) return - updateViewDataAt(pos, updater) - } - - private inline fun updateActionableStatusById(id: String, updater: (Status) -> Status) { - val pos = statusData.indexOfFirst { it.asStatusOrNull()?.id == id } - if (pos == -1) return - updateViewDataAt(pos) { vd -> - if (vd.status.reblog != null) { - vd.copy(status = vd.status.copy(reblog = updater(vd.status.reblog))) - } else { - vd.copy(status = updater(vd.status)) + private inline fun updateStatusByActionableId(id: String, updater: (Status) -> Status) { + // posts can be multiple times in the timeline, e.g. once the original and once as boost + statusData.forEachIndexed { index, status -> + if (status.asStatusOrNull()?.actionableId == id) { + updateViewDataAt(index) { vd -> + if (vd.status.reblog != null) { + vd.copy(status = vd.status.copy(reblog = updater(vd.status.reblog))) + } else { + vd.copy(status = updater(vd.status)) + } + } } } }