diff --git a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index f0803c493..ff05004b0 100644 --- a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -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" diff --git a/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift b/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift index 7b21bfe4d..7759245f9 100644 --- a/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift +++ b/ElementX/Sources/Screens/HomeScreen/HomeScreenViewModel.swift @@ -268,8 +268,9 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol } private func updateVisibleRange(_ range: Range, 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") diff --git a/ElementX/Sources/Services/Client/ClientProxy.swift b/ElementX/Sources/Services/Client/ClientProxy.swift index f81fa3014..5c48446cd 100644 --- a/ElementX/Sources/Services/Client/ClientProxy.swift +++ b/ElementX/Sources/Services/Client/ClientProxy.swift @@ -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 { diff --git a/ElementX/Sources/Services/Client/SlidingSyncViewProxy.swift b/ElementX/Sources/Services/Client/SlidingSyncViewProxy.swift index 114ee6e3c..35f6314c3 100644 --- a/ElementX/Sources/Services/Client/SlidingSyncViewProxy.swift +++ b/ElementX/Sources/Services/Client/SlidingSyncViewProxy.swift @@ -27,25 +27,31 @@ private class SlidingSyncViewObserver: SlidingSyncListRoomListObserver, SlidingS /// Publishes the number of available rooms let countUpdatePublisher = CurrentValueSubject(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, 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)") + } } } diff --git a/ElementX/Sources/Services/Timeline/TimelineItemContent/MessageTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItemContent/MessageTimelineItem.swift index 1ed450c54..309bc502f 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItemContent/MessageTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItemContent/MessageTimelineItem.swift @@ -42,10 +42,6 @@ struct MessageTimelineItem { item.content().asMessage()?.isEdited() == true } - var inReplyTo: String? { - item.content().asMessage()?.inReplyTo() - } - var sender: String { item.sender() } diff --git a/ElementX/Sources/Services/Timeline/TimelineItemProxy.swift b/ElementX/Sources/Services/Timeline/TimelineItemProxy.swift index 55f509053..cc504ab8f 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItemProxy.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItemProxy.swift @@ -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 } } diff --git a/UnitTests/Sources/MessageTimelineItemTests.swift b/UnitTests/Sources/MessageTimelineItemTests.swift index 63641b975..b6c452cd5 100644 --- a/UnitTests/Sources/MessageTimelineItemTests.swift +++ b/UnitTests/Sources/MessageTimelineItemTests.swift @@ -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 } diff --git a/project.yml b/project.yml index 07cdb7413..5c26500ac 100644 --- a/project.yml +++ b/project.yml @@ -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