mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 21:33:26 +00:00
Adopting different timeline item types exposed from rust.
This commit is contained in:
@@ -177,7 +177,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
return
|
||||
}
|
||||
|
||||
self.updateLastMessage(lastMessage.content(), forRoomWithIdentifier: roomIdentifier)
|
||||
self.updateLastMessage(lastMessage.content, forRoomWithIdentifier: roomIdentifier)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
@@ -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()))
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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)?) {
|
||||
|
||||
}
|
||||
}
|
||||
+15
-12
@@ -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))
|
||||
}
|
||||
+2
-2
@@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user