From b73e5e9e5d32d45097da387b3f8b1ee15ea5b48d Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 12 Jun 2024 15:55:12 +0300 Subject: [PATCH] Prioritise joining rooms by alias if available and letting the homeserver do the right thing --- .../Mocks/Generated/GeneratedMocks.swift | 68 +++++++++++++++++++ .../JoinRoomScreenViewModel.swift | 23 +++++-- .../Sources/Services/Client/ClientProxy.swift | 14 ++++ .../Services/Client/ClientProxyProtocol.swift | 2 + 4 files changed, 101 insertions(+), 6 deletions(-) diff --git a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift index a15758cff..89789054f 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -2523,6 +2523,74 @@ class ClientProxyMock: ClientProxyProtocol { return joinRoomViaReturnValue } } + //MARK: - joinRoomAlias + + var joinRoomAliasUnderlyingCallsCount = 0 + var joinRoomAliasCallsCount: Int { + get { + if Thread.isMainThread { + return joinRoomAliasUnderlyingCallsCount + } else { + var returnValue: Int? = nil + DispatchQueue.main.sync { + returnValue = joinRoomAliasUnderlyingCallsCount + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + joinRoomAliasUnderlyingCallsCount = newValue + } else { + DispatchQueue.main.sync { + joinRoomAliasUnderlyingCallsCount = newValue + } + } + } + } + var joinRoomAliasCalled: Bool { + return joinRoomAliasCallsCount > 0 + } + var joinRoomAliasReceivedRoomAlias: String? + var joinRoomAliasReceivedInvocations: [String] = [] + + var joinRoomAliasUnderlyingReturnValue: Result! + var joinRoomAliasReturnValue: Result! { + get { + if Thread.isMainThread { + return joinRoomAliasUnderlyingReturnValue + } else { + var returnValue: Result? = nil + DispatchQueue.main.sync { + returnValue = joinRoomAliasUnderlyingReturnValue + } + + return returnValue! + } + } + set { + if Thread.isMainThread { + joinRoomAliasUnderlyingReturnValue = newValue + } else { + DispatchQueue.main.sync { + joinRoomAliasUnderlyingReturnValue = newValue + } + } + } + } + var joinRoomAliasClosure: ((String) async -> Result)? + + func joinRoomAlias(_ roomAlias: String) async -> Result { + joinRoomAliasCallsCount += 1 + joinRoomAliasReceivedRoomAlias = roomAlias + joinRoomAliasReceivedInvocations.append(roomAlias) + if let joinRoomAliasClosure = joinRoomAliasClosure { + return await joinRoomAliasClosure(roomAlias) + } else { + return joinRoomAliasReturnValue + } + } //MARK: - uploadMedia var uploadMediaUnderlyingCallsCount = 0 diff --git a/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenViewModel.swift b/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenViewModel.swift index 6e704f486..646157640 100644 --- a/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenViewModel.swift @@ -92,12 +92,23 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo hideLoadingIndicator() } - switch await clientProxy.joinRoom(roomID, via: via) { - case .success: - actionsSubject.send(.joined) - case .failure(let error): - MXLog.error("Failed joining room with error: \(error)") - userIndicatorController.submitIndicator(.init(title: L10n.errorUnknown)) + // Prioritise joining by the alias and letting the homeserver do the right thing + if let alias = state.roomDetails?.canonicalAlias { + switch await clientProxy.joinRoomAlias(alias) { + case .success: + actionsSubject.send(.joined) + case .failure(let error): + MXLog.error("Failed joining room alias: \(alias) with error: \(error)") + userIndicatorController.submitIndicator(.init(title: L10n.errorUnknown)) + } + } else { + switch await clientProxy.joinRoom(roomID, via: via) { + case .success: + actionsSubject.send(.joined) + case .failure(let error): + MXLog.error("Failed joining room id: \(roomID) with error: \(error)") + userIndicatorController.submitIndicator(.init(title: L10n.errorUnknown)) + } } } diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index 4e12a7c05..a537f7338 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -385,6 +385,20 @@ class ClientProxy: ClientProxyProtocol { } } + func joinRoomAlias(_ roomAlias: String) async -> Result { + do { + let room = try await client.joinRoomByIdOrAlias(roomIdOrAlias: roomAlias, serverNames: []) + + // Wait for the room to appear in the room lists to avoid issues downstream + let _ = await waitForRoomSummary(with: .success(room.id()), name: nil, timeout: 30) + + return .success(()) + } catch { + MXLog.error("Failed joining roomAlias: \(roomAlias) with error: \(error)") + return .failure(.sdkError(error)) + } + } + func uploadMedia(_ media: MediaInfo) async -> Result { guard let mimeType = media.mimeType else { MXLog.error("Failed uploading media, invalid mime type: \(media)") diff --git a/ElementX/Sources/Services/Client/ClientProxyProtocol.swift b/ElementX/Sources/Services/Client/ClientProxyProtocol.swift index 0f051aa41..6562b1f46 100644 --- a/ElementX/Sources/Services/Client/ClientProxyProtocol.swift +++ b/ElementX/Sources/Services/Client/ClientProxyProtocol.swift @@ -131,6 +131,8 @@ protocol ClientProxyProtocol: AnyObject, MediaLoaderProtocol { func joinRoom(_ roomID: String, via: [String]) async -> Result + func joinRoomAlias(_ roomAlias: String) async -> Result + func uploadMedia(_ media: MediaInfo) async -> Result func roomForIdentifier(_ identifier: String) async -> RoomProxyProtocol?