diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift index 811eefcad..fab971e1c 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoCoordinator.swift @@ -81,6 +81,14 @@ extension RoomInfoCoordinator: RoomInfoListCoordinatorDelegate { self?.remove(childCoordinator: coordinator) } } + + func roomInfoListCoordinator(_ coordinator: RoomInfoListCoordinatorType, wantsToPresent viewController: UIViewController) { + let coordinator = SimpleCoordinator(withViewController: viewController) + coordinator.start() + + self.add(childCoordinator: coordinator) + navigationRouter.present(coordinator, animated: true) + } func roomInfoListCoordinatorDidCancel(_ coordinator: RoomInfoListCoordinatorType) { self.delegate?.roomInfoCoordinatorDidComplete(self) diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListCoordinator.swift b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListCoordinator.swift index 5bcf06b86..4e038f382 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListCoordinator.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListCoordinator.swift @@ -66,6 +66,10 @@ extension RoomInfoListCoordinator: RoomInfoListViewModelCoordinatorDelegate { func roomInfoListViewModel(_ viewModel: RoomInfoListViewModelType, wantsToNavigate viewController: UIViewController) { self.delegate?.roomInfoListCoordinator(self, wantsToNavigate: viewController) } + + func roomInfoListViewModel(_ viewModel: RoomInfoListViewModelType, wantsToPresent viewController: UIViewController) { + self.delegate?.roomInfoListCoordinator(self, wantsToPresent: viewController) + } func roomInfoListViewModelDidCancel(_ viewModel: RoomInfoListViewModelType) { self.delegate?.roomInfoListCoordinatorDidCancel(self) diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListCoordinatorType.swift b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListCoordinatorType.swift index 07e671ee4..0eb43dfc9 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListCoordinatorType.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListCoordinatorType.swift @@ -20,6 +20,7 @@ import Foundation protocol RoomInfoListCoordinatorDelegate: class { func roomInfoListCoordinator(_ coordinator: RoomInfoListCoordinatorType, wantsToNavigate viewController: UIViewController) + func roomInfoListCoordinator(_ coordinator: RoomInfoListCoordinatorType, wantsToPresent viewController: UIViewController) func roomInfoListCoordinatorDidCancel(_ coordinator: RoomInfoListCoordinatorType) } diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewAction.swift b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewAction.swift index 70cf5e6d9..a456d7fb2 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewAction.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewAction.swift @@ -28,5 +28,6 @@ enum RoomInfoListTarget { enum RoomInfoListViewAction { case loadData case navigate(target: RoomInfoListTarget) + case leave case cancel } diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewController.swift b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewController.swift index f3a4c14ae..1497323a1 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewController.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewController.swift @@ -152,7 +152,7 @@ final class RoomInfoListViewController: UIViewController { footer: nil) let row_3_0 = Row(type: .destructive, icon: Asset.Images.roomActionLeave.image, text: VectorL10n.roomParticipantsLeavePromptTitle, accessoryType: .none) { - // no-op + self.viewModel.process(viewAction: .leave) } let section3 = Section(header: nil, rows: [row_3_0], diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModel.swift b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModel.swift index 729664cb6..7432e1355 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModel.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModel.swift @@ -67,6 +67,29 @@ final class RoomInfoListViewModel: NSObject, RoomInfoListViewModelType { return controller }() + private lazy var leaveAlertController: UIAlertController = { + let controller = UIAlertController(title: VectorL10n.roomParticipantsLeavePromptTitle, message: VectorL10n.roomParticipantsLeavePromptMsg, preferredStyle: .alert) + + controller.addAction(UIAlertAction(title: VectorL10n.cancel, style: .cancel, handler: nil)) + controller.addAction(UIAlertAction(title: VectorL10n.leave, style: .default, handler: { [weak self] (action) in + guard let self = self else { return } + self.stopObservingSummaryChanges() + self.update(viewState: .loading) + self.room.leave { (response) in + switch response { + case .success: + self.coordinatorDelegate?.roomInfoListViewModelDidCancel(self) + case .failure(let error): + self.startObservingSummaryChanges() + self.update(viewState: .error(error)) + } + } + })) + controller.mxk_setAccessibilityIdentifier("RoomSettingsVCLeaveAlert") + + return controller + }() + // MARK: Public weak var viewDelegate: RoomInfoListViewModelViewDelegate? @@ -91,11 +114,11 @@ final class RoomInfoListViewModel: NSObject, RoomInfoListViewModelType { self.session = session self.room = room super.init() - NotificationCenter.default.addObserver(self, selector: #selector(roomSummaryUpdated(_:)), name: .mxRoomSummaryDidChange, object: room.summary) + startObservingSummaryChanges() } deinit { - NotificationCenter.default.removeObserver(self) + stopObservingSummaryChanges() } // MARK: - Public @@ -106,6 +129,8 @@ final class RoomInfoListViewModel: NSObject, RoomInfoListViewModelType { self.loadData() case .navigate(let target): self.navigate(to: target) + case .leave: + self.leave() case .cancel: self.coordinatorDelegate?.roomInfoListViewModelDidCancel(self) } @@ -113,6 +138,14 @@ final class RoomInfoListViewModel: NSObject, RoomInfoListViewModelType { // MARK: - Private + private func startObservingSummaryChanges() { + NotificationCenter.default.addObserver(self, selector: #selector(roomSummaryUpdated(_:)), name: .mxRoomSummaryDidChange, object: room.summary) + } + + private func stopObservingSummaryChanges() { + NotificationCenter.default.removeObserver(self, name: .mxRoomSummaryDidChange, object: nil) + } + @objc private func roomSummaryUpdated(_ notification: Notification) { // force update view self.update(viewState: .loaded) @@ -139,6 +172,10 @@ final class RoomInfoListViewModel: NSObject, RoomInfoListViewModelType { } } + private func leave() { + self.coordinatorDelegate?.roomInfoListViewModel(self, wantsToPresent: leaveAlertController) + } + private func update(viewState: RoomInfoListViewState) { self.viewDelegate?.roomInfoListViewModel(self, didUpdateViewState: viewState) } diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModelType.swift b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModelType.swift index 13076f2e4..2db3f22fc 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModelType.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModelType.swift @@ -25,6 +25,7 @@ protocol RoomInfoListViewModelViewDelegate: class { protocol RoomInfoListViewModelCoordinatorDelegate: class { func roomInfoListViewModelDidCancel(_ viewModel: RoomInfoListViewModelType) func roomInfoListViewModel(_ viewModel: RoomInfoListViewModelType, wantsToNavigate viewController: UIViewController) + func roomInfoListViewModel(_ viewModel: RoomInfoListViewModelType, wantsToPresent viewController: UIViewController) } /// Protocol describing the view model used by `RoomInfoListViewController`