mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +00:00
Advance the join room screen when the server joins us to the room
The homeserver can join a user without a join request from their client, auto-accepting a knock (element-hq/synapse#16307) or an invite accepted on another device. The join room screen only navigated on a user-initiated join and only observed membership changes while knocked, so a server-side join left it sitting on a stale invited state.
This commit is contained in:
committed by
Stefan Ceriu
parent
c8b12d9496
commit
c812b723dc
@@ -22,6 +22,7 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
|
||||
private var room: RoomProxyType?
|
||||
private var isLoadingPreview = true
|
||||
private var membershipStateChangeCancellable: AnyCancellable?
|
||||
private var hasSentJoinAction = false
|
||||
|
||||
private let actionsSubject: PassthroughSubject<JoinRoomScreenViewModelAction, Never> = .init()
|
||||
var actionsPublisher: AnyPublisher<JoinRoomScreenViewModelAction, Never> {
|
||||
@@ -148,21 +149,10 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
|
||||
case .invited(let invitedRoomProxy):
|
||||
inviter = invitedRoomProxy.inviter.map(RoomInviterDetails.init)
|
||||
roomInfo = invitedRoomProxy.info
|
||||
watchForMembershipChange(from: .invited)
|
||||
case .knocked(let knockedRoomProxy):
|
||||
roomInfo = knockedRoomProxy.info
|
||||
membershipStateChangeCancellable = clientProxy
|
||||
.staticRoomSummaryProvider
|
||||
.roomListPublisher
|
||||
.compactMap { summaries -> Void? in
|
||||
guard let roomSummary = summaries.first(where: { $0.id == roomInfo?.id }),
|
||||
roomSummary.room.membership() != .knocked else {
|
||||
return nil
|
||||
}
|
||||
return ()
|
||||
}
|
||||
.sink { [weak self] in
|
||||
Task { await self?.loadRoomDetails() }
|
||||
}
|
||||
watchForMembershipChange(from: .knocked)
|
||||
case .banned(let bannedRoomProxy):
|
||||
roomInfo = bannedRoomProxy.info
|
||||
default:
|
||||
@@ -176,6 +166,32 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
|
||||
await updateSpaceRoomDetails(spaceServiceRoom: spaceServiceRoom, inviter: inviter)
|
||||
}
|
||||
await updateMode()
|
||||
|
||||
// The homeserver can join us to the room without a join request from this client:
|
||||
// it auto-joined us after our knock was accepted
|
||||
// (https://github.com/element-hq/synapse/issues/16307), or the invite was accepted
|
||||
// on another of our devices. Advance into the room as if the join button had been
|
||||
// tapped, matching Android's RoomFlowNode.
|
||||
if case .joined = room {
|
||||
await finishJoinAction()
|
||||
}
|
||||
}
|
||||
|
||||
private func watchForMembershipChange(from membership: Membership) {
|
||||
let roomID = state.roomID
|
||||
membershipStateChangeCancellable = clientProxy
|
||||
.staticRoomSummaryProvider
|
||||
.roomListPublisher
|
||||
.compactMap { summaries -> Void? in
|
||||
guard let roomSummary = summaries.first(where: { $0.id == roomID }),
|
||||
roomSummary.room.membership() != membership else {
|
||||
return nil
|
||||
}
|
||||
return ()
|
||||
}
|
||||
.sink { [weak self] in
|
||||
Task { await self?.loadRoomDetails() }
|
||||
}
|
||||
}
|
||||
|
||||
private func updateGenericRoomDetails(roomID: String, roomInfo: BaseRoomInfoProxyProtocol?, inviter: RoomInviterDetails?) async {
|
||||
@@ -329,16 +345,22 @@ class JoinRoomScreenViewModel: JoinRoomScreenViewModelType, JoinRoomScreenViewMo
|
||||
}
|
||||
|
||||
private func finishJoinAction() async {
|
||||
// A user-initiated join and a server-side one can complete concurrently:
|
||||
// only ever advance once.
|
||||
guard !hasSentJoinAction else { return }
|
||||
|
||||
let roomID = state.roomID
|
||||
appSettings.seenInvites.remove(roomID)
|
||||
|
||||
guard state.roomDetails?.isSpace == true else {
|
||||
hasSentJoinAction = true
|
||||
actionsSubject.send(.joined(.roomID(roomID)))
|
||||
return
|
||||
}
|
||||
|
||||
switch await clientProxy.spaceService.spaceRoomList(spaceID: roomID) {
|
||||
case .success(let spaceRoomListProxy):
|
||||
hasSentJoinAction = true
|
||||
actionsSubject.send(.joined(.space(spaceRoomListProxy)))
|
||||
case .failure(let error):
|
||||
MXLog.error("Failed to get the space room list after joining: \(error)")
|
||||
|
||||
Reference in New Issue
Block a user