Files
bundesmessenger-ios/Riot/Modules/ContextMenu/Services/RoomContextActionService.swift
JanNiklas Grabowski d07184c687 Merge commit 'ee6e5de4358a2c0a2705194cd954f9207ff772cf' into feature/5854_foss_merge
* commit 'ee6e5de4358a2c0a2705194cd954f9207ff772cf':
  finish version++
  version++
  Fix a bug where QR codes aren't detected if the camera is too close. (#7762)
  element-hq/element-meta/issues/2201 - Disable mark as unread - relates to element-hq/element-meta/issues/891 - relates to element-hq/element-ios/issues/7253
  Fix dictation when using the Rich Text Editor. (#7752)
  Prepare for new sprint
  finish version++
  version++
  changelog.d: Upgrade MatrixSDK version ([v0.27.6](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.27.6)).
  corrected translations
  Added translation using Weblate (Persian (Old))
  Translated using Weblate (Albanian)
  Translated using Weblate (Chinese (Simplified))
  Translated using Weblate (Chinese (Simplified))
  Translated using Weblate (Albanian)
  changelog
  fix
  Prepare for new sprint
  GH actions: remove triaging process and old GH projects

# Conflicts:
#	Config/AppVersion.xcconfig
#	Riot/Modules/ContextMenu/ActionProviders/RoomActionProvider.swift
2024-03-11 12:13:51 +01:00

238 lines
9.4 KiB
Swift

//
// Copyright 2022 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
/// `RoomContextActionService` implements all the possible actions for an instance of `MXRoom`
class RoomContextActionService: NSObject, RoomContextActionServiceProtocol {
// MARK: - RoomContextActionServiceProtocol
private(set) var session: MXSession
var roomId: String {
return room.roomId
}
internal weak var delegate: RoomContextActionServiceDelegate?
// MARK: - Properties
private let room: MXRoom
private let unownedRoomService: UnownedRoomContextActionService
// MARK: - Setup
init(room: MXRoom, delegate: RoomContextActionServiceDelegate?) {
self.room = room
self.delegate = delegate
self.isRoomJoined = room.summary?.isJoined ?? false
self.hasUnread = room.summary?.hasAnyUnread ?? false
self.roomMembership = room.summary?.membership ?? .unknown
self.session = room.mxSession
self.unownedRoomService = UnownedRoomContextActionService(roomId: room.roomId, canonicalAlias: room.summary?.aliases?.first, session: self.session, delegate: delegate)
}
// MARK: - Public
let isRoomJoined: Bool
let hasUnread: Bool
let roomMembership: MXMembership
var isRoomDirect: Bool {
get {
return room.isDirect
}
set {
delegate?.roomContextActionService(self, updateActivityIndicator: true)
room.setIsDirect(newValue, withUserId: nil) { [weak self] in
guard let self = self else { return }
self.delegate?.roomContextActionService(self, updateActivityIndicator: false)
} failure: { [weak self] error in
guard let self = self else { return }
self.delegate?.roomContextActionService(self, updateActivityIndicator: false)
// Notify the end user
if let userId = self.session.myUserId {
NotificationCenter.default.post(name: NSNotification.Name.mxkError, object: error, userInfo: [kMXKErrorUserIdKey: userId])
} else {
NotificationCenter.default.post(name: NSNotification.Name.mxkError, object: error)
}
}
}
}
var isRoomMuted: Bool {
get {
return room.isMuted || room.isMentionsOnly
}
set {
if BuildSettings.showNotificationsV2 {
self.delegate?.roomContextActionService(self, showRoomNotificationSettingsForRoomWithId: room.roomId)
} else {
self.muteRoomNotifications(newValue)
}
}
}
var isRoomFavourite: Bool {
get {
let currentTag = room.accountData.tags?.values.first
return currentTag?.name == kMXRoomTagFavourite
}
set {
self.updateRoom(tag: newValue ? kMXRoomTagFavourite : nil)
}
}
var isRoomLowPriority: Bool {
get {
let currentTag = room.accountData.tags?.values.first
return currentTag?.name == kMXRoomTagLowPriority
}
set {
self.updateRoom(tag: newValue ? kMXRoomTagLowPriority : nil)
}
}
func markAsRead() {
room.markAllAsRead()
self.delegate?.roomContextActionServiceDidMarkRoom(self)
}
func markAsUnread() {
room.setUnread()
self.delegate?.roomContextActionServiceDidMarkRoom(self)
}
// MARK: - Private
private func muteRoomNotifications(_ isMuted: Bool) {
self.delegate?.roomContextActionService(self, updateActivityIndicator: true)
if isMuted {
room.mentionsOnly { [weak self] in
guard let self = self else { return }
self.delegate?.roomContextActionService(self, updateActivityIndicator: false)
}
} else {
room.allMessages { [weak self] in
guard let self = self else { return }
self.delegate?.roomContextActionService(self, updateActivityIndicator: false)
}
}
}
private func updateRoom(tag: String?) {
self.delegate?.roomContextActionService(self, updateActivityIndicator: true)
room.setRoomTag(tag) {
self.delegate?.roomContextActionService(self, updateActivityIndicator: false)
}
}
func leaveRoom(promptUser: Bool) {
guard promptUser else {
self.leaveRoom()
return
}
// 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() {
unownedRoomService.joinRoom()
}
private func leaveRoom() {
self.delegate?.roomContextActionService(self, updateActivityIndicator: true)
// cancel pending uploads/downloads
// they are useless by now
MXMediaManager.cancelDownloads(inCacheFolder: self.room.roomId)
// TODO: GFO cancel pending uploads related to this room
MXLog.debug("[RoomContextActionService] leaving room \(self.room.roomId ?? "nil")")
self.room.leave { [weak self] response in
guard let self = self else { return }
switch response {
case .success:
self.delegate?.roomContextActionService(self, updateActivityIndicator: false)
self.delegate?.roomContextActionServiceDidLeaveRoom(self)
case .failure(let error):
self.delegate?.roomContextActionService(self, updateActivityIndicator: false)
// Notify the end user
if let userId = self.session.myUserId {
NotificationCenter.default.post(name: NSNotification.Name.mxkError, object: error, userInfo: [kMXKErrorUserIdKey: userId])
} else {
NotificationCenter.default.post(name: NSNotification.Name.mxkError, object: error)
}
}
}
}
// 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
}
}