2021-12-08 22:21:55 +00:00
|
|
|
//
|
|
|
|
// Copyright 2021 New Vector Ltd
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
//
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
|
|
|
|
@objc protocol RoomParticipantsInviteCoordinatorBridgePresenterDelegate {
|
|
|
|
func roomParticipantsInviteCoordinatorBridgePresenterDidStartLoading(_ coordinatorBridgePresenter: RoomParticipantsInviteCoordinatorBridgePresenter)
|
|
|
|
func roomParticipantsInviteCoordinatorBridgePresenterDidEndLoading(_ coordinatorBridgePresenter: RoomParticipantsInviteCoordinatorBridgePresenter)
|
|
|
|
func roomParticipantsInviteCoordinatorBridgePresenterDidComplete(_ coordinatorBridgePresenter: RoomParticipantsInviteCoordinatorBridgePresenter)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// RoomParticipantsInviteCoordinatorBridgePresenter enables to start ContactsPickerCoordinator from a view controller.
|
|
|
|
/// This bridge is used while waiting for global usage of coordinator pattern.
|
|
|
|
@objcMembers
|
|
|
|
final class RoomParticipantsInviteCoordinatorBridgePresenter: NSObject {
|
|
|
|
// MARK: - Properties
|
|
|
|
|
|
|
|
// MARK: Private
|
|
|
|
|
|
|
|
private let session: MXSession?
|
|
|
|
private let room: MXRoom?
|
|
|
|
private let parentSpaceId: String?
|
|
|
|
private let currentSearchText: String?
|
|
|
|
private var actualParticipants: [Contact]?
|
|
|
|
private var invitedParticipants: [Contact]?
|
|
|
|
private var userParticipant: Contact?
|
2021-12-13 21:16:02 +00:00
|
|
|
private var roomOptions: [RoomOptionListItemViewData] = []
|
2021-12-08 22:21:55 +00:00
|
|
|
|
|
|
|
private weak var contactsPickerViewController: ContactsTableViewController?
|
|
|
|
private weak var currentAlert: UIAlertController?
|
|
|
|
private var contactPickerCoordinator: ContactsPickerCoordinator?
|
2021-12-13 21:16:02 +00:00
|
|
|
private var optionListCoordinator: OptionListCoordinator?
|
|
|
|
private var navigationRouter: NavigationRouterType?
|
2021-12-08 22:21:55 +00:00
|
|
|
|
|
|
|
// MARK: Public
|
|
|
|
|
|
|
|
weak var delegate: RoomParticipantsInviteCoordinatorBridgePresenterDelegate?
|
|
|
|
|
|
|
|
// MARK: - Setup
|
|
|
|
|
|
|
|
init(session: MXSession?, room: MXRoom?, parentSpaceId: String?) {
|
|
|
|
self.session = session
|
|
|
|
self.room = room
|
|
|
|
self.parentSpaceId = parentSpaceId
|
|
|
|
self.currentSearchText = nil
|
|
|
|
self.actualParticipants = nil
|
|
|
|
self.invitedParticipants = nil
|
|
|
|
self.userParticipant = nil
|
|
|
|
|
|
|
|
super.init()
|
|
|
|
}
|
|
|
|
|
|
|
|
init(session: MXSession?, room: MXRoom?, parentSpaceId: String?, currentSearchText: String? = nil, actualParticipants: [Contact]? = nil, invitedParticipants: [Contact]? = nil, userParticipant: Contact? = nil) {
|
|
|
|
self.session = session
|
|
|
|
self.room = room
|
|
|
|
self.parentSpaceId = parentSpaceId
|
|
|
|
self.currentSearchText = currentSearchText
|
|
|
|
self.actualParticipants = actualParticipants
|
|
|
|
self.invitedParticipants = invitedParticipants
|
|
|
|
self.userParticipant = userParticipant
|
|
|
|
|
|
|
|
super.init()
|
|
|
|
}
|
|
|
|
|
|
|
|
func present(from viewController: UIViewController, animated: Bool) {
|
|
|
|
guard let room = self.room else {
|
|
|
|
MXLog.error("[RoomParticipantsInviteCoordinatorBridgePresenter] present: nil room found")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-12-13 21:16:02 +00:00
|
|
|
if let navigationController = viewController.navigationController {
|
2022-01-26 09:17:42 +00:00
|
|
|
self.navigationRouter = NavigationRouterStore.shared.findNavigationRouter(for: navigationController) ?? NavigationRouter(navigationController: navigationController)
|
2021-12-13 21:16:02 +00:00
|
|
|
} else {
|
2022-01-26 09:17:42 +00:00
|
|
|
self.navigationRouter = nil
|
2021-12-13 21:16:02 +00:00
|
|
|
}
|
|
|
|
|
2022-01-26 09:17:42 +00:00
|
|
|
if let spaceId = self.parentSpaceId, let spaceRoom = self.session?.spaceService.getSpace(withId: spaceId)?.room {
|
|
|
|
self.presentRoomSelector(between: room, and: spaceRoom)
|
2021-12-08 22:21:55 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-01-26 09:17:42 +00:00
|
|
|
self.pushContactsPicker(for: room)
|
2021-12-08 22:21:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// MARK: - Private
|
|
|
|
|
2021-12-13 21:16:02 +00:00
|
|
|
private class RoomOptionListItemViewData: OptionListItemViewData {
|
|
|
|
let room: MXRoom
|
|
|
|
|
|
|
|
init(title: String? = nil,
|
|
|
|
detail: String? = nil,
|
|
|
|
image: UIImage? = nil,
|
|
|
|
room: MXRoom,
|
2022-01-26 09:17:42 +00:00
|
|
|
accessoryImage: UIImage? = Asset.Images.chevron.image,
|
2022-01-27 13:34:03 +00:00
|
|
|
enabled: Bool = true) {
|
2021-12-13 21:16:02 +00:00
|
|
|
self.room = room
|
2022-01-26 09:17:42 +00:00
|
|
|
super.init(title: title, detail: detail, image: image, accessoryImage: accessoryImage, enabled: enabled)
|
2021-12-13 21:16:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private func presentRoomSelector(between room: MXRoom, and spaceRoom: MXRoom) {
|
2022-01-27 13:34:03 +00:00
|
|
|
let roomName = room.displayName ?? ""
|
|
|
|
let spaceName = spaceRoom.displayName ?? ""
|
|
|
|
|
|
|
|
self.roomOptions = [
|
|
|
|
RoomOptionListItemViewData(title: VectorL10n.roomInviteToSpaceOptionTitle(spaceName),
|
|
|
|
detail: VectorL10n.roomInviteToSpaceOptionDetail(spaceName, roomName),
|
|
|
|
image: Asset.Images.addParticipants.image, room: spaceRoom,
|
|
|
|
accessoryImage: Asset.Images.chevron.image),
|
|
|
|
RoomOptionListItemViewData(title: VectorL10n.roomInviteToRoomOptionTitle,
|
|
|
|
detail: VectorL10n.roomInviteToRoomOptionDetail(spaceName),
|
|
|
|
image: Asset.Images.addParticipants.image, room: room,
|
|
|
|
accessoryImage: Asset.Images.chevron.image)
|
|
|
|
]
|
|
|
|
|
|
|
|
let coordinator = OptionListCoordinator(parameters: OptionListCoordinatorParameters(title: VectorL10n.roomIntroCellAddParticipantsAction, options: self.roomOptions, navigationRouter: self.navigationRouter))
|
|
|
|
coordinator.delegate = self
|
|
|
|
coordinator.start()
|
|
|
|
|
|
|
|
self.optionListCoordinator = coordinator
|
2021-12-08 22:21:55 +00:00
|
|
|
}
|
|
|
|
|
2021-12-13 21:16:02 +00:00
|
|
|
private func pushContactsPicker(for room: MXRoom) {
|
2021-12-08 22:21:55 +00:00
|
|
|
guard let session = self.session else {
|
|
|
|
MXLog.error("[RoomParticipantsInviteCoordinatorBridgePresenter] pushContactsPicker: nil session found")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2022-01-26 09:17:42 +00:00
|
|
|
canInvite(to: room) { [weak self] canInvite in
|
|
|
|
guard let self = self else { return }
|
|
|
|
|
|
|
|
guard canInvite else {
|
|
|
|
let message = room.summary?.roomType == .space ? VectorL10n.spaceInviteNotEnoughPermission : VectorL10n.roomInviteNotEnoughPermission
|
|
|
|
let alert = UIAlertController(title: VectorL10n.spacesInvitePeople, message: message, preferredStyle: .alert)
|
|
|
|
alert.addAction(UIAlertAction(title: VectorL10n.ok, style: .default, handler: nil))
|
|
|
|
self.navigationRouter?.present(alert, animated: true)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
let coordinator = ContactsPickerCoordinator(session: session,
|
|
|
|
room: room,
|
|
|
|
currentSearchText: self.currentSearchText,
|
|
|
|
actualParticipants: self.actualParticipants,
|
|
|
|
invitedParticipants: self.invitedParticipants,
|
|
|
|
userParticipant: self.userParticipant,
|
|
|
|
navigationRouter: self.navigationRouter)
|
|
|
|
coordinator.delegate = self
|
|
|
|
coordinator.start()
|
|
|
|
|
|
|
|
self.contactPickerCoordinator = coordinator
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private func canInvite(to room: MXRoom, completion: @escaping (Bool) -> Void) {
|
|
|
|
guard let userId = self.session?.myUserId else {
|
|
|
|
MXLog.error("[RoomParticipantsInviteCoordinatorBridgePresenter] canInvite: userId not found")
|
|
|
|
completion(false)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
room.state { roomState in
|
|
|
|
guard let powerLevels = roomState?.powerLevels else {
|
|
|
|
MXLog.error("[RoomParticipantsInviteCoordinatorBridgePresenter] canInvite: powerLevels room found")
|
|
|
|
completion(false)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
let userPowerLevel = powerLevels.powerLevelOfUser(withUserID: userId)
|
|
|
|
|
|
|
|
completion(userPowerLevel >= powerLevels.invite)
|
|
|
|
}
|
2021-12-08 22:21:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension RoomParticipantsInviteCoordinatorBridgePresenter: ContactsPickerCoordinatorDelegate {
|
|
|
|
func contactsPickerCoordinatorDidStartLoading(_ coordinator: ContactsPickerCoordinatorType) {
|
|
|
|
delegate?.roomParticipantsInviteCoordinatorBridgePresenterDidStartLoading(self)
|
|
|
|
}
|
|
|
|
|
|
|
|
func contactsPickerCoordinatorDidEndLoading(_ coordinator: ContactsPickerCoordinatorType) {
|
|
|
|
delegate?.roomParticipantsInviteCoordinatorBridgePresenterDidEndLoading(self)
|
|
|
|
}
|
|
|
|
|
|
|
|
func contactsPickerCoordinatorDidClose(_ coordinator: ContactsPickerCoordinatorType) {
|
|
|
|
delegate?.roomParticipantsInviteCoordinatorBridgePresenterDidComplete(self)
|
|
|
|
}
|
|
|
|
}
|
2021-12-13 21:16:02 +00:00
|
|
|
|
|
|
|
extension RoomParticipantsInviteCoordinatorBridgePresenter: OptionListCoordinatorDelegate {
|
|
|
|
func optionListCoordinator(_ coordinator: OptionListCoordinatorProtocol, didSelectOptionAt index: Int) {
|
|
|
|
optionListCoordinator = nil
|
|
|
|
self.pushContactsPicker(for: roomOptions[index].room)
|
|
|
|
}
|
|
|
|
|
|
|
|
func optionListCoordinator(_ coordinator: OptionListCoordinatorProtocol, didCompleteWithUserDisplayName userDisplayName: String?) {
|
|
|
|
optionListCoordinator = nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func optionListCoordinatorDidCancel(_ coordinator: OptionListCoordinatorProtocol) {
|
|
|
|
optionListCoordinator = nil
|
|
|
|
}
|
|
|
|
}
|