From dc4fa6aead3c8db90b7aaabb531bf4287f1c56b1 Mon Sep 17 00:00:00 2001 From: Mauro Romito Date: Thu, 6 Feb 2025 14:24:27 +0100 Subject: [PATCH] async load room preview --- .../Mocks/Generated/GeneratedMocks.swift | 62 +++++++++++++++++-- .../Sources/Mocks/InvitedRoomProxyMock.swift | 4 +- .../Sources/Mocks/KnockedRoomProxyMock.swift | 2 +- .../HomeScreen/HomeScreenViewModel.swift | 9 ++- .../JoinRoomScreenViewModel.swift | 8 +-- .../Sources/Services/Client/ClientProxy.swift | 11 ++-- .../Services/Room/BannedRoomProxy.swift | 5 +- .../Services/Room/InvitedRoomProxy.swift | 34 +++++++--- .../Services/Room/KnockedRoomProxy.swift | 26 +++++--- .../Services/Room/RoomProxyProtocol.swift | 6 +- 10 files changed, 123 insertions(+), 44 deletions(-) diff --git a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift index 8ebd03458c..ad53400fca 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -5952,12 +5952,48 @@ class ElementCallWidgetDriverMock: ElementCallWidgetDriverProtocol, @unchecked S } } class InvitedRoomProxyMock: InvitedRoomProxyProtocol, @unchecked Sendable { + var infoCallsCount = 0 + var infoCalled: Bool { + return infoCallsCount > 0 + } + var info: BaseRoomInfoProxyProtocol { - get { return underlyingInfo } - set(value) { underlyingInfo = value } + get async throws { + if let error = infoThrowableError { + throw error + } + infoCallsCount += 1 + if let infoClosure = infoClosure { + return try await infoClosure() + } else { + return underlyingInfo + } + } } var underlyingInfo: BaseRoomInfoProxyProtocol! - var inviter: RoomMemberProxyProtocol? + var infoThrowableError: Error? + var infoClosure: (() async throws -> BaseRoomInfoProxyProtocol)? + var inviterCallsCount = 0 + var inviterCalled: Bool { + return inviterCallsCount > 0 + } + + var inviter: RoomMemberProxyProtocol? { + get async throws { + if let error = inviterThrowableError { + throw error + } + inviterCallsCount += 1 + if let inviterClosure = inviterClosure { + return try await inviterClosure() + } else { + return underlyingInviter + } + } + } + var underlyingInviter: RoomMemberProxyProtocol? + var inviterThrowableError: Error? + var inviterClosure: (() async throws -> RoomMemberProxyProtocol?)? var id: String { get { return underlyingId } set(value) { underlyingId = value } @@ -10528,11 +10564,27 @@ class KnockRequestProxyMock: KnockRequestProxyProtocol, @unchecked Sendable { } } class KnockedRoomProxyMock: KnockedRoomProxyProtocol, @unchecked Sendable { + var infoCallsCount = 0 + var infoCalled: Bool { + return infoCallsCount > 0 + } + var info: BaseRoomInfoProxyProtocol { - get { return underlyingInfo } - set(value) { underlyingInfo = value } + get async throws { + if let error = infoThrowableError { + throw error + } + infoCallsCount += 1 + if let infoClosure = infoClosure { + return try await infoClosure() + } else { + return underlyingInfo + } + } } var underlyingInfo: BaseRoomInfoProxyProtocol! + var infoThrowableError: Error? + var infoClosure: (() async throws -> BaseRoomInfoProxyProtocol)? var id: String { get { return underlyingId } set(value) { underlyingId = value } diff --git a/ElementX/Sources/Mocks/InvitedRoomProxyMock.swift b/ElementX/Sources/Mocks/InvitedRoomProxyMock.swift index 8c4a248e75..a40af2a45c 100644 --- a/ElementX/Sources/Mocks/InvitedRoomProxyMock.swift +++ b/ElementX/Sources/Mocks/InvitedRoomProxyMock.swift @@ -23,8 +23,8 @@ extension InvitedRoomProxyMock { convenience init(_ configuration: InvitedRoomProxyMockConfiguration) { self.init() id = configuration.id - inviter = configuration.inviter - info = RoomInfoProxy(roomInfo: .init(configuration)) + underlyingInviter = configuration.inviter + underlyingInfo = RoomInfoProxy(roomInfo: .init(configuration)) } } diff --git a/ElementX/Sources/Mocks/KnockedRoomProxyMock.swift b/ElementX/Sources/Mocks/KnockedRoomProxyMock.swift index 241a446cd7..729b16fb73 100644 --- a/ElementX/Sources/Mocks/KnockedRoomProxyMock.swift +++ b/ElementX/Sources/Mocks/KnockedRoomProxyMock.swift @@ -22,7 +22,7 @@ extension KnockedRoomProxyMock { convenience init(_ configuration: KnockedRoomProxyMockConfiguration) { self.init() id = configuration.id - info = RoomInfoProxy(roomInfo: .init(configuration)) + underlyingInfo = RoomInfoProxy(roomInfo: .init(configuration)) } } diff --git a/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift b/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift index 6bcbd210e4..e44d75fa4b 100644 --- a/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift +++ b/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift @@ -410,9 +410,12 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol switch await userSession.clientProxy.joinRoom(roomID, via: []) { case .success: actionsSubject.send(.presentRoom(roomIdentifier: roomID)) - analyticsService.trackJoinedRoom(isDM: roomProxy.info.isDirect, - isSpace: roomProxy.info.isSpace, - activeMemberCount: UInt(roomProxy.info.activeMembersCount)) + Task { + let info = try await roomProxy.info + analyticsService.trackJoinedRoom(isDM: info.isDirect, + isSpace: info.isSpace, + activeMemberCount: UInt(info.activeMembersCount)) + } case .failure: displayError() } diff --git a/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenViewModel.swift b/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenViewModel.swift index 3ecd822ff9..e5c794557a 100644 --- a/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenViewModel.swift @@ -98,7 +98,6 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo } hideLoadingIndicator() - await updateRoomDetails() } @@ -121,11 +120,12 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo switch room { case .joined(let joinedRoomProxy): roomInfo = joinedRoomProxy.infoPublisher.value + roomInfo = joinedRoomProxy.infoPublisher.value case .invited(let invitedRoomProxy): - inviter = invitedRoomProxy.inviter.map(RoomInviterDetails.init) - roomInfo = invitedRoomProxy.info + inviter = try? await invitedRoomProxy.inviter.map(RoomInviterDetails.init) + roomInfo = try? await invitedRoomProxy.info case .knocked(let knockedRoomProxy): - roomInfo = knockedRoomProxy.info + roomInfo = try? await knockedRoomProxy.info if let roomSummaryProvider = clientProxy.roomSummaryProvider { membershipStateChangeCancellable = roomSummaryProvider.roomListPublisher .compactMap { summaries -> Void? in diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index 8efdfefd12..364441d5cf 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -916,14 +916,12 @@ class ClientProxy: ClientProxyProtocol { switch roomListItem.membership() { case .invited: - return try await .invited(InvitedRoomProxy(roomListItem: roomListItem, - roomPreview: roomListItem.previewRoom(via: []), - ownUserID: userID)) + return .invited(InvitedRoomProxy(roomListItem: roomListItem, + ownUserID: userID)) case .knocked: if appSettings.knockingEnabled { - return try await .knocked(KnockedRoomProxy(roomListItem: roomListItem, - roomPreview: roomListItem.previewRoom(via: []), - ownUserID: userID)) + return .knocked(KnockedRoomProxy(roomListItem: roomListItem, + ownUserID: userID)) } return nil case .joined: @@ -940,7 +938,6 @@ class ClientProxy: ClientProxyProtocol { return .left case .banned: return try await .banned(BannedRoomProxy(roomListItem: roomListItem, - roomPreview: roomListItem.previewRoom(via: []), ownUserID: userID)) } } catch { diff --git a/ElementX/Sources/Services/Room/BannedRoomProxy.swift b/ElementX/Sources/Services/Room/BannedRoomProxy.swift index b928b409b2..b285535902 100644 --- a/ElementX/Sources/Services/Room/BannedRoomProxy.swift +++ b/ElementX/Sources/Services/Room/BannedRoomProxy.swift @@ -19,10 +19,9 @@ class BannedRoomProxy: BannedRoomProxyProtocol { lazy var id = info.id init(roomListItem: RoomListItemProtocol, - roomPreview: RoomPreviewProtocol, - ownUserID: String) throws { + ownUserID: String) async throws { self.roomListItem = roomListItem - self.roomPreview = roomPreview + roomPreview = try await roomListItem.previewRoom(via: []) self.ownUserID = ownUserID info = try RoomPreviewInfoProxy(roomPreviewInfo: roomPreview.info()) } diff --git a/ElementX/Sources/Services/Room/InvitedRoomProxy.swift b/ElementX/Sources/Services/Room/InvitedRoomProxy.swift index add21b5f39..324615ba36 100644 --- a/ElementX/Sources/Services/Room/InvitedRoomProxy.swift +++ b/ElementX/Sources/Services/Room/InvitedRoomProxy.swift @@ -11,23 +11,39 @@ import UIKit class InvitedRoomProxy: InvitedRoomProxyProtocol { private let roomListItem: RoomListItemProtocol - private let roomPreview: RoomPreviewProtocol - let info: BaseRoomInfoProxyProtocol + private var roomPreview: RoomPreviewProtocol { + get async throws { + try await roomPreviewTask.value + } + } + + private var roomPreviewTask: Task + + var info: BaseRoomInfoProxyProtocol { + get async throws { + try await RoomPreviewInfoProxy(roomPreviewInfo: roomPreview.info()) + } + } + + var inviter: RoomMemberProxyProtocol? { + get async throws { + try await roomPreview.inviter().map(RoomMemberProxy.init) + } + } + let ownUserID: String - let inviter: RoomMemberProxyProtocol? // A room identifier is constant and lazy stops it from being fetched // multiple times over FFI - lazy var id: String = info.id + lazy var id: String = roomListItem.id() init(roomListItem: RoomListItemProtocol, - roomPreview: RoomPreviewProtocol, - ownUserID: String) async throws { + ownUserID: String) { self.roomListItem = roomListItem - self.roomPreview = roomPreview self.ownUserID = ownUserID - info = try RoomPreviewInfoProxy(roomPreviewInfo: roomPreview.info()) - inviter = await roomPreview.inviter().map(RoomMemberProxy.init) + roomPreviewTask = Task { + try await roomListItem.previewRoom(via: []) + } } func rejectInvitation() async -> Result { diff --git a/ElementX/Sources/Services/Room/KnockedRoomProxy.swift b/ElementX/Sources/Services/Room/KnockedRoomProxy.swift index 9067d20e4b..b774d08f3f 100644 --- a/ElementX/Sources/Services/Room/KnockedRoomProxy.swift +++ b/ElementX/Sources/Services/Room/KnockedRoomProxy.swift @@ -10,21 +10,33 @@ import MatrixRustSDK class KnockedRoomProxy: KnockedRoomProxyProtocol { private let roomListItem: RoomListItemProtocol - private let roomPreview: RoomPreviewProtocol - let info: BaseRoomInfoProxyProtocol + private var roomPreview: RoomPreviewProtocol { + get async throws { + try await roomPreviewTask.value + } + } + + private var roomPreviewTask: Task + + var info: BaseRoomInfoProxyProtocol { + get async throws { + try await RoomPreviewInfoProxy(roomPreviewInfo: roomPreview.info()) + } + } + let ownUserID: String // A room identifier is constant and lazy stops it from being fetched // multiple times over FFI - lazy var id = info.id + lazy var id = roomListItem.id() init(roomListItem: RoomListItemProtocol, - roomPreview: RoomPreviewProtocol, - ownUserID: String) throws { + ownUserID: String) { self.roomListItem = roomListItem - self.roomPreview = roomPreview self.ownUserID = ownUserID - info = try RoomPreviewInfoProxy(roomPreviewInfo: roomPreview.info()) + roomPreviewTask = Task { + try await roomListItem.previewRoom(via: []) + } } func cancelKnock() async -> Result { diff --git a/ElementX/Sources/Services/Room/RoomProxyProtocol.swift b/ElementX/Sources/Services/Room/RoomProxyProtocol.swift index 4650fbc60b..37be6a10a0 100644 --- a/ElementX/Sources/Services/Room/RoomProxyProtocol.swift +++ b/ElementX/Sources/Services/Room/RoomProxyProtocol.swift @@ -34,14 +34,14 @@ protocol RoomProxyProtocol { // sourcery: AutoMockable protocol InvitedRoomProxyProtocol: RoomProxyProtocol { - var info: BaseRoomInfoProxyProtocol { get } - var inviter: RoomMemberProxyProtocol? { get } + var info: BaseRoomInfoProxyProtocol { get async throws } + var inviter: RoomMemberProxyProtocol? { get async throws } func rejectInvitation() async -> Result } // sourcery: AutoMockable protocol KnockedRoomProxyProtocol: RoomProxyProtocol { - var info: BaseRoomInfoProxyProtocol { get } + var info: BaseRoomInfoProxyProtocol { get async throws } func cancelKnock() async -> Result }