mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 19:44:05 +00:00
New SlidingSync flow (#373)
* Switch back to using slidingSync rooms for timeline listeners * Expose 2 types of slidingSync views from the clientProxy and combine their results for the roomList * Fix breaking api changes * Remove sender mxids from the room list (until rust provides resolved display names) * Bump RustSDK to v1.0.22-alpha * Rename originServerTs to timestamp throughout * Simplified sliding sync view list merging * Rollback some SS changes as things still don't work properly * Revert "Switch back to using slidingSync rooms for timeline listeners" This reverts commit 1d6a6c09d8ddf386edefbe0ac6beaf52cc333fba.
This commit is contained in:
@@ -3759,7 +3759,7 @@
|
|||||||
repositoryURL = "https://github.com/matrix-org/matrix-rust-components-swift";
|
repositoryURL = "https://github.com/matrix-org/matrix-rust-components-swift";
|
||||||
requirement = {
|
requirement = {
|
||||||
kind = exactVersion;
|
kind = exactVersion;
|
||||||
version = "0.0.9-demo";
|
version = "1.0.22-alpha";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
96495DD8554E2F39D3954354 /* XCRemoteSwiftPackageReference "posthog-ios" */ = {
|
96495DD8554E2F39D3954354 /* XCRemoteSwiftPackageReference "posthog-ios" */ = {
|
||||||
|
|||||||
@@ -86,8 +86,8 @@
|
|||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/matrix-org/matrix-rust-components-swift",
|
"location" : "https://github.com/matrix-org/matrix-rust-components-swift",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "2645cfb64f3255f299a63af280b5172a6dd6602c",
|
"revision" : "65d6f8a51367d5c411c1fec39402907f588fcd67",
|
||||||
"version" : "0.0.9-demo"
|
"version" : "1.0.22-alpha"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ typealias HomeScreenViewModelType = StateStoreViewModel<HomeScreenViewState, Hom
|
|||||||
|
|
||||||
class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol {
|
class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol {
|
||||||
private let userSession: UserSessionProtocol
|
private let userSession: UserSessionProtocol
|
||||||
private let roomSummaryProvider: RoomSummaryProviderProtocol?
|
private let visibleRoomsSummaryProvider: RoomSummaryProviderProtocol?
|
||||||
|
private let allRoomsSummaryProvider: RoomSummaryProviderProtocol?
|
||||||
private let attributedStringBuilder: AttributedStringBuilderProtocol
|
private let attributedStringBuilder: AttributedStringBuilderProtocol
|
||||||
private var roomsForIdentifiers = [String: HomeScreenRoom]()
|
private var roomsForIdentifiers = [String: HomeScreenRoom]()
|
||||||
|
|
||||||
@@ -32,9 +33,11 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
// swiftlint:disable:next function_body_length
|
// swiftlint:disable:next function_body_length
|
||||||
init(userSession: UserSessionProtocol, attributedStringBuilder: AttributedStringBuilderProtocol) {
|
init(userSession: UserSessionProtocol, attributedStringBuilder: AttributedStringBuilderProtocol) {
|
||||||
self.userSession = userSession
|
self.userSession = userSession
|
||||||
roomSummaryProvider = userSession.clientProxy.roomSummaryProvider
|
|
||||||
self.attributedStringBuilder = attributedStringBuilder
|
self.attributedStringBuilder = attributedStringBuilder
|
||||||
|
|
||||||
|
visibleRoomsSummaryProvider = userSession.clientProxy.visibleRoomsSummaryProvider
|
||||||
|
allRoomsSummaryProvider = userSession.clientProxy.allRoomsSummaryProvider
|
||||||
|
|
||||||
super.init(initialViewState: HomeScreenViewState(userID: userSession.userID))
|
super.init(initialViewState: HomeScreenViewState(userID: userSession.userID))
|
||||||
|
|
||||||
userSession.callbacks
|
userSession.callbacks
|
||||||
@@ -65,14 +68,15 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let roomSummaryProvider else {
|
guard let visibleRoomsSummaryProvider, let allRoomsSummaryProvider else {
|
||||||
MXLog.error("Room summary provider unavailable")
|
MXLog.error("Room summary provider unavailable")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
Publishers.CombineLatest3(roomSummaryProvider.statePublisher,
|
// Combine all 3 publishers to correctly compute the screen state
|
||||||
roomSummaryProvider.countPublisher,
|
Publishers.CombineLatest3(visibleRoomsSummaryProvider.statePublisher,
|
||||||
roomSummaryProvider.roomListPublisher)
|
visibleRoomsSummaryProvider.countPublisher,
|
||||||
|
visibleRoomsSummaryProvider.roomListPublisher)
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
.sink { [weak self] state, totalCount, rooms in
|
.sink { [weak self] state, totalCount, rooms in
|
||||||
if state != .live {
|
if state != .live {
|
||||||
@@ -89,7 +93,16 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
roomSummaryProvider.roomListPublisher
|
// Listen to changes from both roomSummaryProviders and update state accordingly
|
||||||
|
|
||||||
|
visibleRoomsSummaryProvider.roomListPublisher
|
||||||
|
.receive(on: DispatchQueue.main)
|
||||||
|
.sink { [weak self] _ in
|
||||||
|
self?.updateRooms()
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
allRoomsSummaryProvider.roomListPublisher
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
.sink { [weak self] _ in
|
.sink { [weak self] _ in
|
||||||
self?.updateRooms()
|
self?.updateRooms()
|
||||||
@@ -127,12 +140,12 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
private func loadDataForRoomIdentifier(_ identifier: String) {
|
private func loadDataForRoomIdentifier(_ identifier: String) {
|
||||||
guard let roomSummaryProvider else {
|
guard let visibleRoomsSummaryProvider else {
|
||||||
MXLog.error("Room summary provider unavailable")
|
MXLog.error("Room summary provider unavailable")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let roomSummary = roomSummaryProvider.roomListPublisher.value.first(where: { $0.asFilled?.id == identifier })?.asFilled,
|
guard let roomSummary = visibleRoomsSummaryProvider.roomListPublisher.value.first(where: { $0.asFilled?.id == identifier })?.asFilled,
|
||||||
let roomIndex = state.rooms.firstIndex(where: { $0.id == identifier }) else {
|
let roomIndex = state.rooms.firstIndex(where: { $0.id == identifier }) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -153,8 +166,11 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This method will update all view state rooms by merging the data from both summary providers
|
||||||
|
/// If a room is empty in the visible room summary provider it will try to get it from the allRooms one
|
||||||
|
/// This ensures that we show as many room details as possible without loading up timelines
|
||||||
private func updateRooms() {
|
private func updateRooms() {
|
||||||
guard let roomSummaryProvider else {
|
guard let visibleRoomsSummaryProvider else {
|
||||||
MXLog.error("Room summary provider unavailable")
|
MXLog.error("Room summary provider unavailable")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -162,27 +178,19 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
var rooms = [HomeScreenRoom]()
|
var rooms = [HomeScreenRoom]()
|
||||||
var newRoomsForIdentifiers = [String: HomeScreenRoom]()
|
var newRoomsForIdentifiers = [String: HomeScreenRoom]()
|
||||||
|
|
||||||
for summary in roomSummaryProvider.roomListPublisher.value {
|
for (index, summary) in visibleRoomsSummaryProvider.roomListPublisher.value.enumerated() {
|
||||||
switch summary {
|
switch summary {
|
||||||
case .empty(let id):
|
case .empty(let id):
|
||||||
rooms.append(HomeScreenRoom.placeholder(id: id))
|
guard case let .filled(summary) = allRoomsSummaryProvider?.roomListPublisher.value[safe: index] else {
|
||||||
case .filled(let summary):
|
rooms.append(HomeScreenRoom.placeholder(id: id))
|
||||||
let oldRoom = roomsForIdentifiers[summary.id]
|
continue
|
||||||
|
|
||||||
let avatarImage = userSession.mediaProvider.imageFromURLString(summary.avatarURLString, avatarSize: .room(on: .home))
|
|
||||||
|
|
||||||
var timestamp: String?
|
|
||||||
if let lastMessageTimestamp = summary.lastMessageTimestamp {
|
|
||||||
timestamp = lastMessageTimestamp.formatted(date: .omitted, time: .shortened)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let room = HomeScreenRoom(id: summary.id,
|
let room = buildRoomForSummary(summary)
|
||||||
name: summary.name,
|
rooms.append(room)
|
||||||
hasUnreads: summary.unreadNotificationCount > 0,
|
newRoomsForIdentifiers[summary.id] = room
|
||||||
timestamp: timestamp ?? oldRoom?.timestamp,
|
case .filled(let summary):
|
||||||
lastMessage: summary.lastMessage ?? oldRoom?.lastMessage,
|
let room = buildRoomForSummary(summary)
|
||||||
avatar: avatarImage ?? oldRoom?.avatar)
|
|
||||||
|
|
||||||
rooms.append(room)
|
rooms.append(room)
|
||||||
newRoomsForIdentifiers[summary.id] = room
|
newRoomsForIdentifiers[summary.id] = room
|
||||||
}
|
}
|
||||||
@@ -192,6 +200,24 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
roomsForIdentifiers = newRoomsForIdentifiers
|
roomsForIdentifiers = newRoomsForIdentifiers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func buildRoomForSummary(_ summary: RoomSummaryDetails) -> HomeScreenRoom {
|
||||||
|
let oldRoom = roomsForIdentifiers[summary.id]
|
||||||
|
|
||||||
|
let avatarImage = userSession.mediaProvider.imageFromURLString(summary.avatarURLString, avatarSize: .room(on: .home))
|
||||||
|
|
||||||
|
var timestamp: String?
|
||||||
|
if let lastMessageTimestamp = summary.lastMessageTimestamp {
|
||||||
|
timestamp = lastMessageTimestamp.formatted(date: .omitted, time: .shortened)
|
||||||
|
}
|
||||||
|
|
||||||
|
return HomeScreenRoom(id: summary.id,
|
||||||
|
name: summary.name,
|
||||||
|
hasUnreads: summary.unreadNotificationCount > 0,
|
||||||
|
timestamp: timestamp ?? oldRoom?.timestamp,
|
||||||
|
lastMessage: summary.lastMessage ?? oldRoom?.lastMessage,
|
||||||
|
avatar: avatarImage ?? oldRoom?.avatar)
|
||||||
|
}
|
||||||
|
|
||||||
private func updateVisibleRange(visibleItemIdentifiers items: Set<String>) {
|
private func updateVisibleRange(visibleItemIdentifiers items: Set<String>) {
|
||||||
let result = items.compactMap { itemIdentifier in
|
let result = items.compactMap { itemIdentifier in
|
||||||
state.rooms.firstIndex { $0.id == itemIdentifier }
|
state.rooms.firstIndex { $0.id == itemIdentifier }
|
||||||
@@ -205,6 +231,6 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
userSession.clientProxy.roomSummaryProvider?.updateVisibleRange(lowerBound...upperBound)
|
visibleRoomsSummaryProvider?.updateVisibleRange(lowerBound...upperBound)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
private var slidingSyncObserverToken: StoppableSpawn?
|
private var slidingSyncObserverToken: StoppableSpawn?
|
||||||
private var slidingSync: SlidingSync?
|
private var slidingSync: SlidingSync?
|
||||||
|
|
||||||
var roomSummaryProvider: RoomSummaryProviderProtocol?
|
var visibleRoomsSummaryProvider: RoomSummaryProviderProtocol?
|
||||||
|
|
||||||
|
var allRoomsSummaryProvider: RoomSummaryProviderProtocol?
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
// These need to be inlined instead of using stopSync()
|
// These need to be inlined instead of using stopSync()
|
||||||
@@ -83,25 +85,40 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
do {
|
do {
|
||||||
let slidingSyncBuilder = try client.slidingSync().homeserver(url: ServiceLocator.shared.settings.slidingSyncProxyBaseURLString)
|
let slidingSyncBuilder = try client.slidingSync().homeserver(url: ServiceLocator.shared.settings.slidingSyncProxyBaseURLString)
|
||||||
|
|
||||||
let slidingSyncView = try SlidingSyncViewBuilder()
|
let visibleRoomsView = try SlidingSyncViewBuilder()
|
||||||
.timelineLimit(limit: 10)
|
.timelineLimit(limit: 10)
|
||||||
.requiredState(requiredState: [RequiredState(key: "m.room.avatar", value: ""),
|
.requiredState(requiredState: [RequiredState(key: "m.room.avatar", value: ""),
|
||||||
RequiredState(key: "m.room.encryption", value: "")])
|
RequiredState(key: "m.room.encryption", value: "")])
|
||||||
.name(name: "HomeScreenView")
|
.name(name: "CurrentlyVisibleRooms")
|
||||||
.syncMode(mode: .selective)
|
.syncMode(mode: .selective)
|
||||||
.addRange(from: 0, to: 20)
|
.addRange(from: 0, to: 20)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
let allRoomsView = try SlidingSyncViewBuilder()
|
||||||
|
.noTimelineLimit()
|
||||||
|
.requiredState(requiredState: [RequiredState(key: "m.room.avatar", value: ""),
|
||||||
|
RequiredState(key: "m.room.encryption", value: "")])
|
||||||
|
.name(name: "AllRooms")
|
||||||
|
.syncMode(mode: .growingFullSync)
|
||||||
|
.batchSize(batchSize: 20)
|
||||||
|
.build()
|
||||||
|
|
||||||
let slidingSync = try slidingSyncBuilder
|
let slidingSync = try slidingSyncBuilder
|
||||||
.addView(v: slidingSyncView)
|
.addView(v: visibleRoomsView)
|
||||||
|
// .addView(v: allRoomsView) // FIXME: Intentionally disabled as it doesn't work properly
|
||||||
.withCommonExtensions()
|
.withCommonExtensions()
|
||||||
.coldCache(name: "ElementX")
|
.coldCache(name: "ElementX")
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
let slidingSyncViewProxy = SlidingSyncViewProxy(clientProxy: self, slidingSync: slidingSync, slidingSyncView: slidingSyncView)
|
let visibleRoomsViewProxy = SlidingSyncViewProxy(clientProxy: self, slidingSync: slidingSync, slidingSyncView: visibleRoomsView)
|
||||||
|
|
||||||
self.roomSummaryProvider = RoomSummaryProvider(slidingSyncViewProxy: slidingSyncViewProxy,
|
let allRoomsViewProxy = SlidingSyncViewProxy(clientProxy: self, slidingSync: slidingSync, slidingSyncView: allRoomsView)
|
||||||
roomMessageFactory: RoomMessageFactory())
|
|
||||||
|
self.visibleRoomsSummaryProvider = RoomSummaryProvider(slidingSyncViewProxy: visibleRoomsViewProxy,
|
||||||
|
roomMessageFactory: RoomMessageFactory())
|
||||||
|
|
||||||
|
self.allRoomsSummaryProvider = RoomSummaryProvider(slidingSyncViewProxy: allRoomsViewProxy,
|
||||||
|
roomMessageFactory: RoomMessageFactory())
|
||||||
|
|
||||||
self.slidingSync = slidingSync
|
self.slidingSync = slidingSync
|
||||||
} catch {
|
} catch {
|
||||||
@@ -286,7 +303,8 @@ class ClientProxy: ClientProxyProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fileprivate func didReceiveSlidingSyncUpdate(summary: UpdateSummary) {
|
fileprivate func didReceiveSlidingSyncUpdate(summary: UpdateSummary) {
|
||||||
roomSummaryProvider?.updateRoomsWithIdentifiers(summary.rooms)
|
visibleRoomsSummaryProvider?.updateRoomsWithIdentifiers(summary.rooms)
|
||||||
|
allRoomsSummaryProvider?.updateRoomsWithIdentifiers(summary.rooms)
|
||||||
|
|
||||||
callbacks.send(.receivedSyncUpdate)
|
callbacks.send(.receivedSyncUpdate)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,9 @@ protocol ClientProxyProtocol: AnyObject, MediaProxyProtocol {
|
|||||||
|
|
||||||
var restorationToken: RestorationToken? { get }
|
var restorationToken: RestorationToken? { get }
|
||||||
|
|
||||||
var roomSummaryProvider: RoomSummaryProviderProtocol? { get }
|
var visibleRoomsSummaryProvider: RoomSummaryProviderProtocol? { get }
|
||||||
|
|
||||||
|
var allRoomsSummaryProvider: RoomSummaryProviderProtocol? { get }
|
||||||
|
|
||||||
func startSync()
|
func startSync()
|
||||||
|
|
||||||
|
|||||||
@@ -27,11 +27,13 @@ class MockClientProxy: ClientProxyProtocol {
|
|||||||
let homeserver = ""
|
let homeserver = ""
|
||||||
let restorationToken: RestorationToken? = nil
|
let restorationToken: RestorationToken? = nil
|
||||||
|
|
||||||
var roomSummaryProvider: RoomSummaryProviderProtocol? = MockRoomSummaryProvider()
|
var visibleRoomsSummaryProvider: RoomSummaryProviderProtocol? = MockRoomSummaryProvider()
|
||||||
|
|
||||||
|
var allRoomsSummaryProvider: RoomSummaryProviderProtocol? = MockRoomSummaryProvider()
|
||||||
|
|
||||||
internal init(userIdentifier: String, roomSummaryProvider: RoomSummaryProviderProtocol? = MockRoomSummaryProvider()) {
|
internal init(userIdentifier: String, roomSummaryProvider: RoomSummaryProviderProtocol? = MockRoomSummaryProvider()) {
|
||||||
self.userIdentifier = userIdentifier
|
self.userIdentifier = userIdentifier
|
||||||
self.roomSummaryProvider = roomSummaryProvider
|
visibleRoomsSummaryProvider = roomSummaryProvider
|
||||||
}
|
}
|
||||||
|
|
||||||
func startSync() { }
|
func startSync() { }
|
||||||
|
|||||||
@@ -20,5 +20,5 @@ protocol RoomMessageProtocol {
|
|||||||
var id: String { get }
|
var id: String { get }
|
||||||
var body: String { get }
|
var body: String { get }
|
||||||
var sender: String { get }
|
var sender: String { get }
|
||||||
var originServerTs: Date { get }
|
var timestamp: Date { get }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ struct SomeRoomMessage: RoomMessageProtocol {
|
|||||||
let id: String
|
let id: String
|
||||||
let body: String
|
let body: String
|
||||||
let sender: String
|
let sender: String
|
||||||
let originServerTs: Date
|
let timestamp: Date
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RoomMessageFactory: RoomMessageFactoryProtocol {
|
struct RoomMessageFactory: RoomMessageFactoryProtocol {
|
||||||
@@ -29,6 +29,6 @@ struct RoomMessageFactory: RoomMessageFactoryProtocol {
|
|||||||
SomeRoomMessage(id: eventItemProxy.id,
|
SomeRoomMessage(id: eventItemProxy.id,
|
||||||
body: eventItemProxy.body ?? "",
|
body: eventItemProxy.body ?? "",
|
||||||
sender: eventItemProxy.sender,
|
sender: eventItemProxy.sender,
|
||||||
originServerTs: eventItemProxy.originServerTs)
|
timestamp: eventItemProxy.timestamp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,9 +63,9 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
|||||||
|
|
||||||
func updateRoomsWithIdentifiers(_ identifiers: [String]) {
|
func updateRoomsWithIdentifiers(_ identifiers: [String]) {
|
||||||
#warning("This is a valid check but Rust doesn't set it correctly for selective ranged syncs")
|
#warning("This is a valid check but Rust doesn't set it correctly for selective ranged syncs")
|
||||||
// guard statePublisher.value == .live else {
|
// guard statePublisher.value == .live else {
|
||||||
// return
|
// return
|
||||||
// }
|
// }
|
||||||
|
|
||||||
var changes = [CollectionDifference<RoomSummary>.Change]()
|
var changes = [CollectionDifference<RoomSummary>.Change]()
|
||||||
for identifier in identifiers {
|
for identifier in identifiers {
|
||||||
@@ -136,11 +136,14 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
|||||||
var lastMessageTimestamp: Date?
|
var lastMessageTimestamp: Date?
|
||||||
if let latestRoomMessage = room.latestRoomMessage() {
|
if let latestRoomMessage = room.latestRoomMessage() {
|
||||||
let lastMessage = roomMessageFactory.buildRoomMessageFrom(EventTimelineItemProxy(item: latestRoomMessage))
|
let lastMessage = roomMessageFactory.buildRoomMessageFrom(EventTimelineItemProxy(item: latestRoomMessage))
|
||||||
if let lastMessageSender = try? AttributedString(markdown: "**\(lastMessage.sender)**") {
|
|
||||||
// Don't include the message body in the markdown otherwise it makes tappable links.
|
#warning("Intentionally remove the sender mxid from the room list for now")
|
||||||
attributedLastMessage = lastMessageSender + ": " + AttributedString(lastMessage.body)
|
// if let lastMessageSender = try? AttributedString(markdown: "**\(lastMessage.sender)**") {
|
||||||
}
|
// // Don't include the message body in the markdown otherwise it makes tappable links.
|
||||||
lastMessageTimestamp = lastMessage.originServerTs
|
// attributedLastMessage = lastMessageSender + ": " + AttributedString(lastMessage.body)
|
||||||
|
// }
|
||||||
|
attributedLastMessage = AttributedString(lastMessage.body)
|
||||||
|
lastMessageTimestamp = lastMessage.timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
return .filled(details: RoomSummaryDetails(id: room.roomId(),
|
return .filled(details: RoomSummaryDetails(id: room.roomId(),
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ struct MessageTimelineItem<Content: MessageContentProtocol> {
|
|||||||
case .transactionId:
|
case .transactionId:
|
||||||
return .sending
|
return .sending
|
||||||
case .eventId:
|
case .eventId:
|
||||||
return .sent(elapsedTime: Date().timeIntervalSince1970 - originServerTs.timeIntervalSince1970)
|
return .sent(elapsedTime: Date().timeIntervalSince1970 - timestamp.timeIntervalSince1970)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,12 +77,8 @@ struct MessageTimelineItem<Content: MessageContentProtocol> {
|
|||||||
item.sender()
|
item.sender()
|
||||||
}
|
}
|
||||||
|
|
||||||
var originServerTs: Date {
|
var timestamp: Date {
|
||||||
if let timestamp = item.originServerTs() {
|
Date(timeIntervalSince1970: TimeInterval(item.timestamp() / 1000))
|
||||||
return Date(timeIntervalSince1970: TimeInterval(timestamp / 1000))
|
|
||||||
} else {
|
|
||||||
return .now
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,12 +91,8 @@ struct EventTimelineItemProxy: CustomDebugStringConvertible {
|
|||||||
item.reactions()
|
item.reactions()
|
||||||
}
|
}
|
||||||
|
|
||||||
var originServerTs: Date {
|
var timestamp: Date {
|
||||||
if let timestamp = item.originServerTs() {
|
Date(timeIntervalSince1970: TimeInterval(item.timestamp() / 1000))
|
||||||
return Date(timeIntervalSince1970: TimeInterval(timestamp / 1000))
|
|
||||||
} else {
|
|
||||||
return .now
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - CustomDebugStringConvertible
|
// MARK: - CustomDebugStringConvertible
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
|
|||||||
return EncryptedRoomTimelineItem(id: eventItemProxy.id,
|
return EncryptedRoomTimelineItem(id: eventItemProxy.id,
|
||||||
text: ElementL10n.encryptionInformationDecryptionError,
|
text: ElementL10n.encryptionInformationDecryptionError,
|
||||||
encryptionType: encryptionType,
|
encryptionType: encryptionType,
|
||||||
timestamp: eventItemProxy.originServerTs.formatted(date: .omitted, time: .shortened),
|
timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened),
|
||||||
inGroupState: inGroupState,
|
inGroupState: inGroupState,
|
||||||
isOutgoing: isOutgoing,
|
isOutgoing: isOutgoing,
|
||||||
isEditable: eventItemProxy.isEditable,
|
isEditable: eventItemProxy.isEditable,
|
||||||
@@ -115,7 +115,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
|
|||||||
_ avatarImage: UIImage?) -> RoomTimelineItemProtocol {
|
_ avatarImage: UIImage?) -> RoomTimelineItemProtocol {
|
||||||
RedactedRoomTimelineItem(id: eventItemProxy.id,
|
RedactedRoomTimelineItem(id: eventItemProxy.id,
|
||||||
text: ElementL10n.eventRedacted,
|
text: ElementL10n.eventRedacted,
|
||||||
timestamp: eventItemProxy.originServerTs.formatted(date: .omitted, time: .shortened),
|
timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened),
|
||||||
inGroupState: inGroupState,
|
inGroupState: inGroupState,
|
||||||
isOutgoing: isOutgoing,
|
isOutgoing: isOutgoing,
|
||||||
isEditable: eventItemProxy.isEditable,
|
isEditable: eventItemProxy.isEditable,
|
||||||
@@ -136,7 +136,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
|
|||||||
return TextRoomTimelineItem(id: eventItemProxy.id,
|
return TextRoomTimelineItem(id: eventItemProxy.id,
|
||||||
text: eventItemProxy.body ?? "",
|
text: eventItemProxy.body ?? "",
|
||||||
attributedComponents: attributedComponents,
|
attributedComponents: attributedComponents,
|
||||||
timestamp: eventItemProxy.originServerTs.formatted(date: .omitted, time: .shortened),
|
timestamp: eventItemProxy.timestamp.formatted(date: .omitted, time: .shortened),
|
||||||
inGroupState: inGroupState,
|
inGroupState: inGroupState,
|
||||||
isOutgoing: isOutgoing,
|
isOutgoing: isOutgoing,
|
||||||
isEditable: eventItemProxy.isEditable,
|
isEditable: eventItemProxy.isEditable,
|
||||||
@@ -158,7 +158,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
|
|||||||
return TextRoomTimelineItem(id: message.id,
|
return TextRoomTimelineItem(id: message.id,
|
||||||
text: message.body,
|
text: message.body,
|
||||||
attributedComponents: attributedComponents,
|
attributedComponents: attributedComponents,
|
||||||
timestamp: message.originServerTs.formatted(date: .omitted, time: .shortened),
|
timestamp: message.timestamp.formatted(date: .omitted, time: .shortened),
|
||||||
inGroupState: inGroupState,
|
inGroupState: inGroupState,
|
||||||
isOutgoing: isOutgoing,
|
isOutgoing: isOutgoing,
|
||||||
isEditable: message.isEditable,
|
isEditable: message.isEditable,
|
||||||
@@ -183,7 +183,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
|
|||||||
|
|
||||||
return ImageRoomTimelineItem(id: message.id,
|
return ImageRoomTimelineItem(id: message.id,
|
||||||
text: message.body,
|
text: message.body,
|
||||||
timestamp: message.originServerTs.formatted(date: .omitted, time: .shortened),
|
timestamp: message.timestamp.formatted(date: .omitted, time: .shortened),
|
||||||
inGroupState: inGroupState,
|
inGroupState: inGroupState,
|
||||||
isOutgoing: isOutgoing,
|
isOutgoing: isOutgoing,
|
||||||
isEditable: message.isEditable,
|
isEditable: message.isEditable,
|
||||||
@@ -214,7 +214,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
|
|||||||
|
|
||||||
return VideoRoomTimelineItem(id: message.id,
|
return VideoRoomTimelineItem(id: message.id,
|
||||||
text: message.body,
|
text: message.body,
|
||||||
timestamp: message.originServerTs.formatted(date: .omitted, time: .shortened),
|
timestamp: message.timestamp.formatted(date: .omitted, time: .shortened),
|
||||||
inGroupState: inGroupState,
|
inGroupState: inGroupState,
|
||||||
isOutgoing: isOutgoing,
|
isOutgoing: isOutgoing,
|
||||||
isEditable: message.isEditable,
|
isEditable: message.isEditable,
|
||||||
@@ -241,7 +241,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
|
|||||||
_ avatarImage: UIImage?) -> RoomTimelineItemProtocol {
|
_ avatarImage: UIImage?) -> RoomTimelineItemProtocol {
|
||||||
FileRoomTimelineItem(id: message.id,
|
FileRoomTimelineItem(id: message.id,
|
||||||
text: message.body,
|
text: message.body,
|
||||||
timestamp: message.originServerTs.formatted(date: .omitted, time: .shortened),
|
timestamp: message.timestamp.formatted(date: .omitted, time: .shortened),
|
||||||
inGroupState: inGroupState,
|
inGroupState: inGroupState,
|
||||||
isOutgoing: isOutgoing,
|
isOutgoing: isOutgoing,
|
||||||
isEditable: message.isEditable,
|
isEditable: message.isEditable,
|
||||||
@@ -266,7 +266,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
|
|||||||
return NoticeRoomTimelineItem(id: message.id,
|
return NoticeRoomTimelineItem(id: message.id,
|
||||||
text: message.body,
|
text: message.body,
|
||||||
attributedComponents: attributedComponents,
|
attributedComponents: attributedComponents,
|
||||||
timestamp: message.originServerTs.formatted(date: .omitted, time: .shortened),
|
timestamp: message.timestamp.formatted(date: .omitted, time: .shortened),
|
||||||
inGroupState: inGroupState,
|
inGroupState: inGroupState,
|
||||||
isOutgoing: isOutgoing,
|
isOutgoing: isOutgoing,
|
||||||
isEditable: message.isEditable,
|
isEditable: message.isEditable,
|
||||||
@@ -289,7 +289,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
|
|||||||
return EmoteRoomTimelineItem(id: message.id,
|
return EmoteRoomTimelineItem(id: message.id,
|
||||||
text: message.body,
|
text: message.body,
|
||||||
attributedComponents: attributedComponents,
|
attributedComponents: attributedComponents,
|
||||||
timestamp: message.originServerTs.formatted(date: .omitted, time: .shortened),
|
timestamp: message.timestamp.formatted(date: .omitted, time: .shortened),
|
||||||
inGroupState: inGroupState,
|
inGroupState: inGroupState,
|
||||||
isOutgoing: isOutgoing,
|
isOutgoing: isOutgoing,
|
||||||
isEditable: message.isEditable,
|
isEditable: message.isEditable,
|
||||||
|
|||||||
+1
-1
@@ -40,7 +40,7 @@ include:
|
|||||||
packages:
|
packages:
|
||||||
MatrixRustSDK:
|
MatrixRustSDK:
|
||||||
url: https://github.com/matrix-org/matrix-rust-components-swift
|
url: https://github.com/matrix-org/matrix-rust-components-swift
|
||||||
exactVersion: 0.0.9-demo
|
exactVersion: 1.0.22-alpha
|
||||||
# path: ../matrix-rust-components-swift
|
# path: ../matrix-rust-components-swift
|
||||||
DesignKit:
|
DesignKit:
|
||||||
path: ./
|
path: ./
|
||||||
|
|||||||
Reference in New Issue
Block a user