mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-22 01:22:46 +02:00
b298dedc22
Merge commit 'f823ab9aae70e8d15ed7cc079210dd9bbbb6c8e1' into feature/foss_update_1_11_19 * commit 'f823ab9aae70e8d15ed7cc079210dd9bbbb6c8e1': finish version++ version++ comments update submodule remove obsolete tests removed unused code update submodule fix Libolm removal update license macro update license Prepare for new sprint # Conflicts: # Config/AppVersion.xcconfig # IDETemplateMacros.plist # LICENSE # README.md # Riot/Categories/MXSession+Riot.m # Riot/Managers/EncryptionKeyManager/EncryptionKeyManager.swift # Riot/Managers/KeyValueStorage/Extensions/Keychain.swift # Riot/Managers/KeyValueStorage/KeyValueStore.swift # Riot/Managers/KeyValueStorage/KeychainStore.swift # Riot/Managers/KeyValueStorage/MemoryStore.swift # Riot/Managers/PushNotification/PushNotificationService.m # Riot/Managers/Settings/RiotSettings.swift # Riot/Managers/Settings/Shared/RiotSharedSettings.swift # Riot/Modules/Analytics/AnalyticsUIElement.swift # Riot/Modules/Application/AppCoordinator.swift # Riot/Modules/Application/LegacyAppDelegate.h # Riot/Modules/Application/LegacyAppDelegate.m # Riot/Modules/Authentication/Legacy/AuthenticationViewController.h # Riot/Modules/Authentication/Legacy/AuthenticationViewController.m # Riot/Modules/Authentication/Legacy/Views/AuthInputsView.h # Riot/Modules/Authentication/Legacy/Views/AuthInputsView.m # Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m # Riot/Modules/Common/Recents/RecentsViewController.m # Riot/Modules/Common/WebViewController/WebViewViewController.m # Riot/Modules/Contacts/Details/ContactDetailsViewController.m # Riot/Modules/Contacts/Views/ContactTableViewCell.m # Riot/Modules/Favorites/FavouritesViewController.h # Riot/Modules/Favorites/FavouritesViewController.m # Riot/Modules/GlobalSearch/UnifiedSearchViewController.m # Riot/Modules/People/PeopleViewController.h # Riot/Modules/People/PeopleViewController.m # Riot/Modules/Room/ContextualMenu/ReactionsMenu/ReactionsMenuViewModel.swift # Riot/Modules/Room/DataSources/RoomDataSource.m # Riot/Modules/Room/Files/RoomFilesViewController.m # Riot/Modules/Room/Members/Detail/RoomMemberDetailsViewController.m # Riot/Modules/Room/Members/RoomParticipantsViewController.m # Riot/Modules/Room/RoomViewController.m # Riot/Modules/Room/Settings/RoomSettingsViewController.m # Riot/Modules/Room/TimelineCells/RoomCreationIntro/RoomCreationIntroCell.swift # Riot/Modules/Room/TimelineCells/RoomCreationIntro/RoomCreationIntroCellContentView.swift # Riot/Modules/Room/TimelineCells/RoomCreationIntro/RoomCreationIntroViewData.swift # Riot/Modules/Room/TimelineCells/RoomTimelineCellIdentifier.h # Riot/Modules/Rooms/RoomsViewController.h # Riot/Modules/Rooms/ShowDirectory/Cells/Network/DirectoryNetworkTableHeaderFooterView.swift # Riot/Modules/Rooms/ShowDirectory/Cells/Room/DirectoryRoomTableViewCell.swift # Riot/Modules/Rooms/ShowDirectory/PublicRoomsDirectoryViewModel.swift # Riot/Modules/Secrets/Recover/RecoverWithKey/SecretsRecoveryWithKeyCoordinator.swift # Riot/Modules/Secrets/Recover/RecoverWithKey/SecretsRecoveryWithKeyViewController.swift # Riot/Modules/Secrets/Recover/RecoverWithPassphrase/SecretsRecoveryWithPassphraseCoordinator.swift # Riot/Modules/Secrets/Recover/RecoverWithPassphrase/SecretsRecoveryWithPassphraseViewController.swift # Riot/Modules/Secrets/Recover/SecretsRecoveryCoordinator.swift # Riot/Modules/SecureBackup/Setup/Intro/SecureBackupSetupIntroViewController.swift # Riot/Modules/SecureBackup/Setup/Intro/SecureBackupSetupIntroViewModel.swift # Riot/Modules/SecureBackup/Setup/Intro/SecureBackupSetupIntroViewModelType.swift # Riot/Modules/SetPinCode/PinCodePreferences.swift # Riot/Modules/SetPinCode/SetupBiometrics/BiometricsAuthenticationPresenter.swift # Riot/Modules/Settings/Security/ManageSession/ManageSessionViewController.m # Riot/Modules/Settings/Security/SecurityViewController.m # Riot/Modules/Settings/SettingsViewController.m # Riot/Modules/SplitView/SplitViewCoordinator.swift # Riot/Modules/SplitView/SplitViewCoordinatorType.swift # Riot/Modules/StartChat/StartChatViewController.m # Riot/Modules/TabBar/MasterTabBarController.h # Riot/Modules/TabBar/MasterTabBarController.m # Riot/Utils/EventFormatter.m # Riot/Utils/HTMLFormatter.swift # Riot/Utils/Tools.m # RiotNSE/NotificationService.swift
201 lines
8.1 KiB
Swift
201 lines
8.1 KiB
Swift
//
|
|
// Copyright 2022-2024 New Vector Ltd.
|
|
//
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
// Please see LICENSE in the repository root for full details.
|
|
//
|
|
|
|
import UIKit
|
|
import MatrixSDK
|
|
|
|
enum AllChatsEditActionProviderOption {
|
|
case exploreRooms
|
|
case createRoom
|
|
case startChat
|
|
case createSpace
|
|
case scanPermalink
|
|
}
|
|
|
|
protocol AllChatsEditActionProviderDelegate: AnyObject {
|
|
func allChatsEditActionProvider(_ actionProvider: AllChatsEditActionProvider, didSelect option: AllChatsEditActionProviderOption)
|
|
}
|
|
|
|
/// `AllChatsEditActionProvider` provides the menu for accessing edit screens according to the current parent space
|
|
class AllChatsEditActionProvider {
|
|
|
|
// MARK: - Properties
|
|
|
|
weak var delegate: AllChatsEditActionProviderDelegate?
|
|
|
|
// MARK: - Private
|
|
|
|
private var rootSpaceCount: Int = 0
|
|
private var parentSpace: MXSpace? {
|
|
didSet {
|
|
parentName = parentSpace?.summary?.displayName ?? VectorL10n.spaceTag
|
|
}
|
|
}
|
|
private var parentName: String = VectorL10n.spaceTag
|
|
private var isInviteAvailable: Bool = false
|
|
private var isAddRoomAvailable: Bool = true
|
|
|
|
// MARK: - RoomActionProviderProtocol
|
|
|
|
var menu: UIMenu {
|
|
if BWIBuildSettings.shared.allowScanPermalinkQRCode {
|
|
guard parentSpace != nil else {
|
|
var createActions = [
|
|
self.exploreRoomsAction,
|
|
self.createRoomAction,
|
|
self.startChatAction
|
|
]
|
|
if rootSpaceCount > 0 && BWIBuildSettings.shared.enableSpaces {
|
|
createActions.insert(self.createSpaceAction, at: 0)
|
|
}
|
|
return UIMenu(title: "", children: [
|
|
self.scanPermalinkAction,
|
|
UIMenu(title: "", options: .displayInline, children: createActions)
|
|
])
|
|
}
|
|
|
|
return UIMenu(title: "", children: [
|
|
UIMenu(title: "", options: .displayInline, children: [
|
|
self.scanPermalinkAction
|
|
]),
|
|
UIMenu(title: "", options: .displayInline, children: [
|
|
self.exploreRoomsAction,
|
|
self.createSpaceAction,
|
|
self.createRoomAction
|
|
])
|
|
])
|
|
} else {
|
|
guard parentSpace != nil else {
|
|
var createActions = [
|
|
self.createRoomAction,
|
|
self.startChatAction
|
|
]
|
|
if rootSpaceCount > 0 && BWIBuildSettings.shared.enableSpaces {
|
|
createActions.insert(self.createSpaceAction, at: 0)
|
|
}
|
|
return UIMenu(title: "", children: [
|
|
self.exploreRoomsAction,
|
|
UIMenu(title: "", options: .displayInline, children: createActions)
|
|
])
|
|
}
|
|
|
|
return UIMenu(title: "", children: [
|
|
UIMenu(title: "", options: .displayInline, children: [
|
|
self.exploreRoomsAction
|
|
]),
|
|
UIMenu(title: "", options: .displayInline, children: [
|
|
self.createSpaceAction,
|
|
self.createRoomAction
|
|
])
|
|
])
|
|
}
|
|
}
|
|
|
|
// MARK: - Public
|
|
|
|
/// Indicates if the context menu should be updated accordingly to the given parameters.
|
|
///
|
|
/// If `shouldUpdate()` reutrns `true`, you should update the context menu by calling `updateMenu()`.
|
|
///
|
|
/// - Parameters:
|
|
/// - session: The current `MXSession` instance
|
|
/// - parentSpace: The current parent space (`nil` for home space)
|
|
/// - Returns: `true` if the context menu should be updated (call `updateMenu()` in this case). `false` otherwise
|
|
func shouldUpdate(with session: MXSession?, parentSpace: MXSpace?) -> Bool {
|
|
let rootSpaceCount = session?.spaceService.rootSpaces.count ?? 0
|
|
return parentSpace != self.parentSpace || (rootSpaceCount == 0 && self.rootSpaceCount > 0 || rootSpaceCount > 0 && self.rootSpaceCount == 0)
|
|
}
|
|
|
|
/// Returns an instance of the updated menu accordingly to the given parameters.
|
|
///
|
|
/// Some menu items can be disabled depending on the required power levels of the `parentSpace`. Therefore, `updateMenu()` first returns a temporary context menu
|
|
/// with all sensible items disabled, asynchronously fetches power levels of the `parentSpace`, then gives a new instance of the menu with, potentially, all sensible items
|
|
/// enabled via the `completion` callback.
|
|
///
|
|
/// - Parameters:
|
|
/// - session: The current `MXSession` instance
|
|
/// - parentSpace: The current parent space (`nil` for home space)
|
|
/// - completion: callback called once the power levels of the `parentSpace` have been fetched and the menu items have been computed accordingly.
|
|
/// - Returns: If the `parentSpace` is `nil`, the context menu, the temporary context menu otherwise.
|
|
func updateMenu(with session: MXSession?, parentSpace: MXSpace?, completion: @escaping (UIMenu) -> Void) -> UIMenu {
|
|
self.parentSpace = parentSpace
|
|
self.rootSpaceCount = session?.spaceService.rootSpaces.count ?? 0
|
|
isInviteAvailable = false
|
|
isAddRoomAvailable = parentSpace == nil
|
|
|
|
guard let parentSpace = parentSpace, let spaceRoom = parentSpace.room, let session = session else {
|
|
return self.menu
|
|
}
|
|
|
|
spaceRoom.state { [weak self] roomState in
|
|
guard let self = self else { return }
|
|
|
|
guard let powerLevels = roomState?.powerLevels, let userId = session.myUserId else {
|
|
return
|
|
}
|
|
let userPowerLevel = powerLevels.powerLevelOfUser(withUserID: userId)
|
|
|
|
self.isInviteAvailable = userPowerLevel >= powerLevels.invite
|
|
self.isAddRoomAvailable = userPowerLevel >= parentSpace.minimumPowerLevelForAddingRoom(with: powerLevels)
|
|
|
|
completion(self.menu)
|
|
}
|
|
|
|
return self.menu
|
|
}
|
|
|
|
// MARK: - Private
|
|
|
|
private var exploreRoomsAction: UIAction {
|
|
UIAction(title: parentSpace == nil ? BWIL10n.roomRecentsExploreRooms : VectorL10n.spacesExploreRoomsFormat(parentName),
|
|
image: Asset.Images.binoculars.image) { [weak self] action in
|
|
guard let self = self else { return }
|
|
|
|
self.delegate?.allChatsEditActionProvider(self, didSelect: .exploreRooms)
|
|
}
|
|
}
|
|
|
|
private var createRoomAction: UIAction {
|
|
UIAction(title: parentSpace == nil ? BWIL10n.roomRecentsCreateEmptyRoom : VectorL10n.spacesAddRoom,
|
|
image: UIImage(systemName: "person.3"),
|
|
attributes: isAddRoomAvailable ? [] : .disabled) { [weak self] action in
|
|
guard let self = self else { return }
|
|
|
|
self.delegate?.allChatsEditActionProvider(self, didSelect: .createRoom)
|
|
}
|
|
}
|
|
|
|
private var startChatAction: UIAction {
|
|
UIAction(title: BWIL10n.roomRecentsStartChatWith,
|
|
image: UIImage(systemName: "person")) { [weak self] action in
|
|
guard let self = self else { return }
|
|
|
|
self.delegate?.allChatsEditActionProvider(self, didSelect: .startChat)
|
|
}
|
|
}
|
|
|
|
private var createSpaceAction: UIAction {
|
|
UIAction(title: parentSpace == nil ? VectorL10n.spacesCreateSpaceTitle : VectorL10n.spacesCreateSubspaceTitle,
|
|
image: UIImage(systemName: "plus"),
|
|
attributes: isAddRoomAvailable ? [] : .disabled) { [weak self] action in
|
|
guard let self = self else { return }
|
|
|
|
self.delegate?.allChatsEditActionProvider(self, didSelect: .createSpace)
|
|
}
|
|
}
|
|
|
|
private var scanPermalinkAction: UIAction {
|
|
UIAction(title: BWIL10n.roomRecentsScanQrCode,
|
|
image: Asset.Images.qrcodeViewfinder.image) { [weak self] action in
|
|
guard let self = self else { return }
|
|
|
|
self.delegate?.allChatsEditActionProvider(self, didSelect: .scanPermalink)
|
|
}
|
|
}
|
|
|
|
}
|