From 0f22ac9855416c8cd398a403ffa61216eabe5ae4 Mon Sep 17 00:00:00 2001 From: JanNiklas Grabowski Date: Wed, 25 Jan 2023 11:06:00 +0000 Subject: [PATCH] MESSENGER-4039 new layout - add last admin function --- .../Services/RoomContextActionService.swift | 64 ++++++++++++--- .../RoomInfoList/RoomInfoListViewModel.swift | 53 +------------ bwi/LeaveRoom/LeaveRoomHelper.swift | 77 +++++++++++++++++++ 3 files changed, 133 insertions(+), 61 deletions(-) create mode 100644 bwi/LeaveRoom/LeaveRoomHelper.swift diff --git a/Riot/Modules/ContextMenu/Services/RoomContextActionService.swift b/Riot/Modules/ContextMenu/Services/RoomContextActionService.swift index c3abab55b..ecc36b4bc 100644 --- a/Riot/Modules/ContextMenu/Services/RoomContextActionService.swift +++ b/Riot/Modules/ContextMenu/Services/RoomContextActionService.swift @@ -140,15 +140,12 @@ class RoomContextActionService: NSObject, RoomContextActionServiceProtocol { return } - let title = room.isDirect ? VectorL10n.roomParticipantsLeavePromptTitleForDm : VectorL10n.roomParticipantsLeavePromptTitle - let message = room.isDirect ? VectorL10n.roomParticipantsLeavePromptMsgForDm : VectorL10n.roomParticipantsLeavePromptMsg - - let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) - alertController.addAction(UIAlertAction(title: VectorL10n.cancel, style: .cancel, handler: nil)) - alertController.addAction(UIAlertAction(title: VectorL10n.leave, style: .default, handler: { action in - self.leaveRoom() - })) - self.delegate?.roomContextActionService(self, presentAlert: alertController) + // bwi: admins can only leave if there is at least one other admin or the admin is the only member + if BWIBuildSettings.shared.lastAdminIsNotAllowedToLeaveRoom { + self.delegate?.roomContextActionService(self, presentAlert: self.getLeaveAlertController()) + } else { + self.delegate?.roomContextActionService(self, presentAlert: self.leaveAlertController) + } } func joinRoom() { @@ -183,4 +180,53 @@ class RoomContextActionService: NSObject, RoomContextActionServiceProtocol { } } } + + // MARK: bwi leave room alerts + private lazy var leaveAlertController: UIAlertController = { + var title = self.isRoomDirect ? VectorL10n.roomParticipantsLeavePromptTitleForDm : VectorL10n.roomParticipantsLeavePromptTitle + var message = self.isRoomDirect ? VectorL10n.roomParticipantsLeavePromptMsgForDm : VectorL10n.roomParticipantsLeavePromptMsg + + let controller = UIAlertController(title: title, message: message, 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.leaveRoom() + })) + controller.mxk_setAccessibilityIdentifier("RoomContextActionServiceAlert") + + return controller + }() + + private func getLeaveAlertController() -> UIAlertController { + if LeaveRoomHelper.canLeaveRoom(self.session, self.room) { + let title = self.isRoomDirect ? VectorL10n.roomParticipantsLeavePromptTitleForDm : VectorL10n.roomParticipantsLeavePromptTitle + let message = self.isRoomDirect ? VectorL10n.roomParticipantsLeavePromptMsgForDm : VectorL10n.roomParticipantsLeavePromptMsg + + let controller = UIAlertController(title: title, message: message, 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.leaveRoom() + })) + controller.mxk_setAccessibilityIdentifier("RoomContextActionServiceAlert") + + return controller + } else { + return self.doNotLeaveUIAlertController() + } + } + + private func doNotLeaveUIAlertController() -> UIAlertController { + let title = VectorL10n.roomParticipantsLeavePromptTitle + let message = BWIL10n.roomParticipantsCantLeavePromptMessage + let controller = UIAlertController(title: title, message: message, preferredStyle: .alert) + + controller.addAction(UIAlertAction(title: VectorL10n.cancel, style: .cancel, handler: nil)) + controller.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil)) + controller.mxk_setAccessibilityIdentifier("RoomContextActionServiceAlert") + + return controller + } } diff --git a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModel.swift b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModel.swift index 35820d716..3010c5148 100644 --- a/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModel.swift +++ b/Riot/Modules/Room/RoomInfo/RoomInfoList/RoomInfoListViewModel.swift @@ -86,33 +86,7 @@ final class RoomInfoListViewModel: NSObject, RoomInfoListViewModelType { } func canLeaveRoom() -> Bool { - let myUserId = self.session.myUserId - - // None Admins can always leave the room - if !self.isAdmin(self.session.myUserId) { - return true - } - - var canLeave = false - - // admins can only leave if there is at least one other admin - self.room.state { (state) in - if let members = state?.members.joinedMembers { - for user in members where user.userId != myUserId { - if self.isAdmin(user.userId) { - canLeave = true - break - } - } - } - } - - // A single admin can leave the room if he is the only member - if !canLeave && self.isOnlyMember() { - canLeave = true - } - - return canLeave + return LeaveRoomHelper.canLeaveRoom(self.session, self.room) } func isDirectRoom() -> Bool { @@ -131,34 +105,9 @@ final class RoomInfoListViewModel: NSObject, RoomInfoListViewModelType { return !(isDirectRoom() || isPersonalNotesRoom() || isInviteOnlyRoom()) } - func isOnlyMember() -> Bool { - var memberCount = 0 - - self.room.state { (state) in - if let members = state?.members.joinedMembers { - memberCount = members.count - } - } - return (memberCount == 1) - } // MARK: - Private - private func isAdmin(_ userId: String) -> Bool { - var admin = false - - self.room.state { (state) in - let powerLevels = state?.powerLevels - let userPowerLevel = powerLevels?.powerLevelOfUser(withUserID: userId) - let roomPowerLevel = RoomPowerLevelHelper.roomPowerLevel(from: userPowerLevel ?? RoomPowerLevel.user.rawValue) - - if roomPowerLevel == RoomPowerLevel.admin { - admin = true - } - } - - return admin - } private func startObservingSummaryChanges() { NotificationCenter.default.addObserver(self, selector: #selector(roomSummaryUpdated(_:)), name: .mxRoomSummaryDidChange, object: room.summary) diff --git a/bwi/LeaveRoom/LeaveRoomHelper.swift b/bwi/LeaveRoom/LeaveRoomHelper.swift new file mode 100644 index 000000000..7c1c24b11 --- /dev/null +++ b/bwi/LeaveRoom/LeaveRoomHelper.swift @@ -0,0 +1,77 @@ +// +/* + * Copyright (c) 2023 BWI GmbH + * + * 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 + +final class LeaveRoomHelper { + + static func canLeaveRoom(_ session: MXSession, _ room: MXRoom) -> Bool { + let myUserId = session.myUserId + + // None Admins can always leave the room + if !self.isAdmin(session.myUserId, room) { + return true + } + + var canLeave = false + + // admins can only leave if there is at least one other admin + room.state { (state) in + if let members = state?.members.joinedMembers { + for user in members where user.userId != myUserId { + if self.isAdmin(user.userId, room) { + canLeave = true + break + } + } + } + } + // A single admin can leave the room if he is the only member + if !canLeave && self.isOnlyMember(room) { + canLeave = true + } + + return canLeave + } + + static private func isAdmin(_ userId: String, _ room: MXRoom) -> Bool { + var admin = false + + room.state { (state) in + let powerLevels = state?.powerLevels + let userPowerLevel = powerLevels?.powerLevelOfUser(withUserID: userId) + let roomPowerLevel = RoomPowerLevelHelper.roomPowerLevel(from: userPowerLevel ?? RoomPowerLevel.user.rawValue) + + if roomPowerLevel == RoomPowerLevel.admin { + admin = true + } + } + + return admin + } + + static func isOnlyMember(_ room: MXRoom) -> Bool { + var memberCount = 0 + + room.state { (state) in + if let members = state?.members.joinedMembers { + memberCount = members.count + } + } + return (memberCount == 1) + } +}