Adopting different timeline item types exposed from rust.

This commit is contained in:
Stefan Ceriu
2022-03-16 13:30:55 +02:00
parent 44da96c55f
commit 3cc1395fbc
14 changed files with 219 additions and 73 deletions
@@ -110,7 +110,7 @@ class UserSession: ClientDelegate {
func fetchRoomList(_ completion: @escaping ([RoomProxy]) -> Void) {
DispatchQueue.global(qos: .background).async {
let rooms = self.client.conversations().map {
return RoomProxy(room: $0)
return RoomProxy(room: $0, messageFactory: RoomMessageFactory())
}
DispatchQueue.main.async {
@@ -0,0 +1,34 @@
//
// ImageRoomMessage.swift
// ElementX
//
// Created by Stefan Ceriu on 16/03/2022.
// Copyright © 2022 Element. All rights reserved.
//
import Foundation
import MatrixRustSDK
struct ImageRoomMessage: RoomMessageProtocol {
private let message: MatrixRustSDK.ImageMessage
init(message: MatrixRustSDK.ImageMessage) {
self.message = message
}
var id: String {
message.baseMessage().id()
}
var content: String {
message.baseMessage().content()
}
var sender: String {
message.baseMessage().sender()
}
var originServerTs: Date {
Date(timeIntervalSince1970: TimeInterval(message.baseMessage().originServerTs()))
}
}
@@ -0,0 +1,22 @@
//
// RoomMessageFactory.swift
// ElementX
//
// Created by Stefan Ceriu on 16/03/2022.
// Copyright © 2022 Element. All rights reserved.
//
import Foundation
import MatrixRustSDK
struct RoomMessageFactory {
func buildRoomMessageFrom(_ message: AnyMessage) -> RoomMessageProtocol {
if let textMessage = message.text() {
return TextRoomMessage(message: textMessage)
} else if let imageMessage = message.image() {
return ImageRoomMessage(message: imageMessage)
} else {
fatalError("One of these must exist")
}
}
}
@@ -0,0 +1,16 @@
//
// RoomMessageProtocol.swift
// ElementX
//
// Created by Stefan Ceriu on 16/03/2022.
// Copyright © 2022 Element. All rights reserved.
//
import Foundation
protocol RoomMessageProtocol {
var id: String { get }
var content: String { get }
var sender: String { get }
var originServerTs: Date { get }
}
@@ -0,0 +1,35 @@
//
// TextRoomMessage.swift
// ElementX
//
// Created by Stefan Ceriu on 16/03/2022.
// Copyright © 2022 Element. All rights reserved.
//
import Foundation
import UIKit
import MatrixRustSDK
struct TextRoomMessage: RoomMessageProtocol {
private let message: MatrixRustSDK.TextMessage
init(message: MatrixRustSDK.TextMessage) {
self.message = message
}
var id: String {
message.baseMessage().id()
}
var content: String {
message.baseMessage().content()
}
var sender: String {
message.baseMessage().sender()
}
var originServerTs: Date {
Date(timeIntervalSince1970: TimeInterval(message.baseMessage().originServerTs()))
}
}
@@ -39,7 +39,7 @@ struct MockRoomProxy: RoomProxyProtocol {
}
func paginateBackwards(count: UInt, callback: ((Result<[Message], Error>) -> Void)?) {
func paginateBackwards(count: UInt, callback: ((Result<[RoomMessageProtocol], Error>) -> Void)?) {
}
}
@@ -26,7 +26,7 @@ private class WeakRoomProxyWrapper: RoomDelegate {
// MARK: - RoomDelegate
func didReceiveMessage(message: Message) {
func didReceiveMessage(message: AnyMessage) {
DispatchQueue.main.async {
self.roomProxy?.appendMessage(message)
}
@@ -35,14 +35,16 @@ private class WeakRoomProxyWrapper: RoomDelegate {
class RoomProxy: RoomProxyProtocol, Equatable {
private let room: Room
private let messageFactory: RoomMessageFactory
private let processingQueue: DispatchQueue
private var backwardStream: BackwardsStreamProtocol?
let callbacks = PassthroughSubject<RoomProxyCallback, Never>()
init(room: Room) {
init(room: Room, messageFactory: RoomMessageFactory) {
self.room = room
self.messageFactory = messageFactory
processingQueue = DispatchQueue(label: "RoomProxyProcessingQueue")
processingQueue.async {
@@ -130,7 +132,8 @@ class RoomProxy: RoomProxyProtocol, Equatable {
}
}
func paginateBackwards(count: UInt, callback: ((Result<[Message], Error>) -> Void)?) {
func paginateBackwards(count: UInt, callback: ((Result<[RoomMessageProtocol], Error>) -> Void)?) {
MXLog.debug("Started backpaginating")
processingQueue.async {
guard let backwardStream = self.backwardStream else {
DispatchQueue.main.async {
@@ -139,13 +142,16 @@ class RoomProxy: RoomProxyProtocol, Equatable {
return
}
let messages = backwardStream.paginateBackwards(count: UInt64(count))
let messages = backwardStream.paginateBackwards(count: UInt64(count)).map { message in
self.messageFactory.buildRoomMessageFrom(message)
}
MXLog.debug("Finished backpaginating")
DispatchQueue.main.async {
callback?(.success(messages))
if self.lastMessage == nil {
self.lastMessage = messages.last?.content() ?? ""
self.lastMessage = messages.last?.content ?? ""
}
}
}
@@ -159,12 +165,9 @@ class RoomProxy: RoomProxyProtocol, Equatable {
// MARK: - Private
fileprivate func preprendMessages(_ messages: [Message]) {
}
fileprivate func appendMessage(_ message: Message) {
lastMessage = message.content()
fileprivate func appendMessage(_ message: AnyMessage) {
let message = self.messageFactory.buildRoomMessageFrom(message)
lastMessage = message.content
callbacks.send(.addedMessage(message))
}
@@ -10,7 +10,7 @@ import Combine
import MatrixRustSDK
enum RoomProxyCallback {
case addedMessage(Message)
case addedMessage(RoomMessageProtocol)
case updatedLastMessage
}
@@ -31,7 +31,7 @@ protocol RoomProxyProtocol {
func loadDisplayName(_ completion: @escaping (Result<String, Error>) -> Void)
func loadAvatar(_ completion: @escaping (Result<UIImage?, Error>) -> Void)
func paginateBackwards(count: UInt, callback: ((Result<[Message], Error>) -> Void)?)
func paginateBackwards(count: UInt, callback: ((Result<[RoomMessageProtocol], Error>) -> Void)?)
var callbacks: PassthroughSubject<RoomProxyCallback, Never> { get }
}
@@ -48,27 +48,25 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
private func rebuildTimeline() {
var newTimelineItems = [RoomTimelineViewProvider]()
var previousMessage: Message?
var previousMessage: RoomMessageProtocol?
for message in self.timelineProvider.messages {
let timestamp = Date(timeIntervalSince1970: TimeInterval(message.originServerTs()))
let areMessagesFromTheSameDay = self.haveSameDay(lhs: previousMessage, rhs: message)
let shouldAddSectionHeader = !areMessagesFromTheSameDay
if shouldAddSectionHeader {
let item = SeparatorRoomTimelineItem(id: timestamp.ISO8601Format(),
text: timestamp.formatted(date: .long, time: .omitted))
let item = SeparatorRoomTimelineItem(id: message.originServerTs.ISO8601Format(),
text: message.originServerTs.formatted(date: .long, time: .omitted))
newTimelineItems.append(RoomTimelineViewProvider.separator(item))
}
let areMessagesFromTheSameSender = (previousMessage?.sender() == message.sender())
let areMessagesFromTheSameSender = (previousMessage?.sender == message.sender)
let shouldShowSenderDetails = !areMessagesFromTheSameSender || !areMessagesFromTheSameDay
let item = TextRoomTimelineItem(id: message.id(),
senderDisplayName: message.sender(),
text: message.content(),
timestamp: timestamp.formatted(date: .omitted, time: .shortened),
let item = TextRoomTimelineItem(id: message.id,
senderDisplayName: message.sender,
text: message.content,
timestamp: message.originServerTs.formatted(date: .omitted, time: .shortened),
shouldShowSenderDetails: shouldShowSenderDetails)
newTimelineItems.append(RoomTimelineViewProvider.text(item))
@@ -81,15 +79,11 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
self.callbacks.send(.updatedTimelineItems)
}
private func haveSameDay(lhs: Message?, rhs: Message?) -> Bool {
private func haveSameDay(lhs: RoomMessageProtocol?, rhs: RoomMessageProtocol?) -> Bool {
guard let lhs = lhs, let rhs = rhs else {
return false
}
let lhsTimestamp = Date(timeIntervalSince1970: TimeInterval(lhs.originServerTs()))
let rhsTimestamp = Date(timeIntervalSince1970: TimeInterval(rhs.originServerTs()))
return Calendar.current.isDate(lhsTimestamp, inSameDayAs: rhsTimestamp)
return Calendar.current.isDate(lhs.originServerTs, inSameDayAs: rhs.originServerTs)
}
}
@@ -23,7 +23,7 @@ class RoomTimelineProvider {
private var cancellables = Set<AnyCancellable>()
let callbacks = PassthroughSubject<RoomTimelineCallback, Never>()
private(set) var messages = [Message]()
private(set) var messages = [RoomMessageProtocol]()
init(roomProxy: RoomProxyProtocol) {
self.roomProxy = roomProxy
@@ -41,7 +41,7 @@ class RoomTimelineProvider {
}.store(in: &cancellables)
}
func paginateBackwards(_ count: UInt, callback: ((Result<([Message]), RoomTimelineError>) -> Void)?) {
func paginateBackwards(_ count: UInt, callback: ((Result<([RoomMessageProtocol]), RoomTimelineError>) -> Void)?) {
self.roomProxy.paginateBackwards(count: count) { result in
switch result {
case .success(let messages):
@@ -0,0 +1,15 @@
//
// TimelineItemFactory.swift
// ElementX
//
// Created by Stefan Ceriu on 16/03/2022.
// Copyright © 2022 Element. All rights reserved.
//
import Foundation
struct TimelineItemFactory {
func buildTimelineItemFor(_ message: RoomMessageProtocol) {
}
}