Sliding sync v2 (#775)

* Adopt latest rust Sliding Sync changes

* Bump SDK, converge on similar to configure both sliding sync lists

* Adopt latest SDK version, fix breaking changes

* Fix unit tests
This commit is contained in:
Stefan Ceriu
2023-04-06 18:43:08 +03:00
committed by GitHub
parent f368da3485
commit cabb8e5442
8 changed files with 95 additions and 63 deletions
@@ -299,25 +299,20 @@ class ClientProxy: ClientProxyProtocol {
do {
let slidingSyncBuilder = client.slidingSync()
// Build the visibleRoomsSlidingSyncView here so that it can take advantage of the SS builder cold cache
// We will still register the allRoomsSlidingSyncView later, and than will have no cache
let visibleRoomsView = try SlidingSyncListBuilder()
.timelineLimit(limit: UInt32(SlidingSyncConstants.initialTimelineLimit)) // Starts off with zero to quickly load rooms, then goes to 1 while scrolling to quickly load last messages and 20 when the scrolling stops to load room history
.requiredState(requiredState: slidingSyncRequiredState)
.filters(filters: slidingSyncFilters)
.name(name: "CurrentlyVisibleRooms")
.syncMode(mode: .selective)
.addRange(from: 0, to: 20)
.sendUpdatesForItems(enable: true)
.build()
// List observers need to be setup before calling build() on the SlidingSyncBuilder otherwise
// cold cache state and count updates will be lost
buildAndConfigureVisibleRoomsSlidingSyncView(visibleRoomsView: visibleRoomsView)
buildAndConfigureVisibleRoomsSlidingSyncView()
buildAndConfigureAllRoomsSlidingSyncView()
guard let visibleRoomsSlidingSyncView else {
MXLog.error("Visible rooms sliding sync view unavailable")
return
}
// Add the visibleRoomsSlidingSyncView here so that it can take advantage of the SS builder cold cache
// We will still register the allRoomsSlidingSyncView later, and than will have no cache
let slidingSync = try slidingSyncBuilder
.addList(v: visibleRoomsView)
.addList(v: visibleRoomsSlidingSyncView)
.withCommonExtensions()
.coldCache(name: "ElementX")
.build()
@@ -334,28 +329,48 @@ class ClientProxy: ClientProxyProtocol {
}
}
private func buildAndConfigureVisibleRoomsSlidingSyncView(visibleRoomsView: SlidingSyncList) {
let visibleRoomsViewProxy = SlidingSyncViewProxy(slidingSyncView: visibleRoomsView)
visibleRoomsSummaryProvider = RoomSummaryProvider(slidingSyncViewProxy: visibleRoomsViewProxy,
eventStringBuilder: RoomEventStringBuilder(stateEventStringBuilder: RoomStateEventStringBuilder(userID: userID)))
visibleRoomsSlidingSyncView = visibleRoomsView
// Changes to the visibleRoomsSlidingSyncView range need to restart the connection to be applied
visibleRoomsViewProxy.visibleRangeUpdatePublisher.sink { [weak self] in
self?.restartSync()
}
.store(in: &cancellables)
// The allRoomsSlidingSyncView will be registered as soon as the visibleRoomsSlidingSyncView receives its first update
visibleRoomsViewProxyStateObservationToken = visibleRoomsViewProxy.diffPublisher.sink { [weak self] _ in
MXLog.info("Visible rooms view received first update, configuring views post initial sync")
self?.configureViewsPostInitialSync()
self?.visibleRoomsViewProxyStateObservationToken = nil
private func buildAndConfigureVisibleRoomsSlidingSyncView() {
guard visibleRoomsSlidingSyncView == nil else {
fatalError("This shouldn't be called more than once")
}
self.visibleRoomsViewProxy = visibleRoomsViewProxy
do {
let visibleRoomsSlidingSyncView = try SlidingSyncListBuilder()
.timelineLimit(limit: UInt32(SlidingSyncConstants.initialTimelineLimit)) // Starts off with zero to quickly load rooms, then goes to 1 while scrolling to quickly load last messages and 20 when the scrolling stops to load room history
.requiredState(requiredState: slidingSyncRequiredState)
.filters(filters: slidingSyncFilters)
.name(name: "CurrentlyVisibleRooms")
.syncMode(mode: .selective)
.addRange(from: 0, to: 20)
.build()
let visibleRoomsViewProxy = SlidingSyncViewProxy(slidingSyncView: visibleRoomsSlidingSyncView, name: "Visible rooms")
visibleRoomsSummaryProvider = RoomSummaryProvider(slidingSyncViewProxy: visibleRoomsViewProxy,
eventStringBuilder: RoomEventStringBuilder(stateEventStringBuilder: RoomStateEventStringBuilder(userID: userID)))
self.visibleRoomsSlidingSyncView = visibleRoomsSlidingSyncView
self.visibleRoomsViewProxy = visibleRoomsViewProxy
// Changes to the visibleRoomsSlidingSyncView range need to restart the connection to be applied
visibleRoomsViewProxy.visibleRangeUpdatePublisher.sink { [weak self] in
self?.restartSync()
}
.store(in: &cancellables)
// The allRoomsSlidingSyncView will be registered as soon as the visibleRoomsSlidingSyncView receives its first update
visibleRoomsViewProxyStateObservationToken = visibleRoomsViewProxy.statePublisher.sink { [weak self] state in
guard state == .fullyLoaded else {
return
}
MXLog.info("Visible rooms view received first update, configuring views post initial sync")
self?.configureViewsPostInitialSync()
self?.visibleRoomsViewProxyStateObservationToken = nil
}
} catch {
MXLog.error("Failed building the visible rooms sliding sync view with error: \(error)")
}
}
private func buildAndConfigureAllRoomsSlidingSyncView() {
@@ -364,23 +379,21 @@ class ClientProxy: ClientProxyProtocol {
}
do {
let allRoomsView = try SlidingSyncListBuilder()
let allRoomsSlidingSyncView = try SlidingSyncListBuilder()
.noTimelineLimit()
.requiredState(requiredState: slidingSyncRequiredState)
.filters(filters: slidingSyncFilters)
.name(name: "AllRooms")
.syncMode(mode: .growingFullSync)
.syncMode(mode: .growing)
.batchSize(batchSize: 100)
.sendUpdatesForItems(enable: true)
.build()
let allRoomsViewProxy = SlidingSyncViewProxy(slidingSyncView: allRoomsView)
let allRoomsViewProxy = SlidingSyncViewProxy(slidingSyncView: allRoomsSlidingSyncView, name: "All rooms")
allRoomsSummaryProvider = RoomSummaryProvider(slidingSyncViewProxy: allRoomsViewProxy,
eventStringBuilder: RoomEventStringBuilder(stateEventStringBuilder: RoomStateEventStringBuilder(userID: userID)))
allRoomsSlidingSyncView = allRoomsView
self.allRoomsSlidingSyncView = allRoomsSlidingSyncView
self.allRoomsViewProxy = allRoomsViewProxy
} catch {
@@ -27,25 +27,31 @@ private class SlidingSyncViewObserver: SlidingSyncListRoomListObserver, SlidingS
/// Publishes the number of available rooms
let countUpdatePublisher = CurrentValueSubject<UInt, Never>(0)
private let name: String
init(name: String) {
self.name = name
}
// MARK: - SlidingSyncListRoomListObserver
func didReceiveUpdate(diff: SlidingSyncListRoomsListDiff) {
MXLog.verbose("Received room diff")
MXLog.verbose("\(name): Received room diff")
roomListDiffPublisher.send(diff)
}
// MARK: - SlidingSyncListStateObserver
func didReceiveUpdate(newState: SlidingSyncState) {
MXLog.info("Updated state: \(newState)")
MXLog.info("\(name): Updated state: \(newState)")
stateUpdatePublisher.send(newState)
}
// MARK: - SlidingSyncListRoomsCountObserver
func didReceiveUpdate(count: UInt32) {
MXLog.info("Updated room count: \(count)")
MXLog.info("\(name): Updated room count: \(count)")
countUpdatePublisher.send(UInt(count))
}
}
@@ -71,10 +77,10 @@ class SlidingSyncViewProxy {
countUpdateObserverToken?.cancel()
}
init(slidingSyncView: SlidingSyncListProtocol) {
init(slidingSyncView: SlidingSyncListProtocol, name: String) {
self.slidingSyncView = slidingSyncView
let slidingSyncViewObserver = SlidingSyncViewObserver()
let slidingSyncViewObserver = SlidingSyncViewObserver(name: name)
slidingSyncViewObserver.stateUpdatePublisher
.subscribe(statePublisher)
@@ -98,7 +104,7 @@ class SlidingSyncViewProxy {
}
func currentRoomsList() -> [RoomListEntry] {
slidingSyncView.currentRoomsList()
slidingSyncView.currentRoomList()
}
func roomForIdentifier(_ identifier: String) throws -> SlidingSyncRoomProtocol? {
@@ -108,9 +114,13 @@ class SlidingSyncViewProxy {
func updateVisibleRange(_ range: Range<Int>, timelineLimit: UInt) {
MXLog.info("Setting sliding sync view range to \(range), timeline limit: \(timelineLimit)")
slidingSyncView.setRange(start: UInt32(range.lowerBound), end: UInt32(range.upperBound))
slidingSyncView.setTimelineLimit(value: UInt32(timelineLimit))
visibleRangeUpdatePublisher.send(())
do {
try slidingSyncView.setRange(start: UInt32(range.lowerBound), end: UInt32(range.upperBound))
slidingSyncView.setTimelineLimit(value: UInt32(timelineLimit))
visibleRangeUpdatePublisher.send(())
} catch {
MXLog.error("Failed setting sliding sync list range with error: \(error)")
}
}
}
@@ -42,10 +42,6 @@ struct MessageTimelineItem<Content: MessageContentProtocol> {
item.content().asMessage()?.isEdited() == true
}
var inReplyTo: String? {
item.content().asMessage()?.inReplyTo()
}
var sender: String {
item.sender()
}
@@ -116,7 +116,19 @@ struct EventTimelineItemProxy: CustomDebugStringConvertible {
// MARK: - CustomDebugStringConvertible
var debugDescription: String {
item.fmtDebug()
let debugInfo = item.debugInfo()
var debugDescription = debugInfo.model
if let originalJson = debugInfo.originalJson {
debugDescription += "\n\n\(originalJson)"
}
if let latestEditJson = debugInfo.latestEditJson {
debugDescription += "\n\n\(latestEditJson)"
}
return debugDescription
}
}