Last Owner should edit admins, and not leave when is last (#4372)

This commit is contained in:
Mauro
2025-08-07 10:40:14 +02:00
committed by GitHub
parent be525e6a60
commit 5ab6f90863
67 changed files with 691 additions and 363 deletions
@@ -14,15 +14,19 @@ enum RoomChangeRolesScreenViewModelAction {
struct RoomChangeRolesScreenViewState: BindableState {
/// The screen's current mode (which role we are promoting/demoting users to/from.
let mode: RoomMemberDetails.Role
let mode: RoomRole
/// The current user's role.
var ownRole: RoomRole
/// All of the room's members who are currently owners or creators.
var owners: [RoomMemberDetails] = []
/// All of the room's members who are currently admins.
var administrators: [RoomMemberDetails]
var administrators: [RoomMemberDetails] = []
/// All of the room's members who are currently moderators.
var moderators: [RoomMemberDetails]
var moderators: [RoomMemberDetails] = []
/// All of the room's members who are currently neither an admin or moderator.
var users: [RoomMemberDetails]
var users: [RoomMemberDetails] = []
var bindings: RoomChangeRolesScreenViewStateBindings
var bindings = RoomChangeRolesScreenViewStateBindings()
/// The members selected for promotion to the current role.
var membersToPromote: Set<RoomMemberDetails> = []
@@ -35,9 +39,17 @@ struct RoomChangeRolesScreenViewState: BindableState {
/// The screen's title.
var title: String {
switch mode {
case .creator, .owner, .administrator:
// TODO: Handle the creator permissions change
L10n.screenRoomChangeRoleAdministratorsTitle
case .creator:
"" // The screen can't be configured with this role.
case .owner:
L10n.screenRoomChangeRoleOwnersTitle
case .administrator:
switch ownRole {
case .creator:
L10n.screenRoomChangeRoleAdministratorsOrOwnersTitle
default:
L10n.screenRoomChangeRoleAdministratorsTitle
}
case .moderator:
L10n.screenRoomChangeRoleModeratorsTitle
case .user:
@@ -45,6 +57,10 @@ struct RoomChangeRolesScreenViewState: BindableState {
}
}
var visibleOwners: [RoomMemberDetails] {
owners.filter { $0.matches(searchQuery: bindings.searchQuery) }
}
/// The visible admins in the screen (after searching).
var visibleAdministrators: [RoomMemberDetails] {
administrators.filter { $0.matches(searchQuery: bindings.searchQuery) }
@@ -62,7 +78,8 @@ struct RoomChangeRolesScreenViewState: BindableState {
/// All of the members who will gain/keep this screen's role after saving any changes.
var membersWithRole: [RoomMemberDetails] {
administrators.filter(isMemberSelected) + moderators.filter(isMemberSelected) + users.filter(isMemberSelected)
let members = owners + administrators + moderators + users
return members.filter(isMemberSelected)
}
/// Whether or not any changes have been made to the members.
@@ -78,7 +95,31 @@ struct RoomChangeRolesScreenViewState: BindableState {
/// Whether or not a specific member has this screen's role.
func isMemberSelected(_ member: RoomMemberDetails) -> Bool {
guard !membersToDemote.contains(member) else { return false }
return member.role == mode || membersToPromote.contains(member)
return member.role >= mode || membersToPromote.contains(member)
}
func isMemberDisabled(_ member: RoomMemberDetails) -> Bool {
member.role > maxDemotableRole
}
var maxDemotableRole: RoomRole {
switch mode {
case .owner:
return .owner
case .administrator:
switch ownRole {
case .owner:
return .administrator
case .creator:
return .owner
default:
return .moderator
}
case .moderator:
return .moderator
default:
return .user
}
}
}
@@ -91,6 +132,8 @@ struct RoomChangeRolesScreenViewStateBindings {
enum RoomChangeRolesScreenAlertType {
/// A warning that a particular promotion can't be undone.
case promotionWarning
/// A warning that ownership transfer is final when the room is left.
case transferOwnershipWarning
/// A confirmation that the user would like to discard any unsaved changes.
case discardChanges
/// The generic error message.