mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
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:
parent
86ce3def13
commit
f1de42a1f3
@ -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
|
||||
|
BIN
PreviewTests/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-en-GB.Unknown.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-en-GB.Unknown.png
(Stored with Git LFS)
Binary file not shown.
BIN
PreviewTests/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-pseudo.Unknown.png
(Stored with Git LFS)
BIN
PreviewTests/__Snapshots__/PreviewTests/test_joinRoomScreen-iPad-pseudo.Unknown.png
(Stored with Git LFS)
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user