* Use the via property on SpaceRoom. * Fall back to the canonical alias as a space room name if needs be. * Use SpaceRoom.isDirect for computing the name/avatar. * Pass in the parent space as a workaround for no restricted join rules.
78 lines
3.0 KiB
Swift
78 lines
3.0 KiB
Swift
//
|
|
// 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 Combine
|
|
import Foundation
|
|
import MatrixRustSDK
|
|
|
|
class SpaceServiceProxy: SpaceServiceProxyProtocol {
|
|
private let spaceService: SpaceServiceProtocol
|
|
|
|
private var joinedSpacesHandle: TaskHandle?
|
|
private let spacesSubject = CurrentValueSubject<[SpaceRoomProxyProtocol], Never>([])
|
|
var joinedSpacesPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never> {
|
|
spacesSubject.asCurrentValuePublisher()
|
|
}
|
|
|
|
init(spaceService: SpaceServiceProtocol) {
|
|
self.spaceService = spaceService
|
|
|
|
Task { await setupSubscriptions() }
|
|
}
|
|
|
|
private func setupSubscriptions() async {
|
|
joinedSpacesHandle = await spaceService.subscribeToJoinedSpaces(listener: SDKListener { [weak self] updates in
|
|
self?.handleUpdates(updates)
|
|
})
|
|
}
|
|
|
|
// The parent here is temporary until we get the restricted AllowRules from the server.
|
|
func spaceRoomList(spaceID: String, parent: SpaceRoomProxyProtocol?) async -> Result<SpaceRoomListProxyProtocol, SpaceServiceProxyError> {
|
|
do {
|
|
return try await .success(SpaceRoomListProxy(spaceService.spaceRoomList(spaceId: spaceID), parent: parent))
|
|
} catch {
|
|
MXLog.error("Failed creating space room list for \(spaceID): \(error)")
|
|
return .failure(.sdkError(error))
|
|
}
|
|
}
|
|
|
|
// MARK: - Private
|
|
|
|
private func handleUpdates(_ updates: [SpaceListUpdate]) {
|
|
var spaces = spacesSubject.value
|
|
|
|
for update in updates {
|
|
switch update {
|
|
case .append(let spaceRooms):
|
|
spaces.append(contentsOf: spaceRooms.map { SpaceRoomProxy(spaceRoom: $0, parent: nil) })
|
|
case .clear:
|
|
spaces.removeAll()
|
|
case .pushFront(let spaceRoom):
|
|
spaces.insert(SpaceRoomProxy(spaceRoom: spaceRoom, parent: nil), at: 0)
|
|
case .pushBack(let spaceRoom):
|
|
spaces.append(SpaceRoomProxy(spaceRoom: spaceRoom, parent: nil))
|
|
case .popFront:
|
|
spaces.removeFirst()
|
|
case .popBack:
|
|
spaces.removeLast()
|
|
case .insert(let index, let spaceRoom):
|
|
spaces.insert(SpaceRoomProxy(spaceRoom: spaceRoom, parent: nil), at: Int(index))
|
|
case .set(let index, let spaceRoom):
|
|
spaces[Int(index)] = SpaceRoomProxy(spaceRoom: spaceRoom, parent: nil)
|
|
case .remove(let index):
|
|
spaces.remove(at: Int(index))
|
|
case .truncate(let length):
|
|
spaces.removeSubrange(Int(length)..<spaces.count)
|
|
case .reset(let spaceRooms):
|
|
spaces = spaceRooms.map { SpaceRoomProxy(spaceRoom: $0, parent: nil) }
|
|
}
|
|
}
|
|
|
|
spacesSubject.send(spaces)
|
|
}
|
|
}
|