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
This commit is contained in:
committed by
Stefan Ceriu
parent
27df9b1ae0
commit
22e622bd79
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
@@ -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
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a0b850d16e626197c8ce12f6b6467284adefaf19295b2c75deb13599bda4796f
|
||||
size 1963867
|
||||
oid sha256:d101e405e058e332a699eb6c2db1ab38b15966e06b185b2241be78608dd1939e
|
||||
size 1959342
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b3cb6c41cb549203b7bae407d7dd9bc11381a1f15087d148dd067dbaab819e75
|
||||
size 1977775
|
||||
oid sha256:d101e405e058e332a699eb6c2db1ab38b15966e06b185b2241be78608dd1939e
|
||||
size 1959342
|
||||
|
||||
Reference in New Issue
Block a user