Observe room info updates and automatically dismiss the room if meanwhile left or banned (#4122)

* Fix #3302 - Observe room info updates and automatically dismiss the room if meanwhile left or banned.
This commit is contained in:
Stefan Ceriu
2025-05-16 12:55:33 +03:00
committed by GitHub
parent f5089e8d81
commit 35f615ddd1
3 changed files with 42 additions and 1 deletions
@@ -273,6 +273,19 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
// early return above could result in trying to access the room's timeline provider
// before it has been set which triggers a fatal error.
self.roomProxy = roomProxy
// Subscribe to room info updates in order to detect rooms being left on other devices
// and react accordingly by dismissing this flow coordinator.
self.roomProxy.infoPublisher
.receive(on: DispatchQueue.main)
.sink { [weak self] info in
guard let self else { return }
if info.membership == .left || info.membership == .banned, stateMachine.state != .complete {
stateMachine.tryEvent(.dismissFlow)
}
}
.store(in: &cancellables)
}
// swiftlint:disable:next function_body_length
@@ -43,7 +43,10 @@ struct JoinedRoomProxyMockConfiguration {
var canUserPin = true
var shouldUseAutoUpdatingTimeline = false
var joinRule: JoinRule?
var membership: Membership = .joined
var isVisibleInPublicDirectory = false
}
@@ -151,7 +154,7 @@ extension RoomInfo {
isFavourite: false,
canonicalAlias: configuration.canonicalAlias,
alternativeAliases: configuration.alternativeAliases,
membership: .joined,
membership: configuration.membership,
inviter: configuration.inviter.map { RoomMember(userId: $0.userID,
displayName: $0.displayName,
avatarUrl: $0.avatarURL?.absoluteString,
@@ -268,6 +268,31 @@ class RoomFlowCoordinatorTests: XCTestCase {
XCTAssertNil(navigationStackCoordinator.sheetCoordinator, "The media upload sheet shouldn't be shown when sharing text.")
}
func testLeavingRoom() async throws {
await setupRoomFlowCoordinator()
var configuration = JoinedRoomProxyMockConfiguration()
let roomProxy = JoinedRoomProxyMock(configuration)
let roomInfoSubject = CurrentValueSubject<RoomInfoProxy, Never>(.init(roomInfo: .init(configuration)))
roomProxy.infoPublisher = roomInfoSubject.asCurrentValuePublisher()
clientProxy.roomForIdentifierClosure = { _ in
.joined(roomProxy)
}
try await process(route: .room(roomID: "1", via: []))
let fulfillment = deferFulfillment(roomFlowCoordinator.actions) { action in
action == .finished
}
configuration.membership = .left
roomInfoSubject.send(.init(roomInfo: .init(configuration)))
try await fulfillment.fulfill()
}
// MARK: - Private
private func process(route: AppRoute) async throws {