mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 01:20:12 +00:00
Sort reactions on the timeline by count and then timestamp and show the date on the summary view (#1320)
* Sort timetamps on timeline and show the date on the summary view - Sort reaction aggregations on the timeline by count and then by most recent timestamp ascending(tagging new reactions on the end) - Show the timestamp on the summary view and sort descending(newest at the top) * Address comments. - Fix ID case. - Improve readability of components in body. - Improve the comments that describe the sorting.
This commit is contained in:
@@ -34,7 +34,7 @@ enum RoomTimelineItemFixtures {
|
||||
sender: .init(id: "", displayName: "Helena"),
|
||||
content: .init(body: "Let’s get lunch soon! New salad place opened up 🥗. When are y’all free? 🤗"),
|
||||
properties: RoomTimelineItemProperties(reactions: [
|
||||
AggregatedReaction(accountOwnerID: "me", key: "🙌", senders: ["me"])
|
||||
AggregatedReaction(accountOwnerID: "me", key: "🙌", senders: [ReactionSender(senderID: "me", timestamp: Date())])
|
||||
])),
|
||||
TextRoomTimelineItem(id: .init(timelineID: UUID().uuidString),
|
||||
timestamp: "10:11 AM",
|
||||
@@ -43,8 +43,14 @@ enum RoomTimelineItemFixtures {
|
||||
sender: .init(id: "", displayName: "Helena"),
|
||||
content: .init(body: "I can be around on Wednesday. How about some 🌮 instead? Like https://www.tortilla.co.uk/"),
|
||||
properties: RoomTimelineItemProperties(reactions: [
|
||||
AggregatedReaction(accountOwnerID: "me", key: "🙏", senders: ["helena"]),
|
||||
AggregatedReaction(accountOwnerID: "me", key: "🙌", senders: ["me", "helena", "jacob"])
|
||||
AggregatedReaction(accountOwnerID: "me", key: "🙏", senders: [ReactionSender(senderID: "helena", timestamp: Date())]),
|
||||
AggregatedReaction(accountOwnerID: "me",
|
||||
key: "🙌",
|
||||
senders: [
|
||||
ReactionSender(senderID: "me", timestamp: Date()),
|
||||
ReactionSender(senderID: "helena", timestamp: Date()),
|
||||
ReactionSender(senderID: "jacob", timestamp: Date())
|
||||
])
|
||||
])),
|
||||
SeparatorRoomTimelineItem(id: .init(timelineID: "Today"), text: "Today"),
|
||||
TextRoomTimelineItem(id: .init(timelineID: UUID().uuidString),
|
||||
|
||||
@@ -23,7 +23,15 @@ struct AggregatedReaction: Hashable {
|
||||
/// The reaction that was sent.
|
||||
let key: String
|
||||
/// The user ids of those who sent the reactions
|
||||
let senders: [String]
|
||||
let senders: [ReactionSender]
|
||||
}
|
||||
|
||||
/// Details of who sent the reaction
|
||||
struct ReactionSender: Hashable {
|
||||
/// The id of the user who sent the reaction
|
||||
let senderID: String
|
||||
/// The time that the reaction was received on the original homeserver
|
||||
let timestamp: Date
|
||||
}
|
||||
|
||||
extension AggregatedReaction {
|
||||
@@ -34,6 +42,6 @@ extension AggregatedReaction {
|
||||
|
||||
/// Whether to highlight the reaction, indicating that the current user sent this reaction.
|
||||
var isHighlighted: Bool {
|
||||
senders.contains(where: { $0 == accountOwnerID })
|
||||
senders.contains(where: { $0.senderID == accountOwnerID })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,13 +313,28 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
|
||||
|
||||
private func aggregateReactions(_ reactions: [Reaction]) -> [AggregatedReaction] {
|
||||
reactions.map { reaction in
|
||||
AggregatedReaction(accountOwnerID: userID, key: reaction.key, senders: reaction.senders.map(\.senderId))
|
||||
let senders = reaction.senders
|
||||
.map { senderData in
|
||||
ReactionSender(senderID: senderData.senderId, timestamp: Date(timeIntervalSince1970: TimeInterval(senderData.timestamp / 1000)))
|
||||
}
|
||||
.sorted { a, b in
|
||||
// Sort reactions within an aggregation by timestamp descending.
|
||||
// This puts the most recent at the top, useful in cases like the
|
||||
// reaction summary view.
|
||||
a.timestamp > b.timestamp
|
||||
}
|
||||
return AggregatedReaction(accountOwnerID: userID, key: reaction.key, senders: senders)
|
||||
}
|
||||
.sorted { a, b in
|
||||
// Sort by count and then by key for a consistence experience.
|
||||
// Otherwise emojis can switch around. We can replace
|
||||
// with timestamp as a secondary sort when it is available.
|
||||
(a.count, a.key) > (b.count, b.key)
|
||||
// Sort aggregated reactions by count and then timestamp ascending, using
|
||||
// the most recent reaction in the aggregation(hence index 0).
|
||||
// This appends new aggregations on the end of the reaction layout
|
||||
// and the deterministic sort avoids reactions jumping around if the reactions timeline
|
||||
// view reloads.
|
||||
if a.count == b.count {
|
||||
return a.senders[0].timestamp < b.senders[0].timestamp
|
||||
}
|
||||
return a.count > b.count
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user