mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Room list service (#1138)
* Adopt the new RoomListService * Use client.roomListWithEncryption * Store the roomList so that it doesn't get dropped and create problems on the rust side * Use roomListService instead of old roomList client method * Added back documentation removed by mistake * Tweaks following code review, SDK bump
This commit is contained in:
@@ -38,12 +38,11 @@ class MockRoomSummaryProvider: RoomSummaryProviderProtocol {
|
||||
statePublisher = .init(.notLoaded)
|
||||
case .loaded(let rooms):
|
||||
roomListPublisher = .init(rooms)
|
||||
statePublisher = .init(.fullyLoaded)
|
||||
statePublisher = .init(.loaded(totalNumberOfRooms: UInt(rooms.count)))
|
||||
}
|
||||
}
|
||||
|
||||
func subscribeIfNecessary(entriesFunction: EntriesFunction,
|
||||
entriesLoadingStateFunction: LoadingStateFunction?) async { }
|
||||
func setRoomList(_ roomList: RoomList) { }
|
||||
|
||||
func updateVisibleRange(_ range: Range<Int>) { }
|
||||
}
|
||||
|
||||
@@ -19,12 +19,14 @@ import Foundation
|
||||
import MatrixRustSDK
|
||||
|
||||
class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
||||
private let roomListService: RoomListProtocol
|
||||
private let roomListService: RoomListServiceProtocol
|
||||
private let eventStringBuilder: RoomEventStringBuilder
|
||||
private let name: String
|
||||
|
||||
private let serialDispatchQueue: DispatchQueue
|
||||
|
||||
private var roomList: RoomListProtocol?
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
private var listUpdatesTaskHandle: TaskHandle?
|
||||
private var stateUpdatesTaskHandle: TaskHandle?
|
||||
@@ -49,7 +51,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
init(roomListService: RoomListProtocol,
|
||||
init(roomListService: RoomListServiceProtocol,
|
||||
eventStringBuilder: RoomEventStringBuilder,
|
||||
name: String) {
|
||||
self.roomListService = roomListService
|
||||
@@ -63,37 +65,35 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func subscribeIfNecessary(entriesFunction: EntriesFunction,
|
||||
entriesLoadingStateFunction: LoadingStateFunction?) async {
|
||||
func setRoomList(_ roomList: RoomList) {
|
||||
guard listUpdatesTaskHandle == nil, stateUpdatesTaskHandle == nil else {
|
||||
return
|
||||
}
|
||||
|
||||
self.roomList = roomList
|
||||
|
||||
do {
|
||||
let listUpdatesSubscriptionResult = try await entriesFunction(RoomListEntriesListenerProxy { [weak self] update in
|
||||
let listUpdatesSubscriptionResult = try roomList.entries(listener: RoomListEntriesListenerProxy { [weak self] update in
|
||||
guard let self else { return }
|
||||
MXLog.verbose("\(name): Received list update")
|
||||
diffPublisher.send(update)
|
||||
})
|
||||
|
||||
|
||||
listUpdatesTaskHandle = listUpdatesSubscriptionResult.entriesStream
|
||||
|
||||
|
||||
rooms = listUpdatesSubscriptionResult.entries.map { roomListEntry in
|
||||
buildSummaryForRoomListEntry(roomListEntry)
|
||||
}
|
||||
|
||||
if let entriesLoadingStateFunction {
|
||||
let stateUpdatesSubscriptionResult = try await entriesLoadingStateFunction(RoomListStateObserver { [weak self] state in
|
||||
guard let self else { return }
|
||||
MXLog.info("\(name): Received state update: \(state)")
|
||||
stateSubject.send(RoomSummaryProviderState(slidingSyncState: state))
|
||||
})
|
||||
|
||||
stateSubject.send(RoomSummaryProviderState(slidingSyncState: stateUpdatesSubscriptionResult.entriesLoadingState))
|
||||
|
||||
stateUpdatesTaskHandle = stateUpdatesSubscriptionResult.entriesLoadingStateStream
|
||||
}
|
||||
let stateUpdatesSubscriptionResult = try roomList.loadingState(listener: RoomListStateObserver { [weak self] state in
|
||||
guard let self else { return }
|
||||
MXLog.info("\(name): Received state update: \(state)")
|
||||
stateSubject.send(RoomSummaryProviderState(roomListState: state))
|
||||
})
|
||||
|
||||
stateUpdatesTaskHandle = stateUpdatesSubscriptionResult.stateStream
|
||||
|
||||
stateSubject.send(RoomSummaryProviderState(roomListState: stateUpdatesSubscriptionResult.state))
|
||||
} catch {
|
||||
MXLog.error("Failed setting up room list entry listener with error: \(error)")
|
||||
}
|
||||
@@ -266,16 +266,12 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
||||
}
|
||||
|
||||
extension RoomSummaryProviderState {
|
||||
init(slidingSyncState: SlidingSyncListLoadingState) {
|
||||
switch slidingSyncState {
|
||||
init(roomListState: RoomListLoadingState) {
|
||||
switch roomListState {
|
||||
case .notLoaded:
|
||||
self = .notLoaded
|
||||
case .preloaded:
|
||||
self = .preloaded
|
||||
case .partiallyLoaded:
|
||||
self = .partiallyLoaded
|
||||
case .fullyLoaded:
|
||||
self = .fullyLoaded
|
||||
case .loaded(let maximumNumberOfRooms):
|
||||
self = .loaded(totalNumberOfRooms: UInt(maximumNumberOfRooms ?? 0))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -314,14 +310,14 @@ private class RoomListEntriesListenerProxy: RoomListEntriesListener {
|
||||
}
|
||||
}
|
||||
|
||||
private class RoomListStateObserver: SlidingSyncListStateObserver {
|
||||
private let onUpdateClosure: (SlidingSyncListLoadingState) -> Void
|
||||
private class RoomListStateObserver: RoomListLoadingStateListener {
|
||||
private let onUpdateClosure: (RoomListLoadingState) -> Void
|
||||
|
||||
init(_ onUpdateClosure: @escaping (SlidingSyncListLoadingState) -> Void) {
|
||||
init(_ onUpdateClosure: @escaping (RoomListLoadingState) -> Void) {
|
||||
self.onUpdateClosure = onUpdateClosure
|
||||
}
|
||||
|
||||
func didReceiveUpdate(newState: SlidingSyncListLoadingState) {
|
||||
onUpdateClosure(newState)
|
||||
func onUpdate(state: RoomListLoadingState) {
|
||||
onUpdateClosure(state)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,25 @@ import MatrixRustSDK
|
||||
|
||||
enum RoomSummaryProviderState {
|
||||
case notLoaded
|
||||
case preloaded
|
||||
case partiallyLoaded
|
||||
case fullyLoaded
|
||||
case loaded(totalNumberOfRooms: UInt)
|
||||
|
||||
var isLoaded: Bool {
|
||||
switch self {
|
||||
case .loaded:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
var totalNumberOfRooms: UInt? {
|
||||
switch self {
|
||||
case .loaded(let totalNumberOfRooms):
|
||||
return totalNumberOfRooms
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum RoomSummary: CustomStringConvertible {
|
||||
@@ -61,19 +77,15 @@ enum RoomSummary: CustomStringConvertible {
|
||||
}
|
||||
|
||||
protocol RoomSummaryProviderProtocol {
|
||||
typealias EntriesFunction = (RoomListEntriesListener) async throws -> RoomListEntriesResult
|
||||
typealias LoadingStateFunction = (SlidingSyncListStateObserver) async throws -> RoomListEntriesLoadingStateResult
|
||||
|
||||
/// Publishes the currently available room summaries
|
||||
var roomListPublisher: CurrentValuePublisher<[RoomSummary], Never> { get }
|
||||
|
||||
/// Publishes the current state the summary provider is finding itself in
|
||||
var statePublisher: CurrentValuePublisher<RoomSummaryProviderState, Never> { get }
|
||||
|
||||
/// A separate subscription method is needed instead of running this in the constructor because the invites list is added later on the Rust side.
|
||||
/// This is outside of the constructor because the invites list is added later on the Rust side.
|
||||
/// Wanted to be able to build the InvitesSummaryProvider directly instead of having to inform the HomeScreenViewModel about it later
|
||||
func subscribeIfNecessary(entriesFunction: EntriesFunction,
|
||||
entriesLoadingStateFunction: LoadingStateFunction?) async
|
||||
func setRoomList(_ roomList: RoomList)
|
||||
|
||||
func updateVisibleRange(_ range: Range<Int>)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user