Co-authored-by: Doug <douglase@element.io>
This commit is contained in:
Mauro
2024-05-20 14:37:45 +02:00
committed by GitHub
parent 3b82ce8def
commit 545b5c31cc
15 changed files with 192 additions and 95 deletions
@@ -18,6 +18,12 @@ import Combine
import Foundation
import MatrixRustSDK
enum PaginationStatus {
case idle
case timelineEndReached
case paginating
}
struct PaginationState: Equatable {
static var `default` = PaginationState(backward: .idle, forward: .timelineEndReached)
let backward: PaginationStatus
@@ -59,7 +59,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
return nil
}
return buildStateTimelineItem(for: eventItemProxy, state: content, isOutgoing: isOutgoing)
case .roomMembership(userId: let userID, change: let change):
case .roomMembership(userId: let userID, _, change: let change):
if isDM, change == .joined, userID == self.userID {
return nil
}
@@ -29,7 +29,8 @@ final class TimelineProxy: TimelineProxyProtocol {
// periphery:ignore - retaining purpose
private var timelineListener: RoomTimelineListener?
private let backPaginationStatusSubject = CurrentValueSubject<PaginationStatus, Never>(.idle)
private let backPaginationSubscriptionSubject = CurrentValueSubject<PaginationStatus, Never>(.idle)
private let backPaginationTimelineEndSubject = CurrentValueSubject<Bool, Never>(false)
private let forwardPaginationStatusSubject = CurrentValueSubject<PaginationStatus, Never>(.timelineEndReached)
private let timelineUpdatesSubject = PassthroughSubject<[TimelineDiff], Never>()
@@ -70,7 +71,15 @@ final class TimelineProxy: TimelineProxyProtocol {
let result = await timeline.addListener(listener: timelineListener)
roomTimelineObservationToken = result.itemsStream
let paginationStatePublisher = backPaginationStatusSubject
// Merge the subscription with the paginate method's return value.
let backPaginationPublisher = backPaginationSubscriptionSubject
.combineLatest(backPaginationTimelineEndSubject)
.map { status, timelineEnd in
timelineEnd ? .timelineEndReached : status
}
.eraseToAnyPublisher()
let paginationStatePublisher = backPaginationPublisher
.combineLatest(forwardPaginationStatusSubject)
.map { PaginationState(backward: $0.0, forward: $0.1) }
.eraseToAnyPublisher()
@@ -144,9 +153,11 @@ final class TimelineProxy: TimelineProxyProtocol {
MXLog.info("Paginating backwards")
do {
_ = try await timeline.paginateBackwards(numEvents: requestSize)
let timelineEndReached = try await timeline.paginateBackwards(numEvents: requestSize)
MXLog.info("Finished paginating backwards")
backPaginationTimelineEndSubject.send(timelineEndReached)
return .success(())
} catch {
MXLog.error("Failed paginating backwards with error: \(error)")
@@ -166,7 +177,7 @@ final class TimelineProxy: TimelineProxyProtocol {
forwardPaginationStatusSubject.send(.paginating)
do {
let timelineEndReached = try await timeline.focusedPaginateForwards(numEvents: 16)
let timelineEndReached = try await timeline.focusedPaginateForwards(numEvents: requestSize)
MXLog.info("Finished paginating forwards")
forwardPaginationStatusSubject.send(timelineEndReached ? .timelineEndReached : .idle)
@@ -536,7 +547,16 @@ final class TimelineProxy: TimelineProxyProtocol {
private func subscribeToPagination() {
let backPaginationListener = RoomPaginationStatusListener { [weak self] status in
self?.backPaginationStatusSubject.send(status)
guard let self else {
return
}
switch status {
case .initial, .idle:
backPaginationSubscriptionSubject.send(.idle)
case .fetchingTargetEvent, .paginating:
backPaginationSubscriptionSubject.send(.paginating)
}
}
do {
backPaginationStatusObservationToken = try timeline.subscribeToBackPaginationStatus(listener: backPaginationListener)
@@ -562,13 +582,13 @@ private final class RoomTimelineListener: TimelineListener {
}
private final class RoomPaginationStatusListener: PaginationStatusListener {
private let onUpdateClosure: (PaginationStatus) -> Void
private let onUpdateClosure: (PaginatorState) -> Void
init(_ onUpdateClosure: @escaping (PaginationStatus) -> Void) {
init(_ onUpdateClosure: @escaping (PaginatorState) -> Void) {
self.onUpdateClosure = onUpdateClosure
}
func onUpdate(status: PaginationStatus) {
func onUpdate(status: PaginatorState) {
onUpdateClosure(status)
}
}