Contextual menu for rooms (#842)

* Add room contextual menu

* Add room context menu view actions

* Add navigation to room’s detail

* Show leave alert in HomeScreen

* Implement leave logic

* Refine leave navigation for iPad

* Optimize leave from homescreen

* Refactor roomSettings -> roomDetails

* Refactor room for id mock

* Add UTs

* Cleanup

* Fix alert presentation in RoomDetailsScreenViewModel

* Fix animation flag
This commit is contained in:
Alfonso Grillo
2023-05-04 12:02:18 +02:00
committed by GitHub
parent 86aebfb9ef
commit e9c07c9f8f
14 changed files with 242 additions and 17 deletions
@@ -123,9 +123,14 @@ class UserSessionFlowCoordinator: CoordinatorProtocol {
case (.invitesScreen, .closedInvitesScreen, .roomList):
break
case (.invitesScreen, .selectRoom(let roomId), .invitesScreen(let selectedRoomId)) where roomId == selectedRoomId:
self.presentRoomWithIdentifier(roomId)
self.presentRoomWithIdentifier(roomId, animated: animated)
case (.invitesScreen, .deselectRoom, .invitesScreen):
break
case (.roomList(let currentRoomId), .selectRoomDetails(let roomId), .roomList) where currentRoomId == roomId:
break
case (.roomList, .selectRoomDetails(let roomId), .roomList(let selectedRoomId)) where roomId == selectedRoomId:
self.presentRoomDetails(roomIdentifier: roomId, animated: animated)
default:
fatalError("Unknown transition: \(context)")
@@ -152,6 +157,10 @@ class UserSessionFlowCoordinator: CoordinatorProtocol {
switch action {
case .presentRoom(let roomIdentifier):
self.stateMachine.processEvent(.selectRoom(roomId: roomIdentifier))
case .presentRoomDetails(let roomIdentifier):
self.stateMachine.processEvent(.selectRoomDetails(roomId: roomIdentifier))
case .roomLeft(let roomIdentifier):
self.deselectRoomIfNeeded(roomIdentifier: roomIdentifier)
case .presentSettingsScreen:
self.stateMachine.processEvent(.showSettingsScreen)
case .presentFeedbackScreen:
@@ -226,11 +235,54 @@ class UserSessionFlowCoordinator: CoordinatorProtocol {
}
}
}
private func deselectRoomIfNeeded(roomIdentifier: String) {
guard
case .roomList(selectedRoomId: let selectedRoomId) = stateMachine.state,
selectedRoomId == roomIdentifier
else {
return
}
stateMachine.processEvent(.deselectRoom)
navigationSplitCoordinator.setDetailCoordinator(nil)
}
private func dismissRoom() {
detailNavigationStackCoordinator.popToRoot(animated: true)
navigationSplitCoordinator.setDetailCoordinator(nil)
}
private func presentRoomDetails(roomIdentifier: String, animated: Bool = true) {
Task {
guard let roomProxy = await userSession.clientProxy.roomForIdentifier(roomIdentifier) else {
MXLog.error("Invalid room identifier: \(roomIdentifier)")
return
}
let params = RoomDetailsScreenCoordinatorParameters(navigationStackCoordinator: detailNavigationStackCoordinator,
roomProxy: roomProxy,
mediaProvider: userSession.mediaProvider)
let coordinator = RoomDetailsScreenCoordinator(parameters: params)
coordinator.callback = { [weak self] action in
switch action {
case .cancel, .leftRoom:
self?.stateMachine.processEvent(.deselectRoom)
self?.detailNavigationStackCoordinator.setRootCoordinator(nil)
}
}
detailNavigationStackCoordinator.setRootCoordinator(coordinator, animated: animated) { [weak self, roomIdentifier] in
self?.deselectRoomIfNeeded(roomIdentifier: roomIdentifier)
}
if navigationSplitCoordinator.detailCoordinator == nil {
navigationSplitCoordinator.setDetailCoordinator(detailNavigationStackCoordinator, animated: animated)
}
}
}
// MARK: Settings
@@ -77,6 +77,9 @@ class UserSessionFlowCoordinatorStateMachine {
case showInvitesScreen
/// The invites screen has been dismissed
case closedInvitesScreen
/// Request presentation of the settings of a specific room
case selectRoomDetails(roomId: String)
}
private let stateMachine: StateMachine<State, Event>
@@ -129,6 +132,9 @@ class UserSessionFlowCoordinatorStateMachine {
return .invitesScreen(selectedRoomId: roomId)
case (.deselectRoom, .invitesScreen):
return .invitesScreen(selectedRoomId: nil)
case (.selectRoomDetails(let roomId), .roomList):
return .roomList(selectedRoomId: roomId)
default:
return nil