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
@@ -34,6 +34,7 @@ enum RoomDetailsScreenCoordinatorAction {
case presentKnockingRequestsListScreen
case presentSecurityAndPrivacyScreen
case presentReportRoomScreen
case transferOwnership
}
final class RoomDetailsScreenCoordinator: CoordinatorProtocol {
@@ -94,6 +95,8 @@ final class RoomDetailsScreenCoordinator: CoordinatorProtocol {
actionsSubject.send(.presentRecipientDetails(userID: userID))
case .displayReportRoom:
actionsSubject.send(.presentReportRoomScreen)
case .transferOwnership:
actionsSubject.send(.transferOwnership)
}
}
.store(in: &cancellables)
@@ -27,6 +27,7 @@ enum RoomDetailsScreenViewModelAction: Equatable {
case displayKnockingRequests
case displaySecurityAndPrivacy
case displayReportRoom
case transferOwnership
}
// MARK: View
@@ -288,6 +289,8 @@ enum RoomDetailsScreenErrorType: Hashable {
case alert
/// Leaving room has failed..
case unknown
/// Last owner
case lastOwner
}
enum RoomDetailsScreenPinnedEventsActionState {
@@ -119,13 +119,7 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
case .processTapInvite:
actionsSubject.send(.requestInvitePeoplePresentation)
case .processTapLeave:
guard state.joinedMembersCount > 1 else {
state.bindings.leaveRoomAlertItem = LeaveRoomAlertItem(roomID: roomProxy.id, isDM: roomProxy.isDirectOneToOneRoom, state: .empty)
return
}
state.bindings.leaveRoomAlertItem = LeaveRoomAlertItem(roomID: roomProxy.id,
isDM: roomProxy.isDirectOneToOneRoom,
state: roomProxy.infoPublisher.value.isPrivate ?? true ? .private : .public)
processTapToLeave()
case .confirmLeave:
Task { await leaveRoom() }
case .processTapIgnore:
@@ -177,6 +171,38 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
// MARK: - Private
private func processTapToLeave() {
guard state.joinedMembersCount > 1 else {
state.bindings.leaveRoomAlertItem = LeaveRoomAlertItem(roomID: roomProxy.id,
isDM: roomProxy.isDirectOneToOneRoom,
state: roomProxy.infoPublisher.value.isPrivate ?? true ? .empty : .public)
return
}
if !roomProxy.isDirectOneToOneRoom, state.accountOwner?.role.isOwner == true {
var isLastOwner = true
for member in roomProxy.membersPublisher.value where member.userID != roomProxy.ownUserID {
if member.role.isOwner {
isLastOwner = false
break
}
}
if isLastOwner {
state.bindings.alertInfo = .init(id: .lastOwner,
title: L10n.leaveRoomAlertSelectNewOwnerTitle,
message: L10n.leaveRoomAlertSelectNewOwnerSubtitle,
primaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil),
secondaryButton: .init(title: L10n.leaveRoomAlertSelectNewOwnerAction, role: .destructive, action: { [weak self] in self?.actionsSubject.send(.transferOwnership) }))
return
}
}
state.bindings.leaveRoomAlertItem = LeaveRoomAlertItem(roomID: roomProxy.id,
isDM: roomProxy.isDirectOneToOneRoom,
state: roomProxy.infoPublisher.value.isPrivate ?? true ? .private : .public)
}
private func setupRoomSubscription() {
roomProxy.infoPublisher
.receive(on: DispatchQueue.main)
@@ -237,11 +263,6 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
}
private func fetchMembersIfNeeded() async {
// We need to fetch members just in 1-to-1 chat to get the member object for the other person
guard roomProxy.isDirectOneToOneRoom else {
return
}
roomProxy.membersPublisher
.receive(on: DispatchQueue.main)
.sink { [weak self, ownUserID = roomProxy.ownUserID] members in
@@ -251,6 +272,10 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
self.state.accountOwner = .init(withProxy: accountOwner)
}
guard roomProxy.isDirectOneToOneRoom else {
return
}
if let dmRecipient = members.first(where: { $0.userID != ownUserID }) {
self.state.dmRecipientInfo = .init(member: .init(withProxy: dmRecipient))