Low effort fix for timeline date separator glitches

This commit is contained in:
Stefan Ceriu
2023-05-08 18:18:34 +03:00
committed by Stefan Ceriu
parent faefb00626
commit 0d27ed1bbd
6 changed files with 19 additions and 13 deletions
@@ -44,8 +44,8 @@ struct CollapsibleRoomTimelineView: View {
struct CollapsibleRoomTimelineView_Previews: PreviewProvider {
static var previews: some View {
let item = CollapsibleTimelineItem(items: [SeparatorRoomTimelineItem(text: "This is a separator"),
SeparatorRoomTimelineItem(text: "This is another separator")])
let item = CollapsibleTimelineItem(items: [SeparatorRoomTimelineItem(id: "First separator", text: "This is a separator"),
SeparatorRoomTimelineItem(id: "Second separator", text: "This is another separator")])
CollapsibleRoomTimelineView(timelineItem: item)
}
}
@@ -41,7 +41,7 @@ struct ReadMarkerRoomTimelineView_Previews: PreviewProvider {
static let item = ReadMarkerRoomTimelineItem()
static var previews: some View {
VStack(alignment: .leading, spacing: 0) {
RoomTimelineViewProvider.separator(.init(text: "Today"), .single)
RoomTimelineViewProvider.separator(.init(id: "Separator", text: "Today"), .single)
RoomTimelineViewProvider.text(.init(id: "",
timestamp: "",
isOutgoing: true,
@@ -51,7 +51,7 @@ struct ReadMarkerRoomTimelineView_Previews: PreviewProvider {
ReadMarkerRoomTimelineView(timelineItem: item)
RoomTimelineViewProvider.separator(.init(text: "Today"), .single)
RoomTimelineViewProvider.separator(.init(id: "Separator", text: "Today"), .single)
RoomTimelineViewProvider.text(.init(id: "",
timestamp: "",
isOutgoing: false,
@@ -31,7 +31,7 @@ struct SeparatorRoomTimelineView: View {
struct SeparatorRoomTimelineView_Previews: PreviewProvider {
static var previews: some View {
let item = SeparatorRoomTimelineItem(text: "This is a separator")
let item = SeparatorRoomTimelineItem(id: "Separator", text: "This is a separator")
SeparatorRoomTimelineView(timelineItem: item)
}
}
@@ -19,7 +19,7 @@ import Foundation
enum RoomTimelineItemFixtures {
/// The default timeline items used in Xcode previews etc.
static var `default`: [RoomTimelineItemProtocol] = [
SeparatorRoomTimelineItem(text: "Yesterday"),
SeparatorRoomTimelineItem(id: "Yesterday", text: "Yesterday"),
TextRoomTimelineItem(id: UUID().uuidString,
timestamp: "10:10 AM",
isOutgoing: false,
@@ -46,7 +46,7 @@ enum RoomTimelineItemFixtures {
AggregatedReaction(key: "🙏", count: 1, isHighlighted: false),
AggregatedReaction(key: "🙌", count: 2, isHighlighted: true)
])),
SeparatorRoomTimelineItem(text: "Today"),
SeparatorRoomTimelineItem(id: "Today", text: "Today"),
TextRoomTimelineItem(id: UUID().uuidString,
timestamp: "5 PM",
isOutgoing: false,
@@ -231,8 +231,13 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
for (index, collapsibleChunk) in collapsibleChunks.enumerated() {
let isLastItem = index == collapsibleChunks.indices.last
// Try building a stable identifier for items that don't have one
// We need to avoid duplicates otherwise the diffable datasource will crash
let reversedIndex = collapsibleChunks.count - index
let items = collapsibleChunk.compactMap { itemProxy in
let timelineItem = buildTimelineItem(for: itemProxy)
let timelineItem = buildTimelineItem(for: itemProxy, chunkIndex: reversedIndex)
if timelineItem is PaginationIndicatorRoomTimelineItem {
isBackPaginating = true
@@ -267,17 +272,19 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
callbacks.send(.isBackPaginating(isBackPaginating))
}
private func buildTimelineItem(for itemProxy: TimelineItemProxy) -> RoomTimelineItemProtocol? {
private func buildTimelineItem(for itemProxy: TimelineItemProxy, chunkIndex: Int) -> RoomTimelineItemProtocol? {
switch itemProxy {
case .event(let eventTimelineItem):
return timelineItemFactory.buildTimelineItem(for: eventTimelineItem)
case .virtual(let virtualItem):
switch virtualItem {
case .dayDivider(let timestamp):
// These components will be replaced by a timestamp in upcoming releases
let date = Date(timeIntervalSince1970: TimeInterval(timestamp / 1000))
let dateString = date.formatted(date: .complete, time: .omitted)
return SeparatorRoomTimelineItem(text: dateString)
// Separators without stable identifiers cause UI glitches
let identifier = "\(chunkIndex)-\(dateString)"
return SeparatorRoomTimelineItem(id: identifier, text: dateString)
case .readMarker:
return ReadMarkerRoomTimelineItem()
case .loadingIndicator:
@@ -17,7 +17,6 @@
import Foundation
struct SeparatorRoomTimelineItem: DecorationTimelineItemProtocol, Identifiable, Hashable {
#warning("This should really be a stable identifier, ideally coming from the SDK, but unfortunately we receive duplicates for it at the moment, crashing our timeline data source")
let id: String = UUID().uuidString
let id: String
let text: String
}