Adopt the new latest event API. (#4779)

This commit is contained in:
Doug
2025-11-25 11:52:48 +00:00
committed by GitHub
parent 08514917fe
commit f2607affd2
23 changed files with 321 additions and 139 deletions
@@ -1097,7 +1097,7 @@ class ClientProxy: ClientProxyProtocol {
MXLog.info("Pinning current identity for user: \(userID)")
do {
guard let userIdentity = try await client.encryption().userIdentity(userId: userID) else {
guard let userIdentity = try await client.encryption().userIdentity(userId: userID, fallbackToServer: true) else {
MXLog.error("Failed retrieving identity for user: \(userID)")
return .failure(.failedRetrievingUserIdentity)
}
@@ -1113,7 +1113,7 @@ class ClientProxy: ClientProxyProtocol {
MXLog.info("Withdrawing current identity verification for user: \(userID)")
do {
guard let userIdentity = try await client.encryption().userIdentity(userId: userID) else {
guard let userIdentity = try await client.encryption().userIdentity(userId: userID, fallbackToServer: true) else {
MXLog.error("Failed retrieving identity for user: \(userID)")
return .failure(.failedRetrievingUserIdentity)
}
@@ -1133,9 +1133,9 @@ class ClientProxy: ClientProxyProtocol {
}
}
func userIdentity(for userID: String) async -> Result<UserIdentityProxyProtocol?, ClientProxyError> {
func userIdentity(for userID: String, fallBackToServer: Bool) async -> Result<UserIdentityProxyProtocol?, ClientProxyError> {
do {
return try await .success(client.encryption().userIdentity(userId: userID).map(UserIdentityProxy.init))
return try await .success(client.encryption().userIdentity(userId: userID, fallbackToServer: fallBackToServer).map(UserIdentityProxy.init))
} catch {
MXLog.error("Failed retrieving user identity: \(error)")
return .failure(.sdkError(error))
@@ -236,7 +236,7 @@ protocol ClientProxyProtocol: AnyObject {
func withdrawUserIdentityVerification(_ userID: String) async -> Result<Void, ClientProxyError>
func resetIdentity() async -> Result<IdentityResetHandle?, ClientProxyError>
func userIdentity(for userID: String) async -> Result<UserIdentityProxyProtocol?, ClientProxyError>
func userIdentity(for userID: String, fallBackToServer: Bool) async -> Result<UserIdentityProxyProtocol?, ClientProxyError>
// MARK: - Moderation & Safety
@@ -16,15 +16,19 @@ struct RoomEventStringBuilder {
let shouldPrefixSenderName: Bool
func buildAttributedString(for eventItemProxy: EventTimelineItemProxy) -> AttributedString? {
let sender = eventItemProxy.sender
let isOutgoing = eventItemProxy.isOwn
buildAttributedString(for: eventItemProxy.content,
sender: eventItemProxy.sender,
isOutgoing: eventItemProxy.isOwn)
}
func buildAttributedString(for content: TimelineItemContent, sender: TimelineItemSender, isOutgoing: Bool) -> AttributedString? {
let displayName = if shouldDisambiguateDisplayNames {
sender.disambiguatedDisplayName ?? sender.id
} else {
sender.displayName ?? sender.id
}
switch eventItemProxy.content {
switch content {
case .msgLike(let messageLikeContent):
switch messageLikeContent.kind {
case .message(let messageContent):
@@ -230,10 +230,10 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
return updatedItems
}
private func fetchRoomDetails(from room: Room) -> (roomInfo: RoomInfo?, latestEvent: EventTimelineItem?) {
private func fetchRoomDetails(from room: Room) -> (roomInfo: RoomInfo?, latestEvent: LatestEventValue?) {
class FetchResult {
var roomInfo: RoomInfo?
var latestEvent: EventTimelineItem?
var latestEvent: LatestEventValue?
}
let semaphore = DispatchSemaphore(value: 0)
@@ -241,7 +241,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
Task {
do {
result.latestEvent = await room.latestEvent()
result.latestEvent = await room.newLatestEvent()
result.roomInfo = try await room.roomInfo()
} catch {
MXLog.error("Failed fetching room info with error: \(error)")
@@ -263,9 +263,18 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
var lastMessageDate: Date?
if let latestRoomMessage = roomDetails.latestEvent {
let lastMessage = EventTimelineItemProxy(item: latestRoomMessage, uniqueID: .init("0"))
lastMessageDate = lastMessage.timestamp
attributedLastMessage = eventStringBuilder.buildAttributedString(for: lastMessage)
switch latestRoomMessage {
case .local(let timestamp, let senderID, let profile, let content, _):
let sender = TimelineItemSender(senderID: senderID, senderProfile: profile)
attributedLastMessage = eventStringBuilder.buildAttributedString(for: content, sender: sender, isOutgoing: true)
lastMessageDate = Date(timeIntervalSince1970: TimeInterval(timestamp / 1000))
case .remote(let timestamp, let senderID, let isOwn, let profile, let content):
let sender = TimelineItemSender(senderID: senderID, senderProfile: profile)
attributedLastMessage = eventStringBuilder.buildAttributedString(for: content, sender: sender, isOutgoing: isOwn)
lastMessageDate = Date(timeIntervalSince1970: TimeInterval(timestamp / 1000))
case .none:
break
}
}
var inviterProxy: RoomMemberProxyProtocol?
@@ -108,22 +108,7 @@ class EventTimelineItemProxy {
lazy var isEditable = item.isEditable
lazy var sender: TimelineItemSender = {
let profile = item.senderProfile
switch profile {
case let .ready(displayName, isDisplayNameAmbiguous, avatarUrl):
return .init(id: item.sender,
displayName: displayName,
isDisplayNameAmbiguous: isDisplayNameAmbiguous,
avatarURL: avatarUrl.flatMap(URL.init(string:)))
default:
return .init(id: item.sender,
displayName: nil,
isDisplayNameAmbiguous: false,
avatarURL: nil)
}
}()
lazy var sender = TimelineItemSender(senderID: item.sender, senderProfile: item.senderProfile)
lazy var timestamp = Date(timeIntervalSince1970: TimeInterval(item.timestamp / 1000))
@@ -6,7 +6,8 @@
// Please see LICENSE files in the repository root for full details.
//
import UIKit
import MatrixRustSDK
import SwiftUI
struct TimelineItemSender: Identifiable, Hashable {
static let test = TimelineItemSender(id: "@test.matrix.org")
@@ -22,6 +23,21 @@ struct TimelineItemSender: Identifiable, Hashable {
self.isDisplayNameAmbiguous = isDisplayNameAmbiguous
self.avatarURL = avatarURL
}
init(senderID: String, senderProfile: ProfileDetails) {
switch senderProfile {
case let .ready(displayName, isDisplayNameAmbiguous, avatarUrl):
self.init(id: senderID,
displayName: displayName,
isDisplayNameAmbiguous: isDisplayNameAmbiguous,
avatarURL: avatarUrl.flatMap(URL.init(string:)))
default:
self.init(id: senderID,
displayName: nil,
isDisplayNameAmbiguous: false,
avatarURL: nil)
}
}
var disambiguatedDisplayName: String? {
guard let displayName else {
@@ -678,7 +678,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
case .pending:
return .loading
case .ready(let content, let senderID, let senderProfile, _, _):
let sender = buildTimelineItemSender(senderID: senderID, senderProfile: senderProfile)
let sender = TimelineItemSender(senderID: senderID, senderProfile: senderProfile)
let latestEventContent: TimelineEventContent = switch content {
case .msgLike(let messageLikeContent):
@@ -814,7 +814,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
case .pending:
return .init(details: .loading(eventID: details.eventId()), isThreaded: isThreaded)
case let .ready(timelineItem, senderID, senderProfile, _, _):
let sender = buildTimelineItemSender(senderID: senderID, senderProfile: senderProfile)
let sender = TimelineItemSender(senderID: senderID, senderProfile: senderProfile)
let replyContent: TimelineEventContent
@@ -850,21 +850,6 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
// MARK: - Helpers
private func buildTimelineItemSender(senderID: String, senderProfile: ProfileDetails?) -> TimelineItemSender {
switch senderProfile {
case let .ready(displayName, isDisplayNameAmbiguous, avatarUrl):
return TimelineItemSender(id: senderID,
displayName: displayName,
isDisplayNameAmbiguous: isDisplayNameAmbiguous,
avatarURL: avatarUrl.flatMap(URL.init(string:)))
default:
return TimelineItemSender(id: senderID,
displayName: nil,
isDisplayNameAmbiguous: false,
avatarURL: nil)
}
}
private func buildMessageTimelineItemContent(messageType: MessageType?, senderID: String, senderDisplayName: String?) -> EventBasedMessageTimelineItemContentType {
switch messageType {
case .audio(let content):