mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 10:33:45 +00:00
Load member profiles through the timeline (#522)
This commit is contained in:
@@ -4012,7 +4012,7 @@
|
|||||||
repositoryURL = "https://github.com/matrix-org/matrix-rust-components-swift";
|
repositoryURL = "https://github.com/matrix-org/matrix-rust-components-swift";
|
||||||
requirement = {
|
requirement = {
|
||||||
kind = exactVersion;
|
kind = exactVersion;
|
||||||
version = "1.0.36-alpha";
|
version = "1.0.37-alpha";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
96495DD8554E2F39D3954354 /* XCRemoteSwiftPackageReference "posthog-ios" */ = {
|
96495DD8554E2F39D3954354 /* XCRemoteSwiftPackageReference "posthog-ios" */ = {
|
||||||
|
|||||||
@@ -86,8 +86,8 @@
|
|||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/matrix-org/matrix-rust-components-swift",
|
"location" : "https://github.com/matrix-org/matrix-rust-components-swift",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "f001ac9e4b72647a2b5a9f3f210d72384915164f",
|
"revision" : "79ead18b0db04f898d5ba9ce1a0b609a518f44ec",
|
||||||
"version" : "1.0.36-alpha"
|
"version" : "1.0.37-alpha"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,18 +40,10 @@ struct MockRoomProxy: RoomProxyProtocol {
|
|||||||
.failure(.failedRetrievingMemberDisplayName)
|
.failure(.failedRetrievingMemberDisplayName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func avatarURLForUserId(_ userId: String) -> URL? {
|
|
||||||
nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadAvatarURLForUserId(_ userId: String) async -> Result<URL?, RoomProxyError> {
|
func loadAvatarURLForUserId(_ userId: String) async -> Result<URL?, RoomProxyError> {
|
||||||
.failure(.failedRetrievingMemberAvatarURL)
|
.failure(.failedRetrievingMemberAvatarURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
func displayNameForUserId(_ userId: String) -> String? {
|
|
||||||
nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func startLiveEventListener() { }
|
func startLiveEventListener() { }
|
||||||
|
|
||||||
func addTimelineListener(listener: TimelineListener) -> Result<Void, RoomProxyError> {
|
func addTimelineListener(listener: TimelineListener) -> Result<Void, RoomProxyError> {
|
||||||
|
|||||||
@@ -31,9 +31,6 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
|
|
||||||
private var sendMessageBackgroundTask: BackgroundTaskProtocol?
|
private var sendMessageBackgroundTask: BackgroundTaskProtocol?
|
||||||
|
|
||||||
private var memberAvatars = [String: URL]()
|
|
||||||
private var memberDisplayNames = [String: String]()
|
|
||||||
|
|
||||||
private(set) var displayName: String?
|
private(set) var displayName: String?
|
||||||
|
|
||||||
private var timelineObservationToken: StoppableSpawn?
|
private var timelineObservationToken: StoppableSpawn?
|
||||||
@@ -109,10 +106,6 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return Asset.Images.encryptionTrusted.image
|
return Asset.Images.encryptionTrusted.image
|
||||||
}
|
}
|
||||||
|
|
||||||
func avatarURLForUserId(_ userId: String) -> URL? {
|
|
||||||
memberAvatars[userId]
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadAvatarURLForUserId(_ userId: String) async -> Result<URL?, RoomProxyError> {
|
func loadAvatarURLForUserId(_ userId: String) async -> Result<URL?, RoomProxyError> {
|
||||||
do {
|
do {
|
||||||
guard let urlString = try await Task.dispatch(on: lowPriorityDispatchQueue, {
|
guard let urlString = try await Task.dispatch(on: lowPriorityDispatchQueue, {
|
||||||
@@ -126,23 +119,17 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
return .failure(.failedRetrievingMemberAvatarURL)
|
return .failure(.failedRetrievingMemberAvatarURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
update(url: avatarURL, forUserId: userId)
|
|
||||||
return .success(avatarURL)
|
return .success(avatarURL)
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedRetrievingMemberAvatarURL)
|
return .failure(.failedRetrievingMemberAvatarURL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func displayNameForUserId(_ userId: String) -> String? {
|
|
||||||
memberDisplayNames[userId]
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadDisplayNameForUserId(_ userId: String) async -> Result<String?, RoomProxyError> {
|
func loadDisplayNameForUserId(_ userId: String) async -> Result<String?, RoomProxyError> {
|
||||||
do {
|
do {
|
||||||
let displayName = try await Task.dispatch(on: lowPriorityDispatchQueue) {
|
let displayName = try await Task.dispatch(on: lowPriorityDispatchQueue) {
|
||||||
try self.room.memberDisplayName(userId: userId)
|
try self.room.memberDisplayName(userId: userId)
|
||||||
}
|
}
|
||||||
update(displayName: displayName, forUserId: userId)
|
|
||||||
return .success(displayName)
|
return .success(displayName)
|
||||||
} catch {
|
} catch {
|
||||||
return .failure(.failedRetrievingMemberDisplayName)
|
return .failure(.failedRetrievingMemberDisplayName)
|
||||||
@@ -152,6 +139,9 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
func addTimelineListener(listener: TimelineListener) -> Result<Void, RoomProxyError> {
|
func addTimelineListener(listener: TimelineListener) -> Result<Void, RoomProxyError> {
|
||||||
if let token = slidingSyncRoom.subscribeAndAddTimelineListener(listener: listener, settings: nil) {
|
if let token = slidingSyncRoom.subscribeAndAddTimelineListener(listener: listener, settings: nil) {
|
||||||
timelineObservationToken = token
|
timelineObservationToken = token
|
||||||
|
Task {
|
||||||
|
await fetchMembers()
|
||||||
|
}
|
||||||
return .success(())
|
return .success(())
|
||||||
} else {
|
} else {
|
||||||
return .failure(.failedAddingTimelineListener)
|
return .failure(.failedAddingTimelineListener)
|
||||||
@@ -195,17 +185,17 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
let transactionId = genTransactionId()
|
let transactionId = genTransactionId()
|
||||||
|
|
||||||
return await Task.dispatch(on: userInitiatedDispatchQueue) {
|
return await Task.dispatch(on: userInitiatedDispatchQueue) {
|
||||||
do {
|
if let eventID {
|
||||||
if let eventID {
|
do {
|
||||||
try self.room.sendReply(msg: message, inReplyToEventId: eventID, txnId: transactionId)
|
try self.room.sendReply(msg: message, inReplyToEventId: eventID, txnId: transactionId)
|
||||||
} else {
|
} catch {
|
||||||
let messageContent = messageEventContentFromMarkdown(md: message)
|
return .failure(.failedSendingMessage)
|
||||||
try self.room.send(msg: messageContent, txnId: transactionId)
|
|
||||||
}
|
}
|
||||||
return .success(())
|
} else {
|
||||||
} catch {
|
let messageContent = messageEventContentFromMarkdown(md: message)
|
||||||
return .failure(.failedSendingMessage)
|
self.room.send(msg: messageContent, txnId: transactionId)
|
||||||
}
|
}
|
||||||
|
return .success(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,14 +270,14 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
private func update(url: URL?, forUserId userId: String) {
|
/// Force the timeline to load member details so it can populate sender profiles whenever we add a timeline listener
|
||||||
memberAvatars[userId] = url
|
/// This should become automatic on the RustSDK side at some point
|
||||||
|
private func fetchMembers() async {
|
||||||
|
await Task.dispatch(on: .global()) {
|
||||||
|
self.room.fetchMembers()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func update(displayName: String?, forUserId userId: String) {
|
|
||||||
memberDisplayNames[userId] = displayName
|
|
||||||
}
|
|
||||||
|
|
||||||
private func update(displayName: String) {
|
private func update(displayName: String) {
|
||||||
self.displayName = displayName
|
self.displayName = displayName
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,12 +51,8 @@ protocol RoomProxyProtocol {
|
|||||||
|
|
||||||
var avatarURL: URL? { get }
|
var avatarURL: URL? { get }
|
||||||
|
|
||||||
func avatarURLForUserId(_ userId: String) -> URL?
|
|
||||||
|
|
||||||
func loadAvatarURLForUserId(_ userId: String) async -> Result<URL?, RoomProxyError>
|
func loadAvatarURLForUserId(_ userId: String) async -> Result<URL?, RoomProxyError>
|
||||||
|
|
||||||
func displayNameForUserId(_ userId: String) -> String?
|
|
||||||
|
|
||||||
func loadDisplayNameForUserId(_ userId: String) async -> Result<String?, RoomProxyError>
|
func loadDisplayNameForUserId(_ userId: String) async -> Result<String?, RoomProxyError>
|
||||||
|
|
||||||
func addTimelineListener(listener: TimelineListener) -> Result<Void, RoomProxyError>
|
func addTimelineListener(listener: TimelineListener) -> Result<Void, RoomProxyError>
|
||||||
|
|||||||
@@ -97,15 +97,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func processItemAppearance(_ itemID: String) async {
|
func processItemAppearance(_ itemID: String) async { }
|
||||||
guard let timelineItem = timelineItems.first(where: { $0.id == itemID }) else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if let item = timelineItem as? EventBasedTimelineItemProtocol {
|
|
||||||
await loadUserDisplayNameForTimelineItem(item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func processItemDisappearance(_ itemID: String) { }
|
func processItemDisappearance(_ itemID: String) { }
|
||||||
|
|
||||||
@@ -435,26 +427,4 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#warning("This is here because sender profiles aren't working properly. Remove it entirely later")
|
|
||||||
private func loadUserDisplayNameForTimelineItem(_ timelineItem: EventBasedTimelineItemProtocol) async {
|
|
||||||
if timelineItem.shouldShowSenderDetails == false || timelineItem.sender.displayName != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch await roomProxy.loadDisplayNameForUserId(timelineItem.sender.id) {
|
|
||||||
case .success(let displayName):
|
|
||||||
guard let displayName,
|
|
||||||
let index = timelineItems.firstIndex(where: { $0.id == timelineItem.id }),
|
|
||||||
var item = timelineItems[index] as? EventBasedTimelineItemProtocol else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
item.sender.displayName = displayName
|
|
||||||
timelineItems[index] = item
|
|
||||||
callbacks.send(.updatedTimelineItem(timelineItem.id))
|
|
||||||
case .failure:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,9 +106,17 @@ struct EventTimelineItemProxy: CustomDebugStringConvertible {
|
|||||||
|
|
||||||
var sender: TimelineItemSender {
|
var sender: TimelineItemSender {
|
||||||
let profile = item.senderProfile()
|
let profile = item.senderProfile()
|
||||||
return .init(id: item.sender(),
|
|
||||||
displayName: profile.displayName,
|
switch profile {
|
||||||
avatarURL: profile.avatarUrl.flatMap(URL.init(string:)))
|
case let .ready(displayName, _, avatarUrl):
|
||||||
|
return .init(id: item.sender(),
|
||||||
|
displayName: displayName,
|
||||||
|
avatarURL: avatarUrl.flatMap(URL.init(string:)))
|
||||||
|
default:
|
||||||
|
return .init(id: item.sender(),
|
||||||
|
displayName: nil,
|
||||||
|
avatarURL: nil)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var reactions: [Reaction] {
|
var reactions: [Reaction] {
|
||||||
|
|||||||
+1
-1
@@ -40,7 +40,7 @@ include:
|
|||||||
packages:
|
packages:
|
||||||
MatrixRustSDK:
|
MatrixRustSDK:
|
||||||
url: https://github.com/matrix-org/matrix-rust-components-swift
|
url: https://github.com/matrix-org/matrix-rust-components-swift
|
||||||
exactVersion: 1.0.36-alpha
|
exactVersion: 1.0.37-alpha
|
||||||
# path: ../matrix-rust-sdk
|
# path: ../matrix-rust-sdk
|
||||||
DesignKit:
|
DesignKit:
|
||||||
path: DesignKit
|
path: DesignKit
|
||||||
|
|||||||
Reference in New Issue
Block a user