From f1de42a1f3411224f1e58cea9ba2dea0f823381c Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Thu, 18 Jul 2024 16:49:04 +0300 Subject: [PATCH] Fixes #2840 - Use both the room list room and the room preview details to populate the join room screen - the room summary API is indeed enabled on matrix.org and working fine for most rooms - it is not however capable of giving us data about non-joined + private rooms - the SDK addresses that by first trying to use known rooms before resorting to the preview endpoint - that fails if it's a brand new room that the client doesn't know about yet i.e. a sync hasn't ran, which is exactly what's happening here - the ClientProxy instead does wait for the room list to go into the first loaded before returning the room --- .../JoinRoomScreen/JoinRoomScreenModels.swift | 12 +++++- .../JoinRoomScreenViewModel.swift | 42 +++++++++++++++---- ...test_joinRoomScreen-iPad-en-GB.Unknown.png | 4 +- ...est_joinRoomScreen-iPad-pseudo.Unknown.png | 4 +- 4 files changed, 49 insertions(+), 13 deletions(-) diff --git a/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenModels.swift b/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenModels.swift index a29f63aac1..e215a129a7 100644 --- a/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenModels.swift +++ b/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenModels.swift @@ -29,11 +29,19 @@ enum JoinRoomScreenInteractionMode { case knock } +struct JoinRoomScreenRoomDetails { + let name: String? + let topic: String? + let canonicalAlias: String? + let avatar: RoomAvatar + let memberCount: UInt +} + struct JoinRoomScreenViewState: BindableState { // Maybe use room summary details or similar here?? let roomID: String - var roomDetails: RoomPreviewDetails? + var roomDetails: JoinRoomScreenRoomDetails? var mode: JoinRoomScreenInteractionMode = .loading @@ -52,7 +60,7 @@ struct JoinRoomScreenViewState: BindableState { } var avatar: RoomAvatar { - .room(id: roomID, name: title, avatarURL: roomDetails?.avatarURL) + roomDetails?.avatar ?? .room(id: roomID, name: title, avatarURL: nil) } } diff --git a/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenViewModel.swift b/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenViewModel.swift index 8000b19960..3cc283acc8 100644 --- a/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenViewModel.swift @@ -26,6 +26,9 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo private let clientProxy: ClientProxyProtocol private let userIndicatorController: UserIndicatorControllerProtocol + private var roomPreviewDetails: RoomPreviewDetails? + private var roomProxy: RoomProxyProtocol? + private let actionsSubject: PassthroughSubject = .init() var actionsPublisher: AnyPublisher { actionsSubject.eraseToAnyPublisher() @@ -77,13 +80,23 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo showLoadingIndicator() defer { - updateMode() hideLoadingIndicator() } + // Using only the preview API isn't enough as it's not capable + // of giving us information for non-joined rooms (at least not on synapse) + // See if we known about the room locally and, if so, have that + // take priority over the preview one. + + if let roomProxy = await clientProxy.roomForIdentifier(roomID) { + self.roomProxy = roomProxy + updateRoomDetails() + } + switch await clientProxy.roomPreviewForIdentifier(roomID, via: via) { - case .success(let roomDetails): - state.roomDetails = roomDetails + case .success(let roomPreviewDetails): + self.roomPreviewDetails = roomPreviewDetails + updateRoomDetails() case .failure(.roomPreviewIsPrivate): break // Handled by the mode, we don't need an error indicator. case .failure: @@ -91,17 +104,32 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo } } + private func updateRoomDetails() { + if roomProxy == nil, roomPreviewDetails == nil { + return + } + + let name = roomProxy?.name ?? roomPreviewDetails?.name + state.roomDetails = JoinRoomScreenRoomDetails(name: name, + topic: roomProxy?.topic ?? roomPreviewDetails?.topic, + canonicalAlias: roomProxy?.canonicalAlias ?? roomPreviewDetails?.canonicalAlias, + avatar: roomProxy?.avatar ?? .room(id: roomID, name: name ?? "", avatarURL: roomPreviewDetails?.avatarURL), + memberCount: UInt(roomProxy?.activeMembersCount ?? Int(roomPreviewDetails?.memberCount ?? 0))) + + updateMode() + } + private func updateMode() { - guard let roomDetails = state.roomDetails else { + if roomProxy == nil, roomPreviewDetails == nil { state.mode = .unknown return } - if roomDetails.isPublic { + if roomProxy?.isPublic ?? false || roomPreviewDetails?.isPublic ?? false { state.mode = .join - } else if roomDetails.isInvited { + } else if roomProxy?.membership == .invited || roomPreviewDetails?.isInvited ?? false { state.mode = .invited - } else if roomDetails.canKnock, allowKnocking { // Knocking is not supported yet, the flag is purely for preview tests. + } else if roomPreviewDetails?.canKnock ?? false, allowKnocking { // Knocking is not supported yet, the flag is purely for preview tests. state.mode = .knock } else { state.mode = .unknown diff --git a/PreviewTests/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-en-GB.Unknown.png b/PreviewTests/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-en-GB.Unknown.png index 6ff8f3f953..555119de6f 100644 --- a/PreviewTests/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-en-GB.Unknown.png +++ b/PreviewTests/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-en-GB.Unknown.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a0b850d16e626197c8ce12f6b6467284adefaf19295b2c75deb13599bda4796f -size 1963867 +oid sha256:d101e405e058e332a699eb6c2db1ab38b15966e06b185b2241be78608dd1939e +size 1959342 diff --git a/PreviewTests/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-pseudo.Unknown.png b/PreviewTests/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-pseudo.Unknown.png index d52f6a7243..555119de6f 100644 --- a/PreviewTests/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-pseudo.Unknown.png +++ b/PreviewTests/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-pseudo.Unknown.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b3cb6c41cb549203b7bae407d7dd9bc11381a1f15087d148dd067dbaab819e75 -size 1977775 +oid sha256:d101e405e058e332a699eb6c2db1ab38b15966e06b185b2241be78608dd1939e +size 1959342