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
@@ -20,22 +20,19 @@ class RoomChangeRolesScreenViewModel: RoomChangeRolesScreenViewModelType, RoomCh
actionsSubject.eraseToAnyPublisher()
}
init(mode: RoomMemberDetails.Role,
init(mode: RoomRole,
roomProxy: JoinedRoomProxyProtocol,
mediaProvider: MediaProviderProtocol,
userIndicatorController: UserIndicatorControllerProtocol,
analytics: AnalyticsService) {
guard mode != .user else { fatalError("Invalid screen configuration: \(mode)") }
guard mode != .user || mode != .creator else { fatalError("Invalid screen configuration: \(mode)") }
self.roomProxy = roomProxy
self.userIndicatorController = userIndicatorController
self.analytics = analytics
super.init(initialViewState: RoomChangeRolesScreenViewState(mode: mode,
administrators: [],
moderators: [],
users: [],
bindings: .init()),
ownRole: roomProxy.membersPublisher.value.first { $0.userID == roomProxy.id }?.role ?? .administrator),
mediaProvider: mediaProvider)
roomProxy.membersPublisher
@@ -64,11 +61,16 @@ class RoomChangeRolesScreenViewModel: RoomChangeRolesScreenViewModelType, RoomCh
case .demoteMember(let member):
demoteMember(member)
case .save:
if state.mode.isAdminOrHigher, !state.membersToPromote.isEmpty {
showPromotionWarning()
} else {
Task { await save() }
if !state.membersToPromote.isEmpty {
if state.mode == .administrator, state.ownRole == .administrator {
showPromotionWarning()
return
} else if state.mode == .owner {
showTransferOwnershipWarning()
return
}
}
Task { await save() }
case .cancel:
confirmDiscardChanges()
}
@@ -77,17 +79,23 @@ class RoomChangeRolesScreenViewModel: RoomChangeRolesScreenViewModelType, RoomCh
// MARK: - Private
private func updateMembers(_ members: [RoomMemberProxyProtocol]) {
var owners = [RoomMemberDetails]()
var administrators = [RoomMemberDetails]()
var moderators = [RoomMemberDetails]()
var users = [RoomMemberDetails]()
for member in members.sorted() {
if member.userID == roomProxy.ownUserID {
state.ownRole = member.role
}
guard member.isActive else { continue }
let memberDetails = RoomMemberDetails(withProxy: member)
switch member.role {
// TODO: Create a owner list
case .administrator, .creator:
switch memberDetails.role {
case .creator, .owner:
owners.append(memberDetails)
case .administrator:
administrators.append(memberDetails)
case .moderator:
moderators.append(memberDetails)
@@ -96,6 +104,7 @@ class RoomChangeRolesScreenViewModel: RoomChangeRolesScreenViewModelType, RoomCh
}
}
state.owners = owners
state.administrators = administrators
state.moderators = moderators
state.users = users
@@ -107,9 +116,9 @@ class RoomChangeRolesScreenViewModel: RoomChangeRolesScreenViewModelType, RoomCh
} else if state.membersToDemote.contains(member) {
state.membersToDemote.remove(member)
state.lastPromotedMember = member
} else if member.role == state.mode {
} else if member.role >= state.mode, member.role <= state.maxDemotableRole {
state.membersToDemote.insert(member)
} else {
} else if member.role < state.mode {
state.membersToPromote.insert(member)
state.lastPromotedMember = member
}
@@ -133,6 +142,16 @@ class RoomChangeRolesScreenViewModel: RoomChangeRolesScreenViewModelType, RoomCh
secondaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil))
}
private func showTransferOwnershipWarning() {
context.alertInfo = AlertInfo(id: .transferOwnershipWarning,
title: L10n.screenRoomChangeRoleConfirmChangeOwnersTitle,
message: L10n.screenRoomChangeRoleConfirmChangeOwnersDescription,
primaryButton: .init(title: L10n.actionContinue, role: .destructive) {
Task { await self.save() }
},
secondaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil))
}
private func save() async {
showSavingIndicator()