mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Various sliding sync tweaks (#446)
* Refactor SS configuration and add (unfinished) support for adding views dynamically. * Implement pop and clear support on the room summary provider * Register views against sliding sync * Read invalidated vislbeRoomsSummaryProvider from the allRoomSummaryProvider * Switch SS window range setting from the ScrollViewAdapter to a publisher debounce * Tweak allRoomsView addition: switch from listening the visibleRoomsView's state to when it publishes the first diff update * Cleanup client delegate and sliding sync observers and lifecycle * Bump the RustSDK to 1.0.30-alpha * Reuse startSync within restartSync
This commit is contained in:
@@ -46,9 +46,6 @@ private class WeakClientProxyWrapper: ClientDelegate, SlidingSyncObserver {
|
||||
}
|
||||
|
||||
class ClientProxy: ClientProxyProtocol {
|
||||
/// The maximum number of timeline events required during a sync request.
|
||||
static let syncLimit: UInt16 = 50
|
||||
|
||||
private let client: ClientProtocol
|
||||
private let backgroundTaskService: BackgroundTaskServiceProtocol
|
||||
private var sessionVerificationControllerProxy: SessionVerificationControllerProxy?
|
||||
@@ -58,10 +55,15 @@ class ClientProxy: ClientProxyProtocol {
|
||||
private var slidingSyncObserverToken: StoppableSpawn?
|
||||
private var slidingSync: SlidingSync?
|
||||
|
||||
var visibleRoomsSlidingSyncView: SlidingSyncView?
|
||||
var visibleRoomsSummaryProvider: RoomSummaryProviderProtocol?
|
||||
|
||||
var allRoomsSlidingSyncView: SlidingSyncView?
|
||||
var allRoomsSummaryProvider: RoomSummaryProviderProtocol?
|
||||
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
private var visibleRoomsViewProxyStateObservationToken: AnyCancellable?
|
||||
|
||||
deinit {
|
||||
// These need to be inlined instead of using stopSync()
|
||||
// as we can't call async methods safely from deinit
|
||||
@@ -72,77 +74,16 @@ class ClientProxy: ClientProxyProtocol {
|
||||
|
||||
let callbacks = PassthroughSubject<ClientProxyCallback, Never>()
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
init(client: ClientProtocol,
|
||||
backgroundTaskService: BackgroundTaskServiceProtocol) async {
|
||||
init(client: ClientProtocol, backgroundTaskService: BackgroundTaskServiceProtocol) async {
|
||||
self.client = client
|
||||
self.backgroundTaskService = backgroundTaskService
|
||||
clientQueue = .init(label: "ClientProxyQueue",
|
||||
attributes: .concurrent)
|
||||
mediaProxy = MediaProxy(client: client,
|
||||
clientQueue: clientQueue)
|
||||
clientQueue = .init(label: "ClientProxyQueue", attributes: .concurrent)
|
||||
|
||||
mediaProxy = MediaProxy(client: client, clientQueue: clientQueue)
|
||||
|
||||
await Task.dispatch(on: clientQueue) {
|
||||
do {
|
||||
let slidingSyncBuilder = try client.slidingSync().homeserver(url: ServiceLocator.shared.settings.slidingSyncProxyBaseURLString)
|
||||
|
||||
let requiredState = [RequiredState(key: "m.room.avatar", value: ""),
|
||||
RequiredState(key: "m.room.encryption", value: "")]
|
||||
|
||||
let filters = SlidingSyncRequestListFilters(isDm: nil,
|
||||
spaces: [],
|
||||
isEncrypted: nil,
|
||||
isInvite: false,
|
||||
isTombstoned: false,
|
||||
roomTypes: [],
|
||||
notRoomTypes: ["m.space"],
|
||||
roomNameLike: nil,
|
||||
tags: [],
|
||||
notTags: [])
|
||||
|
||||
let visibleRoomsView = try SlidingSyncViewBuilder()
|
||||
.timelineLimit(limit: 20)
|
||||
.requiredState(requiredState: requiredState)
|
||||
.filters(filters: filters)
|
||||
.name(name: "CurrentlyVisibleRooms")
|
||||
.syncMode(mode: .selective)
|
||||
.addRange(from: 0, to: 20)
|
||||
.build()
|
||||
|
||||
let allRoomsView = try SlidingSyncViewBuilder()
|
||||
.noTimelineLimit()
|
||||
.requiredState(requiredState: requiredState)
|
||||
.filters(filters: filters)
|
||||
.name(name: "AllRooms")
|
||||
.syncMode(mode: .growingFullSync)
|
||||
.batchSize(batchSize: 100)
|
||||
.roomLimit(limit: 500)
|
||||
.build()
|
||||
|
||||
let slidingSync = try slidingSyncBuilder
|
||||
.addView(v: visibleRoomsView)
|
||||
.addView(v: allRoomsView)
|
||||
.withCommonExtensions()
|
||||
.coldCache(name: "ElementX")
|
||||
.build()
|
||||
|
||||
let visibleRoomsViewProxy = SlidingSyncViewProxy(clientProxy: self, slidingSync: slidingSync, slidingSyncView: visibleRoomsView)
|
||||
|
||||
let allRoomsViewProxy = SlidingSyncViewProxy(clientProxy: self, slidingSync: slidingSync, slidingSyncView: allRoomsView)
|
||||
|
||||
self.visibleRoomsSummaryProvider = RoomSummaryProvider(slidingSyncViewProxy: visibleRoomsViewProxy,
|
||||
roomMessageFactory: RoomMessageFactory())
|
||||
|
||||
self.allRoomsSummaryProvider = RoomSummaryProvider(slidingSyncViewProxy: allRoomsViewProxy,
|
||||
roomMessageFactory: RoomMessageFactory())
|
||||
|
||||
self.slidingSync = slidingSync
|
||||
} catch {
|
||||
MXLog.error("Failed configuring sliding sync with error: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
client.setDelegate(delegate: WeakClientProxyWrapper(clientProxy: self))
|
||||
|
||||
configureSlidingSync()
|
||||
}
|
||||
|
||||
var userIdentifier: String {
|
||||
@@ -181,24 +122,16 @@ class ClientProxy: ClientProxyProtocol {
|
||||
}
|
||||
|
||||
func startSync() {
|
||||
guard !client.isSoftLogout() else {
|
||||
guard !client.isSoftLogout(), slidingSyncObserverToken == nil else {
|
||||
return
|
||||
}
|
||||
|
||||
slidingSync?.setObserver(observer: WeakClientProxyWrapper(clientProxy: self))
|
||||
slidingSyncObserverToken = slidingSync?.sync()
|
||||
}
|
||||
|
||||
func stopSync() {
|
||||
client.setDelegate(delegate: nil)
|
||||
|
||||
slidingSyncObserverToken?.cancel()
|
||||
slidingSync?.setObserver(observer: nil)
|
||||
}
|
||||
|
||||
func restartSync() {
|
||||
slidingSyncObserverToken?.cancel()
|
||||
slidingSyncObserverToken = slidingSync?.sync()
|
||||
slidingSyncObserverToken = nil
|
||||
}
|
||||
|
||||
func roomForIdentifier(_ identifier: String) async -> RoomProxyProtocol? {
|
||||
@@ -297,6 +230,125 @@ class ClientProxy: ClientProxyProtocol {
|
||||
}
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private func restartSync() {
|
||||
stopSync()
|
||||
startSync()
|
||||
}
|
||||
|
||||
private func configureSlidingSync() {
|
||||
guard slidingSync == nil else {
|
||||
fatalError("This shouldn't be called more than once")
|
||||
}
|
||||
|
||||
do {
|
||||
let slidingSyncBuilder = try client.slidingSync().homeserver(url: ServiceLocator.shared.settings.slidingSyncProxyBaseURLString)
|
||||
|
||||
let slidingSync = try slidingSyncBuilder
|
||||
.withCommonExtensions()
|
||||
.coldCache(name: "ElementX")
|
||||
.build()
|
||||
|
||||
slidingSync.setObserver(observer: WeakClientProxyWrapper(clientProxy: self))
|
||||
|
||||
self.slidingSync = slidingSync
|
||||
|
||||
configureSlidingSyncViews(slidingSync: slidingSync)
|
||||
|
||||
guard let visibleRoomsSlidingSyncView else {
|
||||
MXLog.error("Visible rooms sliding sync view unavailable")
|
||||
return
|
||||
}
|
||||
|
||||
registerSlidingSyncView(visibleRoomsSlidingSyncView)
|
||||
|
||||
} catch {
|
||||
MXLog.error("Failed building sliding sync with error: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
// swiftlint:disable:next function_body_length
|
||||
private func configureSlidingSyncViews(slidingSync: SlidingSyncProtocol) {
|
||||
guard visibleRoomsSlidingSyncView == nil,
|
||||
allRoomsSlidingSyncView == nil else {
|
||||
fatalError("This shouldn't be called more than once")
|
||||
}
|
||||
|
||||
let requiredState = [RequiredState(key: "m.room.avatar", value: ""),
|
||||
RequiredState(key: "m.room.encryption", value: "")]
|
||||
|
||||
let filters = SlidingSyncRequestListFilters(isDm: nil,
|
||||
spaces: [],
|
||||
isEncrypted: nil,
|
||||
isInvite: false,
|
||||
isTombstoned: false,
|
||||
roomTypes: [],
|
||||
notRoomTypes: ["m.space"],
|
||||
roomNameLike: nil,
|
||||
tags: [],
|
||||
notTags: [])
|
||||
|
||||
do {
|
||||
let visibleRoomsView = try SlidingSyncViewBuilder()
|
||||
.timelineLimit(limit: 20)
|
||||
.requiredState(requiredState: requiredState)
|
||||
.filters(filters: filters)
|
||||
.name(name: "CurrentlyVisibleRooms")
|
||||
.syncMode(mode: .selective)
|
||||
.addRange(from: 0, to: 20)
|
||||
.build()
|
||||
|
||||
let allRoomsView = try SlidingSyncViewBuilder()
|
||||
.noTimelineLimit()
|
||||
.requiredState(requiredState: requiredState)
|
||||
.filters(filters: filters)
|
||||
.name(name: "AllRooms")
|
||||
.syncMode(mode: .growingFullSync)
|
||||
.batchSize(batchSize: 100)
|
||||
.roomLimit(limit: 500)
|
||||
.build()
|
||||
|
||||
let visibleRoomsViewProxy = SlidingSyncViewProxy(slidingSync: slidingSync, slidingSyncView: visibleRoomsView)
|
||||
|
||||
let allRoomsViewProxy = SlidingSyncViewProxy(slidingSync: slidingSync, slidingSyncView: allRoomsView)
|
||||
|
||||
visibleRoomsSummaryProvider = RoomSummaryProvider(slidingSyncViewProxy: visibleRoomsViewProxy,
|
||||
roomMessageFactory: RoomMessageFactory())
|
||||
|
||||
allRoomsSummaryProvider = RoomSummaryProvider(slidingSyncViewProxy: allRoomsViewProxy,
|
||||
roomMessageFactory: RoomMessageFactory())
|
||||
|
||||
visibleRoomsViewProxy.visibleRangeUpdatePublisher.sink { [weak self] in
|
||||
self?.restartSync()
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
visibleRoomsViewProxyStateObservationToken = visibleRoomsViewProxy.diffPublisher.sink { [weak self] _ in
|
||||
self?.registerAllRoomSlidingSyncView()
|
||||
self?.visibleRoomsViewProxyStateObservationToken = nil
|
||||
}
|
||||
|
||||
visibleRoomsSlidingSyncView = visibleRoomsView
|
||||
allRoomsSlidingSyncView = allRoomsView
|
||||
|
||||
} catch {
|
||||
MXLog.error("Failed building sliding sync views with error: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
private func registerAllRoomSlidingSyncView() {
|
||||
guard let allRoomsSlidingSyncView else {
|
||||
MXLog.error("All rooms sliding sync view unavailable")
|
||||
return
|
||||
}
|
||||
|
||||
registerSlidingSyncView(allRoomsSlidingSyncView)
|
||||
}
|
||||
|
||||
private func registerSlidingSyncView(_ view: SlidingSyncView) {
|
||||
_ = slidingSync?.addView(view: view)
|
||||
restartSync()
|
||||
}
|
||||
|
||||
private func roomTupleForIdentifier(_ identifier: String) -> (SlidingSyncRoom?, Room?) {
|
||||
do {
|
||||
|
||||
Reference in New Issue
Block a user