SP1.2: Invite to Space in room landing element-ios#5225

- Check user permissions to invite people
This commit is contained in:
Gil Eluard
2022-01-26 10:17:42 +01:00
parent d23f24b9ce
commit fb89b0092e
7 changed files with 129 additions and 40 deletions
@@ -21,14 +21,17 @@ class OptionListItemViewData {
let detail: String?
let image: UIImage?
let accessoryImage: UIImage?
let enabled: Bool
init(title: String? = nil,
detail: String? = nil,
image: UIImage? = nil,
accessoryImage: UIImage? = Asset.Images.chevron.image) {
accessoryImage: UIImage? = Asset.Images.chevron.image,
enabled: Bool = true) {
self.title = title
self.detail = detail
self.image = image
self.accessoryImage = accessoryImage
self.enabled = enabled
}
}
@@ -26,6 +26,12 @@ class OptionListViewCell: UITableViewCell, NibReusable {
@IBOutlet private weak var detailLabel: UILabel!
@IBOutlet private weak var selectionView: UIView!
@IBOutlet private weak var chevronView: UIImageView!
var isEnabled: Bool = true {
didSet {
self.contentView.alpha = isEnabled ? 1 : 0.3
}
}
// MARK: - Private
@@ -42,10 +48,12 @@ class OptionListViewCell: UITableViewCell, NibReusable {
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
if isEnabled {
super.setSelected(selected, animated: animated)
UIView.animate(withDuration: animated ? 0.2 : 0.0) {
self.selectionView.transform = selected ? .init(scaleX: 0.95, y: 0.95) : .identity
UIView.animate(withDuration: animated ? 0.2 : 0.0) {
self.selectionView.transform = selected ? .init(scaleX: 0.95, y: 0.95) : .identity
}
}
}
@@ -56,6 +64,7 @@ class OptionListViewCell: UITableViewCell, NibReusable {
self.titleLabel.text = viewData.title
self.detailLabel.text = viewData.detail
self.chevronView.image = viewData.accessoryImage?.withRenderingMode(.alwaysTemplate)
self.isEnabled = viewData.enabled
}
func update(theme: Theme) {
@@ -207,6 +207,8 @@ extension OptionListViewController: UITableViewDataSource {
extension OptionListViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
viewModel.process(viewAction: .selected(indexPath.row))
if options[indexPath.row].enabled {
viewModel.process(viewAction: .selected(indexPath.row))
}
}
}
@@ -82,17 +82,17 @@ final class RoomParticipantsInviteCoordinatorBridgePresenter: NSObject {
}
if let navigationController = viewController.navigationController {
navigationRouter = NavigationRouterStore.shared.findNavigationRouter(for: navigationController) ?? NavigationRouter(navigationController: navigationController)
self.navigationRouter = NavigationRouterStore.shared.findNavigationRouter(for: navigationController) ?? NavigationRouter(navigationController: navigationController)
} else {
navigationRouter = nil
self.navigationRouter = nil
}
if let spaceId = self.parentSpaceId, let spaceRoom = session?.spaceService.getSpace(withId: spaceId)?.room {
presentRoomSelector(between: room, and: spaceRoom)
if let spaceId = self.parentSpaceId, let spaceRoom = self.session?.spaceService.getSpace(withId: spaceId)?.room {
self.presentRoomSelector(between: room, and: spaceRoom)
return
}
pushContactsPicker(for: room)
self.pushContactsPicker(for: room)
}
// MARK: - Private
@@ -104,26 +104,43 @@ final class RoomParticipantsInviteCoordinatorBridgePresenter: NSObject {
detail: String? = nil,
image: UIImage? = nil,
room: MXRoom,
accessoryImage: UIImage? = Asset.Images.chevron.image) {
accessoryImage: UIImage? = Asset.Images.chevron.image,
enabled: Bool) {
self.room = room
super.init(title: title, detail: detail, image: image, accessoryImage: accessoryImage)
super.init(title: title, detail: detail, image: image, accessoryImage: accessoryImage, enabled: enabled)
}
}
private func presentRoomSelector(between room: MXRoom, and spaceRoom: MXRoom) {
let roomName = room.displayName ?? ""
let spaceName = spaceRoom.displayName ?? ""
roomOptions = [
RoomOptionListItemViewData(title: VectorL10n.roomInviteToSpaceOptionTitle(spaceName),
detail: VectorL10n.roomInviteToSpaceOptionDetail(spaceName, roomName),
image: Asset.Images.addParticipants.image, room: spaceRoom),
RoomOptionListItemViewData(title: VectorL10n.roomInviteToRoomOptionTitle,
detail: VectorL10n.roomInviteToRoomOptionDetail(spaceName),
image: Asset.Images.addParticipants.image, room: room)
]
optionListCoordinator = OptionListCoordinator(parameters: OptionListCoordinatorParameters(title: VectorL10n.roomIntroCellAddParticipantsAction, options: roomOptions, navigationRouter: navigationRouter))
optionListCoordinator?.delegate = self
optionListCoordinator?.start()
canInvite(to: room) { [weak self] canInviteToRoom in
guard let self = self else { return }
self.canInvite(to: spaceRoom) { [weak self] canInviteToSpace in
guard let self = self else { return }
let roomName = room.displayName ?? ""
let spaceName = spaceRoom.displayName ?? ""
self.roomOptions = [
RoomOptionListItemViewData(title: VectorL10n.roomInviteToSpaceOptionTitle(spaceName),
detail: canInviteToSpace ? VectorL10n.roomInviteToSpaceOptionDetail(spaceName, roomName) : VectorL10n.spaceInviteNotEnoughPermission,
image: Asset.Images.addParticipants.image, room: spaceRoom,
accessoryImage: canInviteToSpace ? Asset.Images.chevron.image : nil,
enabled: canInviteToSpace),
RoomOptionListItemViewData(title: VectorL10n.roomInviteToRoomOptionTitle,
detail: canInviteToRoom ? VectorL10n.roomInviteToRoomOptionDetail(spaceName) : VectorL10n.roomInviteNotEnoughPermission,
image: Asset.Images.addParticipants.image, room: room,
accessoryImage: canInviteToRoom ? Asset.Images.chevron.image : nil,
enabled: canInviteToRoom)
]
let coordinator = OptionListCoordinator(parameters: OptionListCoordinatorParameters(title: VectorL10n.roomIntroCellAddParticipantsAction, options: self.roomOptions, navigationRouter: self.navigationRouter))
coordinator.delegate = self
coordinator.start()
self.optionListCoordinator = coordinator
}
}
}
private func pushContactsPicker(for room: MXRoom) {
@@ -132,17 +149,48 @@ final class RoomParticipantsInviteCoordinatorBridgePresenter: NSObject {
return
}
let coordinator = ContactsPickerCoordinator(session: session,
room: room,
currentSearchText: currentSearchText,
actualParticipants: actualParticipants,
invitedParticipants: invitedParticipants,
userParticipant: userParticipant,
navigationRouter: navigationRouter)
coordinator.delegate = self
coordinator.start()
self.contactPickerCoordinator = coordinator
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)
}
}
}