diff --git a/ElementX/Sources/Screens/RoomScreen/View/Timeline/CollapsibleRoomTimelineView.swift b/ElementX/Sources/Screens/RoomScreen/View/Timeline/CollapsibleRoomTimelineView.swift index b3d7152d4..89a9539fb 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Timeline/CollapsibleRoomTimelineView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Timeline/CollapsibleRoomTimelineView.swift @@ -53,7 +53,7 @@ struct CollapsibleRoomTimelineView_Previews: PreviewProvider { private struct CollapsibleRoomTimelineItemDisclosureGroupStyle: DisclosureGroupStyle { func makeBody(configuration: Configuration) -> some View { - VStack { + VStack(spacing: 0.0) { HStack(alignment: .center) { configuration.label Text(Image(systemName: "chevron.forward")) @@ -63,8 +63,10 @@ private struct CollapsibleRoomTimelineItemDisclosureGroupStyle: DisclosureGroupS .frame(maxWidth: .infinity) .font(.element.footnote) .foregroundColor(.element.secondaryContent) - .padding(.horizontal, 36) - .padding(.vertical, 8) + .padding(.horizontal, 36.0) + .padding(.top, 20.0) + .padding(.bottom, 12.0) + .onTapGesture { configuration.isExpanded.toggle() } diff --git a/ElementX/Sources/Screens/RoomScreen/View/Timeline/SeparatorRoomTimelineView.swift b/ElementX/Sources/Screens/RoomScreen/View/Timeline/SeparatorRoomTimelineView.swift index 3a205d80d..45919273b 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Timeline/SeparatorRoomTimelineView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Timeline/SeparatorRoomTimelineView.swift @@ -23,9 +23,9 @@ struct SeparatorRoomTimelineView: View { Text(timelineItem.text) .font(.element.footnote) .foregroundColor(.element.secondaryContent) - .padding(.top, 12) - .padding(.bottom, 8) .frame(maxWidth: .infinity) + .padding(.horizontal, 36.0) + .padding(.vertical, 8.0) } } diff --git a/ElementX/Sources/Screens/RoomScreen/View/Timeline/StateRoomTimelineView.swift b/ElementX/Sources/Screens/RoomScreen/View/Timeline/StateRoomTimelineView.swift index aa7f61591..492be7286 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/Timeline/StateRoomTimelineView.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/Timeline/StateRoomTimelineView.swift @@ -25,8 +25,8 @@ struct StateRoomTimelineView: View { .multilineTextAlignment(.center) .foregroundColor(.element.secondaryContent) .frame(maxWidth: .infinity, alignment: .center) - .padding(.horizontal, 36) - .padding(.vertical, 8) + .padding(.horizontal, 36.0) + .padding(.vertical, 8.0) } } diff --git a/ElementX/Sources/Services/Timeline/TimelineController/RoomTimelineController.swift b/ElementX/Sources/Services/Timeline/TimelineController/RoomTimelineController.swift index 43ba88b57..056c6bdd9 100644 --- a/ElementX/Sources/Services/Timeline/TimelineController/RoomTimelineController.swift +++ b/ElementX/Sources/Services/Timeline/TimelineController/RoomTimelineController.swift @@ -235,24 +235,37 @@ class RoomTimelineController: RoomTimelineControllerProtocol { var canBackPaginate = true var isBackPaginating = false - var createdIdentifiers = [String: Bool]() - let collapsibleChunks = timelineProvider.itemsPublisher.value.groupBy { isItemCollapsible($0) } - for (index, itemGroup) in collapsibleChunks.enumerated() { - if itemGroup.count == 1, let itemProxy = itemGroup.first { - let isLastItem = index == collapsibleChunks.indices.last - if let item = buildTimelineItemFor(itemProxy: itemProxy, isLastItem: isLastItem, createdIdentifiers: &createdIdentifiers, isBackPaginating: &isBackPaginating, canBackPaginate: &canBackPaginate) { - newTimelineItems.append(item) - } - } else { - let items = itemGroup.compactMap { itemProxy in - buildTimelineItemFor(itemProxy: itemProxy, isLastItem: false, createdIdentifiers: &createdIdentifiers, isBackPaginating: &isBackPaginating, canBackPaginate: &canBackPaginate) + for (index, collapsibleChunk) in collapsibleChunks.enumerated() { + let isLastItem = index == collapsibleChunks.indices.last + + let items = collapsibleChunk.compactMap { itemProxy in + let timelineItem = buildTimelineItemFor(itemProxy: itemProxy) + + if timelineItem is PaginationIndicatorRoomTimelineItem { + isBackPaginating = true + } else if timelineItem is TimelineStartRoomTimelineItem { + canBackPaginate = false } - if !items.isEmpty { - newTimelineItems.append(CollapsibleTimelineItem(items: items)) + return timelineItem + } + + if items.isEmpty { + continue + } + + if items.count == 1, let timelineItem = items.first { + // Don't show the read marker if it's the last item in the timeline + // https://github.com/matrix-org/matrix-rust-sdk/issues/1546 + guard !(timelineItem is ReadMarkerRoomTimelineItem && isLastItem) else { + continue } + + newTimelineItems.append(timelineItem) + } else { + newTimelineItems.append(CollapsibleTimelineItem(items: items)) } } @@ -263,22 +276,10 @@ class RoomTimelineController: RoomTimelineControllerProtocol { callbacks.send(.isBackPaginating(isBackPaginating)) } - private func buildTimelineItemFor(itemProxy: TimelineItemProxy, - isLastItem: Bool, - createdIdentifiers: inout [String: Bool], - isBackPaginating: inout Bool, - canBackPaginate: inout Bool) -> RoomTimelineItemProtocol? { + private func buildTimelineItemFor(itemProxy: TimelineItemProxy) -> RoomTimelineItemProtocol? { switch itemProxy { case .event(let eventItemProxy): - if let timelineItem = timelineItemFactory.buildTimelineItemFor(eventItemProxy: eventItemProxy) { - #warning("This works around duplicated items coming out of the SDK, remove once fixed") - if createdIdentifiers[timelineItem.id] == nil { - createdIdentifiers[timelineItem.id] = true - return timelineItem - } else { - MXLog.error("Found duplicated timeline item, ignoring") - } - } + return timelineItemFactory.buildTimelineItemFor(eventItemProxy: eventItemProxy) case .virtual(let virtualItem): switch virtualItem { case .dayDivider(let timestamp): @@ -287,15 +288,10 @@ class RoomTimelineController: RoomTimelineControllerProtocol { let dateString = date.formatted(date: .complete, time: .omitted) return SeparatorRoomTimelineItem(text: dateString) case .readMarker: - // Don't show the read marker if it's the last item in the timeline - if !isLastItem { - return ReadMarkerRoomTimelineItem() - } + return ReadMarkerRoomTimelineItem() case .loadingIndicator: - isBackPaginating = true return PaginationIndicatorRoomTimelineItem() case .timelineStart: - canBackPaginate = false return TimelineStartRoomTimelineItem(name: roomProxy.displayName ?? roomProxy.name) } case .unknown: diff --git a/changelog.d/631.bugfix b/changelog.d/631.bugfix new file mode 100644 index 000000000..8df8c8d46 --- /dev/null +++ b/changelog.d/631.bugfix @@ -0,0 +1 @@ +Prevent creating collapsible groups for one single event. Increase their padding and touch area. \ No newline at end of file