Skip to content

Commit

Permalink
Fixes #2840 - Use both the room list room and the room preview detail…
Browse files Browse the repository at this point in the history
…s 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
  • Loading branch information
stefanceriu committed Jul 18, 2024
1 parent 86ce3de commit f1de42a
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 13 deletions.
12 changes: 10 additions & 2 deletions ElementX/Sources/Screens/JoinRoomScreen/JoinRoomScreenModels.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<JoinRoomScreenViewModelAction, Never> = .init()
var actionsPublisher: AnyPublisher<JoinRoomScreenViewModelAction, Never> {
actionsSubject.eraseToAnyPublisher()
Expand Down Expand Up @@ -77,31 +80,56 @@ 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:
userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
}
}

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
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit f1de42a

Please sign in to comment.