diff --git a/changelog.d/8840.bugfix b/changelog.d/8840.bugfix new file mode 100644 index 00000000000..87175c2443d --- /dev/null +++ b/changelog.d/8840.bugfix @@ -0,0 +1 @@ +Fix redacted events not grouped correctly when hidden events are inserted between. diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt index 2149857ec27..b9457b9dc12 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt @@ -84,7 +84,7 @@ class MergedHeaderItemFactory @Inject constructor( buildRoomCreationMergedSummary(currentPosition, items, partialState, event, eventIdToHighlight, requestModelBuild, callback) isStartOfSameTypeEventsSummary(event, nextEvent, addDaySeparator) -> buildSameTypeEventsMergedSummary(currentPosition, items, partialState, event, eventIdToHighlight, requestModelBuild, callback) - isStartOfRedactedEventsSummary(event, items, currentPosition, addDaySeparator) -> + isStartOfRedactedEventsSummary(event, items, currentPosition, partialState, addDaySeparator) -> buildRedactedEventsMergedSummary(currentPosition, items, partialState, event, eventIdToHighlight, requestModelBuild, callback) else -> null } @@ -122,19 +122,25 @@ class MergedHeaderItemFactory @Inject constructor( * @param event the main timeline event * @param items all known items, sorted from newer event to oldest event * @param currentPosition the current position + * @param partialState partial state data * @param addDaySeparator true to add a day separator */ private fun isStartOfRedactedEventsSummary( event: TimelineEvent, items: List, currentPosition: Int, + partialState: TimelineEventController.PartialState, addDaySeparator: Boolean, ): Boolean { - val nextNonRedactionEvent = items - .subList(fromIndex = currentPosition + 1, toIndex = items.size) - .find { it.root.getClearType() != EventType.REDACTION } - return event.root.isRedacted() && - (!nextNonRedactionEvent?.root?.isRedacted().orFalse() || addDaySeparator) + val nextDisplayableEvent = items.subList(currentPosition + 1, items.size).firstOrNull { + timelineEventVisibilityHelper.shouldShowEvent( + timelineEvent = it, + highlightedEventId = partialState.highlightedEventId, + isFromThreadTimeline = partialState.isFromThreadTimeline(), + rootThreadEventId = partialState.rootThreadEventId + ) + } + return event.root.isRedacted() && (nextDisplayableEvent?.root?.isRedacted() == false || addDaySeparator) } private fun buildSameTypeEventsMergedSummary( diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineEventVisibilityHelper.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineEventVisibilityHelper.kt index 703a5cb9114..09c22aa7718 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineEventVisibilityHelper.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineEventVisibilityHelper.kt @@ -151,16 +151,20 @@ class TimelineEventVisibilityHelper @Inject constructor( rootThreadEventId: String?, isFromThreadTimeline: Boolean ): List { - val prevSub = timelineEvents - .subList(0, index + 1) - // Ensure to not take the REDACTION events into account - .filter { it.root.getClearType() != EventType.REDACTION } - return prevSub + val prevDisplayableEvents = timelineEvents.subList(0, index + 1) + .filter { + shouldShowEvent( + timelineEvent = it, + highlightedEventId = eventIdToHighlight, + isFromThreadTimeline = isFromThreadTimeline, + rootThreadEventId = rootThreadEventId) + } + return prevDisplayableEvents .reversed() .let { nextEventsUntil(it, 0, minSize, eventIdToHighlight, rootThreadEventId, isFromThreadTimeline, object : PredicateToStopSearch { override fun shouldStopSearch(oldEvent: Event, newEvent: Event): Boolean { - return oldEvent.isRedacted() && !newEvent.isRedacted() + return !newEvent.isRedacted() } }) }