Scroll to latest pending post on button tap

This commit is contained in:
Thomas Ricouard 2023-02-04 14:05:30 +01:00
parent 508b180a1d
commit b57df4a9d7
3 changed files with 17 additions and 3 deletions

View file

@ -8,6 +8,7 @@ class PendingStatusesObserver: ObservableObject {
@Published var pendingStatusesCount: Int = 0
var disableUpdate: Bool = false
var scrollToIndex: ((Int) -> ())?
var pendingStatuses: [String] = [] {
didSet {
@ -27,11 +28,14 @@ class PendingStatusesObserver: ObservableObject {
struct PendingStatusesObserverView: View {
@ObservedObject var observer: PendingStatusesObserver
var body: some View {
if observer.pendingStatusesCount > 0 {
HStack(spacing: 6) {
Spacer()
Button {} label: {
Button {
observer.scrollToIndex?(observer.pendingStatusesCount)
} label: {
Text("\(observer.pendingStatusesCount)")
}
.buttonStyle(.bordered)

View file

@ -63,10 +63,11 @@ public struct TimelineView: View {
}
.onChange(of: viewModel.scrollToIndex) { index in
if let index {
viewModel.scrollToIndex = nil
collectionView?.scrollToItem(at: .init(row: index, section: 0),
at: .top,
animated: false)
animated: viewModel.scrollToIndexAnimated)
viewModel.scrollToIndexAnimated = false
viewModel.scrollToIndex = nil
}
}
.onChange(of: scrollToTopSignal, perform: { _ in

View file

@ -35,6 +35,7 @@ class TimelineViewModel: ObservableObject {
private let cache: TimelineCache = .shared
var scrollToIndexAnimated: Bool = false
@Published var scrollToIndex: Int?
@Published var statusesState: StatusesState = .loading
@ -66,6 +67,13 @@ class TimelineViewModel: ObservableObject {
var serverName: String {
client?.server ?? "Error"
}
init() {
pendingStatusesObserver.scrollToIndex = { [weak self] index in
self?.scrollToIndexAnimated = true
self?.scrollToIndex = index
}
}
private func fetchTag(id: String) async {
guard let client else { return }
@ -225,6 +233,7 @@ extension TimelineViewModel: StatusesFetcher {
if let topStatusId, visibileStatusesIds.contains(topStatusId), scrollToTopVisible {
pendingStatusesObserver.disableUpdate = true
statusesState = .display(statuses: statuses, nextPageState: statuses.count < 20 ? .none : .hasNextPage)
scrollToIndexAnimated = false
scrollToIndex = newStatuses.count + 1
DispatchQueue.main.async {
self.pendingStatusesObserver.disableUpdate = false