mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Use the SDK's SpaceService, SpaceRoom and SpaceRoomList. (#4455)
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// 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 MatrixRustSDK
|
||||
|
||||
class SpaceRoomListProxy: SpaceRoomListProxyProtocol {
|
||||
private let spaceRoomList: SpaceRoomListProtocol
|
||||
let spaceRoomProxy: SpaceRoomProxyProtocol
|
||||
|
||||
private var spaceRoomsHandle: TaskHandle?
|
||||
private let spaceRoomsSubject = CurrentValueSubject<[SpaceRoomProxyProtocol], Never>([])
|
||||
var spaceRoomsPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never> {
|
||||
spaceRoomsSubject.asCurrentValuePublisher()
|
||||
}
|
||||
|
||||
private let paginationStateHandle: TaskHandle
|
||||
let paginationStatePublisher: CurrentValuePublisher<SpaceRoomListPaginationState, Never>
|
||||
|
||||
init(_ spaceRoomList: SpaceRoomListProtocol, spaceRoomProxy: SpaceRoomProxyProtocol) {
|
||||
self.spaceRoomList = spaceRoomList
|
||||
self.spaceRoomProxy = spaceRoomProxy
|
||||
|
||||
let paginationStateSubject = CurrentValueSubject<SpaceRoomListPaginationState, Never>(spaceRoomList.paginationState())
|
||||
paginationStatePublisher = paginationStateSubject.asCurrentValuePublisher()
|
||||
|
||||
paginationStateHandle = spaceRoomList.subscribeToPaginationStateUpdates(listener: SDKListener { paginationState in
|
||||
paginationStateSubject.send(paginationState)
|
||||
})
|
||||
|
||||
spaceRoomsHandle = spaceRoomList.subscribeToRoomUpdate(listener: SDKListener { [weak self] updates in
|
||||
self?.handleUpdates(updates)
|
||||
})
|
||||
}
|
||||
|
||||
func paginate() async {
|
||||
do {
|
||||
try await spaceRoomList.paginate()
|
||||
} catch {
|
||||
MXLog.error("Pagination failure: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func handleUpdates(_ updates: [SpaceListUpdate]) {
|
||||
var rooms = spaceRoomsSubject.value
|
||||
|
||||
for update in updates {
|
||||
switch update {
|
||||
case .append(let spaceRooms):
|
||||
rooms.append(contentsOf: spaceRooms.map(SpaceRoomProxy.init))
|
||||
case .clear:
|
||||
rooms.removeAll()
|
||||
case .pushFront(let spaceRoom):
|
||||
rooms.insert(SpaceRoomProxy(spaceRoom: spaceRoom), at: 0)
|
||||
case .pushBack(let spaceRoom):
|
||||
rooms.append(SpaceRoomProxy(spaceRoom: spaceRoom))
|
||||
case .popFront:
|
||||
rooms.removeFirst()
|
||||
case .popBack:
|
||||
rooms.removeLast()
|
||||
case .insert(let index, let spaceRoom):
|
||||
rooms.insert(SpaceRoomProxy(spaceRoom: spaceRoom), at: Int(index))
|
||||
case .set(let index, let spaceRoom):
|
||||
rooms[Int(index)] = SpaceRoomProxy(spaceRoom: spaceRoom)
|
||||
case .remove(let index):
|
||||
rooms.remove(at: Int(index))
|
||||
case .truncate(let length):
|
||||
rooms.removeSubrange(Int(length)..<rooms.count)
|
||||
case .reset(let spaceRooms):
|
||||
rooms = spaceRooms.map(SpaceRoomProxy.init)
|
||||
}
|
||||
}
|
||||
|
||||
spaceRoomsSubject.send(rooms)
|
||||
}
|
||||
}
|
||||
@@ -8,18 +8,12 @@
|
||||
import Combine
|
||||
import MatrixRustSDK
|
||||
|
||||
// Temporary until the SDK is updated.
|
||||
enum SpaceRoomListProxyPaginationState: Equatable {
|
||||
case idle(endReached: Bool)
|
||||
case loading
|
||||
}
|
||||
|
||||
// sourcery: AutoMockable
|
||||
protocol SpaceRoomListProxyProtocol {
|
||||
var spaceRoom: SpaceRoomProxyProtocol { get }
|
||||
var spaceRoomProxy: SpaceRoomProxyProtocol { get }
|
||||
|
||||
var spaceRoomsPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never> { get }
|
||||
var paginationStatePublisher: CurrentValuePublisher<SpaceRoomListProxyPaginationState, Never> { get }
|
||||
var paginationStatePublisher: CurrentValuePublisher<SpaceRoomListPaginationState, Never> { get }
|
||||
|
||||
func paginate() async
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
//
|
||||
// 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 SpaceRoomProxy: SpaceRoomProxyProtocol {
|
||||
private let spaceRoom: SpaceRoom
|
||||
|
||||
init(spaceRoom: SpaceRoom) {
|
||||
self.spaceRoom = spaceRoom
|
||||
}
|
||||
|
||||
lazy var id = spaceRoom.roomId
|
||||
var name: String? { spaceRoom.name }
|
||||
var avatarURL: URL? { spaceRoom.avatarUrl.flatMap(URL.init) }
|
||||
|
||||
var isSpace: Bool { spaceRoom.roomType == .space }
|
||||
var childrenCount: Int { Int(spaceRoom.childrenCount) }
|
||||
|
||||
var joinedMembersCount: Int { Int(spaceRoom.numJoinedMembers) }
|
||||
var heroes: [UserProfileProxy] { (spaceRoom.heroes ?? []).map(UserProfileProxy.init) }
|
||||
var topic: String? { spaceRoom.topic }
|
||||
var canonicalAlias: String? { spaceRoom.canonicalAlias }
|
||||
|
||||
var joinRule: JoinRule? { spaceRoom.joinRule }
|
||||
var worldReadable: Bool? { spaceRoom.worldReadable }
|
||||
var guestCanJoin: Bool { spaceRoom.guestCanJoin }
|
||||
var state: Membership? { spaceRoom.state }
|
||||
}
|
||||
@@ -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 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)
|
||||
})
|
||||
}
|
||||
|
||||
func spaceRoomList(for spaceRoomProxy: SpaceRoomProxyProtocol) async -> Result<SpaceRoomListProxyProtocol, SpaceServiceProxyError> {
|
||||
do {
|
||||
return try await .success(SpaceRoomListProxy(spaceService.spaceRoomList(spaceId: spaceRoomProxy.id), spaceRoomProxy: spaceRoomProxy))
|
||||
} catch {
|
||||
MXLog.error("Failed creating space room list for \(spaceRoomProxy.id): \(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.init))
|
||||
case .clear:
|
||||
spaces.removeAll()
|
||||
case .pushFront(let spaceRoom):
|
||||
spaces.insert(SpaceRoomProxy(spaceRoom: spaceRoom), at: 0)
|
||||
case .pushBack(let spaceRoom):
|
||||
spaces.append(SpaceRoomProxy(spaceRoom: spaceRoom))
|
||||
case .popFront:
|
||||
spaces.removeFirst()
|
||||
case .popBack:
|
||||
spaces.removeLast()
|
||||
case .insert(let index, let spaceRoom):
|
||||
spaces.insert(SpaceRoomProxy(spaceRoom: spaceRoom), at: Int(index))
|
||||
case .set(let index, let spaceRoom):
|
||||
spaces[Int(index)] = SpaceRoomProxy(spaceRoom: spaceRoom)
|
||||
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.init)
|
||||
}
|
||||
}
|
||||
|
||||
spacesSubject.send(spaces)
|
||||
}
|
||||
}
|
||||
@@ -15,5 +15,5 @@ enum SpaceServiceProxyError: Error {
|
||||
protocol SpaceServiceProxyProtocol {
|
||||
var joinedSpacesPublisher: CurrentValuePublisher<[SpaceRoomProxyProtocol], Never> { get }
|
||||
|
||||
func spaceRoomList(for spaceRoom: SpaceRoomProxyProtocol) async -> Result<SpaceRoomListProxyProtocol, SpaceServiceProxyError>
|
||||
func spaceRoomList(for spaceRoomProxy: SpaceRoomProxyProtocol) async -> Result<SpaceRoomListProxyProtocol, SpaceServiceProxyError>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user