mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-11 13:59:13 +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
|
case knock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct JoinRoomScreenRoomDetails {
|
||||||
|
let name: String?
|
||||||
|
let topic: String?
|
||||||
|
let canonicalAlias: String?
|
||||||
|
let avatar: RoomAvatar
|
||||||
|
let memberCount: UInt
|
||||||
|
}
|
||||||
|
|
||||||
struct JoinRoomScreenViewState: BindableState {
|
struct JoinRoomScreenViewState: BindableState {
|
||||||
// Maybe use room summary details or similar here??
|
// Maybe use room summary details or similar here??
|
||||||
let roomID: String
|
let roomID: String
|
||||||
|
|
||||||
var roomDetails: RoomPreviewDetails?
|
var roomDetails: JoinRoomScreenRoomDetails?
|
||||||
|
|
||||||
var mode: JoinRoomScreenInteractionMode = .loading
|
var mode: JoinRoomScreenInteractionMode = .loading
|
||||||
|
|
||||||
@ -52,7 +60,7 @@ struct JoinRoomScreenViewState: BindableState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var avatar: RoomAvatar {
|
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 clientProxy: ClientProxyProtocol
|
||||||
private let userIndicatorController: UserIndicatorControllerProtocol
|
private let userIndicatorController: UserIndicatorControllerProtocol
|
||||||
|
|
||||||
|
private var roomPreviewDetails: RoomPreviewDetails?
|
||||||
|
private var roomProxy: RoomProxyProtocol?
|
||||||
|
|
||||||
private let actionsSubject: PassthroughSubject<JoinRoomScreenViewModelAction, Never> = .init()
|
private let actionsSubject: PassthroughSubject<JoinRoomScreenViewModelAction, Never> = .init()
|
||||||
var actionsPublisher: AnyPublisher<JoinRoomScreenViewModelAction, Never> {
|
var actionsPublisher: AnyPublisher<JoinRoomScreenViewModelAction, Never> {
|
||||||
actionsSubject.eraseToAnyPublisher()
|
actionsSubject.eraseToAnyPublisher()
|
||||||
@ -77,13 +80,23 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
|
|||||||
showLoadingIndicator()
|
showLoadingIndicator()
|
||||||
|
|
||||||
defer {
|
defer {
|
||||||
updateMode()
|
|
||||||
hideLoadingIndicator()
|
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) {
|
switch await clientProxy.roomPreviewForIdentifier(roomID, via: via) {
|
||||||
case .success(let roomDetails):
|
case .success(let roomPreviewDetails):
|
||||||
state.roomDetails = roomDetails
|
self.roomPreviewDetails = roomPreviewDetails
|
||||||
|
updateRoomDetails()
|
||||||
case .failure(.roomPreviewIsPrivate):
|
case .failure(.roomPreviewIsPrivate):
|
||||||
break // Handled by the mode, we don't need an error indicator.
|
break // Handled by the mode, we don't need an error indicator.
|
||||||
case .failure:
|
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() {
|
private func updateMode() {
|
||||||
guard let roomDetails = state.roomDetails else {
|
if roomProxy == nil, roomPreviewDetails == nil {
|
||||||
state.mode = .unknown
|
state.mode = .unknown
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if roomDetails.isPublic {
|
if roomProxy?.isPublic ?? false || roomPreviewDetails?.isPublic ?? false {
|
||||||
state.mode = .join
|
state.mode = .join
|
||||||
} else if roomDetails.isInvited {
|
} else if roomProxy?.membership == .invited || roomPreviewDetails?.isInvited ?? false {
|
||||||
state.mode = .invited
|
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
|
state.mode = .knock
|
||||||
} else {
|
} else {
|
||||||
state.mode = .unknown
|
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