Fix back pagination (#432)

* Use pagination and start items for view state.

isBackPaginating and canBackPaginate are updated each time the timeline is rebuilt

* Update some timeline snapshots

The top section has gone, which has altered the layout slightly.
This commit is contained in:
Doug
2023-01-11 09:11:36 +00:00
committed by GitHub
parent 3d1266ca25
commit 08b333839a
24 changed files with 54 additions and 72 deletions
@@ -42,20 +42,7 @@ class MockRoomTimelineController: RoomTimelineControllerProtocol {
}
func paginateBackwards(requestSize: UInt, untilNumberOfItems: UInt) async -> Result<Void, RoomTimelineControllerError> {
callbacks.send(.startedBackPaginating)
guard !backPaginationResponses.isEmpty else {
callbacks.send(.finishedBackPaginating)
return .failure(.generic)
}
let newItems = backPaginationResponses.removeFirst()
try? await Task.sleep(for: backPaginationDelay)
timelineItems.insert(contentsOf: newItems, at: 0)
callbacks.send(.updatedTimelineItems)
callbacks.send(.finishedBackPaginating)
callbacks.send(.canBackPaginate(false))
return .success(())
}
@@ -125,11 +112,12 @@ class MockRoomTimelineController: RoomTimelineControllerProtocol {
/// Prepends the next chunk of items to the `timelineItems` array.
private func simulateBackPagination() async throws {
guard !backPaginationResponses.isEmpty else { return }
callbacks.send(.isBackPaginating(true))
let newItems = backPaginationResponses.removeFirst()
timelineItems.insert(contentsOf: newItems, at: 0)
callbacks.send(.updatedTimelineItems)
callbacks.send(.finishedBackPaginating)
callbacks.send(.isBackPaginating(false))
try? await connection?.send(.success)
}
@@ -61,18 +61,6 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
}
.store(in: &cancellables)
self.timelineProvider
.backPaginationPublisher
.receive(on: DispatchQueue.main)
.sink { [weak self] value in
if value {
self?.callbacks.send(.startedBackPaginating)
} else {
self?.callbacks.send(.finishedBackPaginating)
}
}
.store(in: &cancellables)
updateTimelineItems()
NotificationCenter.default.addObserver(self, selector: #selector(contentSizeCategoryDidChange), name: UIContentSizeCategory.didChangeNotification, object: nil)
@@ -230,6 +218,8 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
// swiftlint:disable:next cyclomatic_complexity
private func asyncUpdateTimelineItems() async {
var newTimelineItems = [RoomTimelineItemProtocol]()
var canBackPaginate = true
var isBackPaginating = false
for (index, itemProxy) in timelineProvider.itemsPublisher.value.enumerated() {
if Task.isCancelled {
@@ -262,8 +252,10 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
}
case .loadingIndicator:
newTimelineItems.append(PaginationIndicatorRoomTimelineItem())
isBackPaginating = true
case .timelineStart:
newTimelineItems.append(TimelineStartRoomTimelineItem(name: roomProxy.displayName ?? roomProxy.name))
canBackPaginate = false
}
default:
break
@@ -277,6 +269,8 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
timelineItems = newTimelineItems
callbacks.send(.updatedTimelineItems)
callbacks.send(.canBackPaginate(canBackPaginate))
callbacks.send(.isBackPaginating(isBackPaginating))
}
private func computeGroupState(for itemProxy: TimelineItemProxy,
@@ -21,8 +21,8 @@ import UIKit
enum RoomTimelineControllerCallback {
case updatedTimelineItems
case updatedTimelineItem(_ itemId: String)
case startedBackPaginating
case finishedBackPaginating
case canBackPaginate(Bool)
case isBackPaginating(Bool)
}
enum RoomTimelineControllerAction {