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
@@ -153,10 +153,17 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
// MARK: - Public
// swiftlint:disable:next cyclomatic_complexity
override func process(viewAction: HomeScreenViewAction) {
switch viewAction {
case .selectRoom(let roomIdentifier):
callback?(.presentRoom(roomIdentifier: roomIdentifier))
case .showRoomDetails(roomIdentifier: let roomIdentifier):
callback?(.presentRoomDetails(roomIdentifier: roomIdentifier))
case .leaveRoom(roomIdentifier: let roomIdentifier):
startLeaveRoomProcess(roomId: roomIdentifier)
case .confirmLeaveRoom(roomIdentifier: let roomIdentifier):
leaveRoom(roomId: roomIdentifier)
case .userMenu(let action):
switch action {
case .feedback:
@@ -301,4 +308,56 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
visibleRoomsSummaryProvider.updateVisibleRange(range, timelineLimit: timelineLimit)
}
private static let leaveRoomLoadingID = "LeaveRoomLoading"
private func startLeaveRoomProcess(roomId: String) {
Task {
defer {
ServiceLocator.shared.userIndicatorController.retractIndicatorWithId(Self.leaveRoomLoadingID)
}
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(id: Self.leaveRoomLoadingID, type: .modal, title: L10n.commonLoading, persistent: true))
let room = await userSession.clientProxy.roomForIdentifier(roomId)
guard let room else {
state.bindings.alertInfo = AlertInfo(id: UUID(), title: L10n.errorUnknown)
return
}
guard !room.isPublic else {
state.bindings.leaveRoomAlertItem = LeaveRoomAlertItem(roomId: roomId, state: .public)
return
}
await room.updateMembers()
let joinedMembers = await room.membersPublisher.values.first()?.filter { $0.membership == .join }
guard let joinedMembers else {
state.bindings.alertInfo = AlertInfo(id: UUID(), title: L10n.errorUnknown)
return
}
state.bindings.leaveRoomAlertItem = joinedMembers.count > 1 ? LeaveRoomAlertItem(roomId: roomId, state: .private) : LeaveRoomAlertItem(roomId: roomId, state: .empty)
}
}
private func leaveRoom(roomId: String) {
Task {
defer {
ServiceLocator.shared.userIndicatorController.retractIndicatorWithId(Self.leaveRoomLoadingID)
}
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(id: Self.leaveRoomLoadingID, type: .modal, title: L10n.commonLoading, persistent: true))
let room = await userSession.clientProxy.roomForIdentifier(roomId)
let result = await room?.leaveRoom()
switch result {
case .none, .some(.failure):
state.bindings.alertInfo = AlertInfo(id: UUID(), title: L10n.errorUnknown)
case .some(.success):
callback?(.roomLeft(roomIdentifier: roomId))
}
}
}
}