mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
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:
parent
f368da3485
commit
cabb8e5442
@ -111,8 +111,8 @@
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/matrix-org/matrix-rust-components-swift",
|
||||
"state" : {
|
||||
"revision" : "3d377773dc09104af8a38cf641860aa21f33f2c6",
|
||||
"version" : "1.0.51-alpha"
|
||||
"revision" : "c4185fb641cd5eb312c64b2b70ec2241ade3e309",
|
||||
"version" : "1.0.53-alpha"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -163,7 +163,7 @@
|
||||
{
|
||||
"identity" : "swift-snapshot-testing",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/pointfreeco/swift-snapshot-testing.git",
|
||||
"location" : "https://github.com/pointfreeco/swift-snapshot-testing",
|
||||
"state" : {
|
||||
"revision" : "cef5b3f6f11781dd4591bdd1dd0a3d22bd609334",
|
||||
"version" : "1.11.0"
|
||||
|
@ -268,8 +268,9 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
}
|
||||
|
||||
private func updateVisibleRange(_ range: Range<Int>, timelineLimit: UInt) {
|
||||
guard visibleRoomsSummaryProvider?.statePublisher.value == .fullyLoaded,
|
||||
!range.isEmpty else { return }
|
||||
guard !range.isEmpty else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let visibleRoomsSummaryProvider else {
|
||||
MXLog.error("Visible rooms summary provider unavailable")
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,7 @@ private struct MockEventTimelineItem: EventTimelineItemProtocol {
|
||||
|
||||
func eventId() -> String? { UUID().uuidString }
|
||||
|
||||
func fmtDebug() -> String { "MockEvent" }
|
||||
func debugInfo() -> MatrixRustSDK.EventTimelineItemDebugInfo { .init(model: "MockEvent", originalJson: nil, latestEditJson: nil) }
|
||||
|
||||
func isEditable() -> Bool { false }
|
||||
|
||||
@ -159,7 +159,7 @@ private struct MockEventTimelineItem: EventTimelineItemProtocol {
|
||||
|
||||
func sender() -> String { "@user:server.com" }
|
||||
|
||||
func senderProfile() -> MatrixRustSDK.ProfileTimelineDetails { .unavailable }
|
||||
func senderProfile() -> MatrixRustSDK.ProfileDetails { .unavailable }
|
||||
|
||||
func timestamp() -> UInt64 { 0 }
|
||||
|
||||
|
@ -42,7 +42,7 @@ include:
|
||||
packages:
|
||||
MatrixRustSDK:
|
||||
url: https://github.com/matrix-org/matrix-rust-components-swift
|
||||
exactVersion: 1.0.51-alpha
|
||||
exactVersion: 1.0.53-alpha
|
||||
# path: ../matrix-rust-sdk
|
||||
DesignKit:
|
||||
path: DesignKit
|
||||
|
Loading…
x
Reference in New Issue
Block a user