mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Implement the flow for leaving a space. (#4568)
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// Copyright 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
|
||||
|
||||
class LeaveSpaceHandleProxy: Identifiable {
|
||||
let id: String
|
||||
let leaveHandle: LeaveSpaceHandleProtocol
|
||||
var rooms: [LeaveSpaceRoomDetails]
|
||||
|
||||
enum Mode { case manyRooms, onlyAdminRooms, noRooms }
|
||||
let mode: Mode
|
||||
|
||||
init(spaceID: String, leaveHandle: LeaveSpaceHandleProtocol) {
|
||||
id = spaceID
|
||||
self.leaveHandle = leaveHandle
|
||||
|
||||
rooms = leaveHandle.rooms()
|
||||
.compactMap { room in
|
||||
guard room.spaceRoom.state == .joined, // The SDK is going to do this but not yet.
|
||||
room.spaceRoom.isDirect != true,
|
||||
room.spaceRoom.roomId != spaceID else {
|
||||
return nil
|
||||
}
|
||||
return .init(spaceRoomProxy: SpaceRoomProxy(spaceRoom: room.spaceRoom, parent: nil),
|
||||
isLastAdmin: room.isLastAdmin,
|
||||
isSelected: !room.isLastAdmin)
|
||||
}
|
||||
|
||||
mode = if rooms.isEmpty {
|
||||
.noRooms
|
||||
} else if rooms.count(where: { !$0.isLastAdmin }) == 0 {
|
||||
.onlyAdminRooms
|
||||
} else {
|
||||
.manyRooms
|
||||
}
|
||||
}
|
||||
|
||||
func leave() async -> Result<Void, SpaceServiceProxyError> {
|
||||
let selectedRoomIDs = rooms.filter(\.isSelected).map(\.spaceRoomProxy.id)
|
||||
|
||||
do {
|
||||
return try await .success(leaveHandle.leave(roomIds: selectedRoomIDs + [id]))
|
||||
} catch {
|
||||
MXLog.error("Failed leaving space \(id): \(error)")
|
||||
rooms = rooms.filter { leaveRoom in
|
||||
leaveHandle.rooms().contains { $0.spaceRoom.roomId == leaveRoom.spaceRoomProxy.id }
|
||||
}
|
||||
return .failure(.sdkError(error))
|
||||
}
|
||||
}
|
||||
|
||||
var selectedCount: Int { rooms.count { $0.isSelected } }
|
||||
|
||||
var confirmationTitle: String {
|
||||
let selectedCount = selectedCount
|
||||
return selectedCount > 0 ? L10n.screenLeaveSpaceSubmit(selectedCount) : L10n.actionLeaveSpace
|
||||
}
|
||||
}
|
||||
|
||||
@Observable class LeaveSpaceRoomDetails {
|
||||
let spaceRoomProxy: SpaceRoomProxyProtocol
|
||||
let isLastAdmin: Bool
|
||||
var isSelected: Bool
|
||||
|
||||
init(spaceRoomProxy: SpaceRoomProxyProtocol, isLastAdmin: Bool, isSelected: Bool) {
|
||||
self.spaceRoomProxy = spaceRoomProxy
|
||||
self.isLastAdmin = isLastAdmin
|
||||
self.isSelected = isSelected
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,15 @@ class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
func leaveSpace(spaceID: String) async -> Result<LeaveSpaceHandleProxy, SpaceServiceProxyError> {
|
||||
do {
|
||||
return try await .success(.init(spaceID: spaceID, leaveHandle: spaceService.leaveSpace(spaceId: spaceID)))
|
||||
} catch {
|
||||
MXLog.error("Failed to get leave handle for \(spaceID): \(error)")
|
||||
return .failure(.sdkError(error))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func handleUpdates(_ updates: [SpaceListUpdate]) {
|
||||
|
||||
@@ -17,4 +17,5 @@ protocol SpaceServiceProxyProtocol {
|
||||
var joinedSpacesPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never> { get }
|
||||
|
||||
func spaceRoomList(spaceID: String, parent: SpaceRoomProxyProtocol?) async -> Result<SpaceRoomListProxyProtocol, SpaceServiceProxyError>
|
||||
func leaveSpace(spaceID: String) async -> Result<LeaveSpaceHandleProxy, SpaceServiceProxyError>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user