Added room timeline screen with live events listening and back pagination. Rearranged project files.

This commit is contained in:
Stefan Ceriu
2022-03-08 14:24:33 +02:00
parent f403c59b95
commit c22d9689d4
77 changed files with 1269 additions and 491 deletions
@@ -0,0 +1,20 @@
//
// MockRoomTimelineController.swift
// ElementX
//
// Created by Stefan Ceriu on 04.03.2022.
// Copyright © 2022 Element. All rights reserved.
//
import Foundation
import Combine
class MockRoomTimelineController: RoomTimelineControllerProtocol {
let timelineItems: [RoomTimelineItemProtocol] = [TextRoomTimelineItem(id: UUID().uuidString, senderDisplayName: "Anne", text: "You rock!", originServerTs: .now),
TextRoomTimelineItem(id: UUID().uuidString, senderDisplayName: "Bob", text: "You rule!", originServerTs: .now)]
let callbacks = PassthroughSubject<RoomTimelineControllerCallback, Never>()
func paginateBackwards(_ count: UInt) {
}
}
@@ -0,0 +1,48 @@
//
// RoomTimelineController.swift
// ElementX
//
// Created by Stefan Ceriu on 04.03.2022.
// Copyright © 2022 Element. All rights reserved.
//
import Foundation
import Combine
import MatrixRustSDK
enum RoomTimelineControllerCallback {
case updatedTimelineItems
}
class RoomTimelineController: RoomTimelineControllerProtocol {
private let timelineProvider: RoomTimelineProvider
private var cancellables = Set<AnyCancellable>()
let callbacks = PassthroughSubject<RoomTimelineControllerCallback, Never>()
private(set) var timelineItems = [RoomTimelineItemProtocol]()
init(timelineProvider: RoomTimelineProvider) {
self.timelineProvider = timelineProvider
self.timelineProvider.callbacks.sink { [weak self] callback in
guard let self = self else { return }
switch callback {
case .updatedMessages:
self.timelineItems = self.timelineProvider.messages.map { message in
let timestamp = Date(timeIntervalSince1970: TimeInterval(message.originServerTs()))
return TextRoomTimelineItem(id: message.id(),
senderDisplayName: message.sender(),
text: message.content(),
originServerTs: timestamp)
}
self.callbacks.send(.updatedTimelineItems)
}
}.store(in: &cancellables)
}
func paginateBackwards(_ count: UInt) {
timelineProvider.paginateBackwards(count)
}
}
@@ -0,0 +1,17 @@
//
// RoomTimelineControllerProtocol.swift
// ElementX
//
// Created by Stefan Ceriu on 04.03.2022.
// Copyright © 2022 Element. All rights reserved.
//
import Foundation
import Combine
protocol RoomTimelineControllerProtocol {
var timelineItems: [RoomTimelineItemProtocol] { get }
var callbacks: PassthroughSubject<RoomTimelineControllerCallback, Never> { get }
func paginateBackwards(_ count: UInt)
}
@@ -0,0 +1,16 @@
//
// RoomTimelineItemProtocol.swift
// ElementX
//
// Created by Stefan Ceriu on 04.03.2022.
// Copyright © 2022 Element. All rights reserved.
//
import Foundation
protocol RoomTimelineItemProtocol {
var id: String { get }
var senderDisplayName: String { get }
var text: String { get }
var originServerTs: Date { get }
}
@@ -0,0 +1,61 @@
//
// RoomTimeline.swift
// ElementX
//
// Created by Stefan Ceriu on 04.03.2022.
// Copyright © 2022 Element. All rights reserved.
//
import Foundation
import Combine
import MatrixRustSDK
enum RoomTimelineCallback {
case updatedMessages
}
class RoomTimelineProvider {
private let roomProxy: RoomProxyProtocol
private var cancellables = Set<AnyCancellable>()
private var paginationCounter: UInt = 0
private var isWaitingPaginationResponse = false
let callbacks = PassthroughSubject<RoomTimelineCallback, Never>()
private(set) var messages = [Message]()
init(roomProxy: RoomProxyProtocol) {
self.roomProxy = roomProxy
self.roomProxy.startLiveEventListener()
self.roomProxy.callbacks.sink { [weak self] callback in
guard let self = self else { return }
switch callback {
case .addedMessage(let message):
self.messages.append(message)
case .prependedMessages(let messages):
self.messages.insert(contentsOf: messages.reversed(), at: 0)
self.isWaitingPaginationResponse = false
case .updatedLastMessage:
break
}
self.callbacks.send(.updatedMessages)
}.store(in: &cancellables)
}
func paginateBackwards(_ count: UInt) {
if isWaitingPaginationResponse {
return
}
self.roomProxy.paginateBackwards(start: paginationCounter, finish: count)
isWaitingPaginationResponse = true
// This is not in any way correct but it will do for now.
self.paginationCounter += count
}
}
@@ -0,0 +1,16 @@
//
// TextRoomTimelineItem.swift
// ElementX
//
// Created by Stefan Ceriu on 04.03.2022.
// Copyright © 2022 Element. All rights reserved.
//
import Foundation
struct TextRoomTimelineItem: RoomTimelineItemProtocol {
let id: String
let senderDisplayName: String
let text: String
let originServerTs: Date
}