mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-05 11:58:32 +00:00
Added room timeline screen with live events listening and back pagination. Rearranged project files.
This commit is contained in:
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user