diff --git a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 4b15621aa..87497c584 100644 --- a/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/ElementX.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -95,8 +95,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/matrix-org/matrix-rust-components-swift", "state" : { - "revision" : "986c400f8d4d0f9d467370f98d70b6b742e90e18", - "version" : "1.0.38-alpha" + "revision" : "cceadb7fb59518e642010901b8f0cd87946221f3", + "version" : "1.0.40-alpha" } }, { diff --git a/ElementX/Sources/Services/Room/MockRoomProxy.swift b/ElementX/Sources/Services/Room/MockRoomProxy.swift index 4231c6793..24134910c 100644 --- a/ElementX/Sources/Services/Room/MockRoomProxy.swift +++ b/ElementX/Sources/Services/Room/MockRoomProxy.swift @@ -46,7 +46,7 @@ struct MockRoomProxy: RoomProxyProtocol { func startLiveEventListener() { } - func addTimelineListener(listener: TimelineListener) -> Result { + func addTimelineListener(listener: TimelineListener) -> Result<[TimelineItem], RoomProxyError> { .failure(.failedAddingTimelineListener) } diff --git a/ElementX/Sources/Services/Room/RoomProxy.swift b/ElementX/Sources/Services/Room/RoomProxy.swift index 8aaa7d296..9e036fb0c 100644 --- a/ElementX/Sources/Services/Room/RoomProxy.swift +++ b/ElementX/Sources/Services/Room/RoomProxy.swift @@ -136,16 +136,16 @@ class RoomProxy: RoomProxyProtocol { } } - func addTimelineListener(listener: TimelineListener) -> Result { + func addTimelineListener(listener: TimelineListener) -> Result<[TimelineItem], RoomProxyError> { let settings = RoomSubscription(requiredState: [RequiredState(key: "m.room.topic", value: ""), RequiredState(key: "m.room.canonical_alias", value: "")], timelineLimit: nil) - if let token = slidingSyncRoom.subscribeAndAddTimelineListener(listener: listener, settings: settings) { - timelineObservationToken = token + if let result = try? slidingSyncRoom.subscribeAndAddTimelineListener(listener: listener, settings: settings) { + timelineObservationToken = result.taskHandle Task { await fetchMembers() } - return .success(()) + return .success(result.items) } else { return .failure(.failedAddingTimelineListener) } diff --git a/ElementX/Sources/Services/Room/RoomProxyProtocol.swift b/ElementX/Sources/Services/Room/RoomProxyProtocol.swift index fe032335a..821496d78 100644 --- a/ElementX/Sources/Services/Room/RoomProxyProtocol.swift +++ b/ElementX/Sources/Services/Room/RoomProxyProtocol.swift @@ -57,7 +57,7 @@ protocol RoomProxyProtocol { func loadDisplayNameForUserId(_ userId: String) async -> Result - func addTimelineListener(listener: TimelineListener) -> Result + func addTimelineListener(listener: TimelineListener) -> Result<[TimelineItem], RoomProxyError> func paginateBackwards(requestSize: UInt, untilNumberOfItems: UInt) async -> Result diff --git a/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift b/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift index 3138d8978..2c641ea22 100644 --- a/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift +++ b/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift @@ -54,11 +54,11 @@ class RoomTimelineProvider: RoomTimelineProviderProtocol { .store(in: &cancellables) switch await roomProxy.addTimelineListener(listener: roomTimelineListener) { + case .success(let items): + itemProxies = items.map(TimelineItemProxy.init) case .failure: let roomID = await roomProxy.id MXLog.error("Failed adding timeline listener on room with identifier: \(roomID)") - default: - break } } } @@ -87,79 +87,76 @@ class RoomTimelineProvider: RoomTimelineProviderProtocol { MXLog.verbose("Finished applying diff") } - + // swiftlint:disable:next cyclomatic_complexity function_body_length private func buildDiff(from diff: TimelineDiff, on itemProxies: [TimelineItemProxy]) -> CollectionDifference? { var changes = [CollectionDifference.Change]() switch diff.change() { - case .push: - guard let item = diff.push() else { - fatalError() - } + case .pushFront: + guard let item = diff.pushFront() else { fatalError() } - MXLog.verbose("Push") + MXLog.verbose("Push Front") + let itemProxy = TimelineItemProxy(item: item) + changes.append(.insert(offset: 0, element: itemProxy, associatedWith: nil)) + case .pushBack: + guard let item = diff.pushBack() else { fatalError() } + + MXLog.verbose("Push Back") let itemProxy = TimelineItemProxy(item: item) changes.append(.insert(offset: Int(itemProxies.count), element: itemProxy, associatedWith: nil)) - case .updateAt: - guard let update = diff.updateAt() else { - fatalError() + case .insert: + guard let update = diff.insert() else { fatalError() } + + MXLog.verbose("Insert at \(update.index), current total count: \(itemProxies.count)") + let itemProxy = TimelineItemProxy(item: update.item) + changes.append(.insert(offset: Int(update.index), element: itemProxy, associatedWith: nil)) + case .append: + guard let items = diff.append() else { fatalError() } + + MXLog.verbose("Append new items with count: \(items.count), to current total count: \(itemProxies.count)") + for (index, item) in items.enumerated() { + changes.append(.insert(offset: Int(itemProxies.count) + index, element: TimelineItemProxy(item: item), associatedWith: nil)) } + case .set: + guard let update = diff.set() else { fatalError() } MXLog.verbose("Update \(update.index), current total count: \(itemProxies.count)") let itemProxy = TimelineItemProxy(item: update.item) changes.append(.remove(offset: Int(update.index), element: itemProxy, associatedWith: nil)) changes.append(.insert(offset: Int(update.index), element: itemProxy, associatedWith: nil)) - case .insertAt: - guard let update = diff.insertAt() else { - fatalError() - } + case .popFront: + MXLog.verbose("Pop Front, current total count: \(itemProxies.count)") + guard let itemProxy = itemProxies.first else { fatalError() } - MXLog.verbose("Insert at \(update.index), current total count: \(itemProxies.count)") - let itemProxy = TimelineItemProxy(item: update.item) - changes.append(.insert(offset: Int(update.index), element: itemProxy, associatedWith: nil)) - case .move: - guard let update = diff.move() else { - fatalError() - } - - MXLog.verbose("Move from: \(update.oldIndex) to: \(update.newIndex), current total count: \(itemProxies.count)") - let itemProxy = itemProxies[Int(update.oldIndex)] - changes.append(.remove(offset: Int(update.oldIndex), element: itemProxy, associatedWith: nil)) - changes.append(.insert(offset: Int(update.newIndex), element: itemProxy, associatedWith: nil)) - case .removeAt: - guard let index = diff.removeAt() else { - fatalError() - } + changes.append(.remove(offset: 0, element: itemProxy, associatedWith: nil)) + case .popBack: + MXLog.verbose("Pop Back, current total count: \(itemProxies.count)") + guard let itemProxy = itemProxies.last else { fatalError() } - MXLog.verbose("Remove from: \(index), current total count: \(itemProxies.count)") + changes.append(.remove(offset: itemProxies.count - 1, element: itemProxy, associatedWith: nil)) + case .remove: + guard let index = diff.remove() else { fatalError() } + + MXLog.verbose("Remove item at: \(index), current total count: \(itemProxies.count)") let itemProxy = itemProxies[Int(index)] changes.append(.remove(offset: Int(index), element: itemProxy, associatedWith: nil)) - case .replace: - guard let items = diff.replace() else { - fatalError() + case .clear: + MXLog.verbose("Clear all items, current total count: \(itemProxies.count)") + for (index, itemProxy) in itemProxies.enumerated() { + changes.append(.remove(offset: index, element: itemProxy, associatedWith: nil)) } + case .reset: + guard let items = diff.reset() else { fatalError() } MXLog.verbose("Replace all items with new count: \(items.count), current total count: \(itemProxies.count)") for (index, itemProxy) in itemProxies.enumerated() { changes.append(.remove(offset: index, element: itemProxy, associatedWith: nil)) } - for (index, item) in items.enumerated() { - changes.append(.insert(offset: index, element: TimelineItemProxy(item: item), associatedWith: nil)) + for (index, timelineItem) in items.enumerated() { + changes.append(.insert(offset: index, element: TimelineItemProxy(item: timelineItem), associatedWith: nil)) } - case .clear: - MXLog.verbose("Clear all items, current total count: \(itemProxies.count)") - for (index, itemProxy) in itemProxies.enumerated() { - changes.append(.remove(offset: index, element: itemProxy, associatedWith: nil)) - } - case .pop: - MXLog.verbose("Pop, current total count: \(itemProxies.count)") - guard let itemProxy = itemProxies.last else { - fatalError() - } - - changes.append(.remove(offset: itemProxies.count - 1, element: itemProxy, associatedWith: nil)) } return CollectionDifference(changes) diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactory.swift b/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactory.swift index 57e2b5b10..c2c80fcf4 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactory.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/RoomTimelineItemFactory.swift @@ -78,6 +78,9 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol { case .emote(content: let content): let message = MessageTimelineItem(item: eventItemProxy.item, content: content) return buildEmoteTimelineItemFromMessage(eventItemProxy, message, isOutgoing, groupState) + case .audio: + #warning("Audio timeline items not currently supported") + return nil case .none: return buildFallbackTimelineItem(eventItemProxy, isOutgoing, groupState) } diff --git a/NSE/Sources/Other/NotificationItemProxy+NSE.swift b/NSE/Sources/Other/NotificationItemProxy+NSE.swift index 60a0f8dba..26a0ad396 100644 --- a/NSE/Sources/Other/NotificationItemProxy+NSE.swift +++ b/NSE/Sources/Other/NotificationItemProxy+NSE.swift @@ -94,6 +94,9 @@ extension NotificationItemProxy { senderId: senderId, roomId: roomId, mediaProvider: mediaProvider) + case .audio: + #warning("Audio timeline items not currently supported") + return nil case .video(content: let content): return try await processVideo(content: content, senderId: senderId, diff --git a/project.yml b/project.yml index 63a2c63f1..dfb62bccd 100644 --- a/project.yml +++ b/project.yml @@ -40,7 +40,7 @@ include: packages: MatrixRustSDK: url: https://github.com/matrix-org/matrix-rust-components-swift - exactVersion: 1.0.38-alpha + exactVersion: 1.0.40-alpha # path: ../matrix-rust-sdk DesignKit: path: DesignKit