// // Copyright 2025 Element Creations Ltd. // Copyright 2024-2025 New Vector Ltd. // // SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. // Please see LICENSE files in the repository root for full details. // import Foundation import MatrixRustSDK struct RoomPermissionsSetting: Identifiable { static let allValues: [(title: String, tag: RoomRole)] = [(title: L10n.screenRoomChangePermissionsAdministrators, tag: .administrator), (title: L10n.screenRoomChangePermissionsModerators, tag: .moderator), (title: L10n.screenRoomChangePermissionsEveryone, tag: .user)] var id: KeyPath { keyPath } /// The title of this setting. let title: String /// The selected role of this setting. var value: Int64 let ownPowerLevel: RoomPowerLevel var roleValue: RoomRole { get { RoomRole(powerLevelValue: value) } set { value = newValue.powerLevelValue } } /// The `RoomPermissions` property that this setting is for. let keyPath: KeyPath /// The `RoomPowerLevelChanges` properties that this setting is saved into. var rustKeyPaths: Set> { switch keyPath { case \.ban: [\.ban] case \.invite: [\.invite] case \.kick: [\.kick] case \.redact: [\.redact] case \.eventsDefault: [\.eventsDefault] case \.stateDefault: [\.stateDefault] case \.usersDefault: [\.usersDefault] case \.roomName: [\.roomName] case \.roomAvatar: [\.roomAvatar] case \.roomTopic: [\.roomTopic] case \.spaceChild: [\.spaceChild] case \.liveLocation: [\.beacon, \.beaconInfo] default: fatalError("Unexpected key path: \(keyPath)") } } /// Can the setting be edited var isDisabled: Bool { switch ownPowerLevel { case .value(let ownValue): ownValue < value case .infinite: false } } /// All of the available roles that this setting can be configured with. var availableValues: [(title: String, tag: RoomRole)] { if isDisabled { Self.allValues.filter { $0.tag == RoomRole(powerLevelValue: value) } } else { Self.allValues.filter { $0.tag <= ownPowerLevel.role } } } } struct RoomPermissions { /// The level required to ban a user. var ban: Int64 /// The level required to invite a user. var invite: Int64 /// The level required to kick a user. var kick: Int64 /// The level required to redact an event. var redact: Int64 /// The default level required to send message events. var eventsDefault: Int64 /// The default level required to send state events. var stateDefault: Int64 /// The default power level for every user in the room. var usersDefault: Int64 /// The level required to change the room's name. var roomName: Int64 /// The level required to change the room's avatar. var roomAvatar: Int64 /// The level required to change the room's topic. var roomTopic: Int64 /// The level required to add/remove childrens from a space. var spaceChild: Int64 /// The level required to send live location updates var liveLocation: Int64 } extension RoomPermissions { /// Create permissions from the room's power levels. init(powerLevels: RoomPowerLevelsValues) { ban = powerLevels.ban invite = powerLevels.invite kick = powerLevels.kick redact = powerLevels.redact eventsDefault = powerLevels.eventsDefault stateDefault = powerLevels.stateDefault usersDefault = powerLevels.usersDefault roomName = powerLevels.roomName roomAvatar = powerLevels.roomAvatar roomTopic = powerLevels.roomTopic spaceChild = powerLevels.spaceChild liveLocation = max(powerLevels.beacon, powerLevels.beaconInfo) } }