mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-11-10 19:20:59 +00:00
Timeline: cleanup datasource near bottom
This commit is contained in:
parent
0b7c6a799f
commit
93421c56d9
3 changed files with 29 additions and 11 deletions
|
@ -65,7 +65,7 @@ public struct StatusesListView<Fetcher>: View where Fetcher: StatusesFetcher {
|
||||||
}
|
}
|
||||||
.padding(.horizontal, .layoutPadding)
|
.padding(.horizontal, .layoutPadding)
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.listRowBackground(theme.primaryBackgroundColor)
|
.listRowBackground(theme.primaryBackgroundColor)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case .none:
|
case .none:
|
||||||
|
|
|
@ -57,7 +57,7 @@ import SwiftUI
|
||||||
}
|
}
|
||||||
|
|
||||||
@ObservationIgnored
|
@ObservationIgnored
|
||||||
private var visibileStatuses: [Status] = []
|
private var visibleStatuses: [Status] = []
|
||||||
|
|
||||||
private var canStreamEvents: Bool = true {
|
private var canStreamEvents: Bool = true {
|
||||||
didSet {
|
didSet {
|
||||||
|
@ -301,6 +301,9 @@ extension TimelineViewModel: StatusesFetcher {
|
||||||
private func updateTimelineWithNewStatuses(_ newStatuses: [Status]) async {
|
private func updateTimelineWithNewStatuses(_ newStatuses: [Status]) async {
|
||||||
let topStatus = await datasource.getFiltered().first
|
let topStatus = await datasource.getFiltered().first
|
||||||
await datasource.insert(contentOf: newStatuses, at: 0)
|
await datasource.insert(contentOf: newStatuses, at: 0)
|
||||||
|
if let lastVisible = visibleStatuses.last {
|
||||||
|
await datasource.remove(after: lastVisible, safeOffset: 15)
|
||||||
|
}
|
||||||
await cache()
|
await cache()
|
||||||
pendingStatusesObserver.pendingStatuses.insert(contentsOf: newStatuses.map(\.id), at: 0)
|
pendingStatusesObserver.pendingStatuses.insert(contentsOf: newStatuses.map(\.id), at: 0)
|
||||||
|
|
||||||
|
@ -308,7 +311,7 @@ extension TimelineViewModel: StatusesFetcher {
|
||||||
let nextPageState: StatusesState.PagingState = statuses.count < 20 ? .none : .hasNextPage
|
let nextPageState: StatusesState.PagingState = statuses.count < 20 ? .none : .hasNextPage
|
||||||
|
|
||||||
if let topStatus = topStatus,
|
if let topStatus = topStatus,
|
||||||
visibileStatuses.contains(where: { $0.id == topStatus.id }),
|
visibleStatuses.contains(where: { $0.id == topStatus.id }),
|
||||||
scrollToTopVisible
|
scrollToTopVisible
|
||||||
{
|
{
|
||||||
updateTimelineWithScrollToTop(newStatuses: newStatuses, statuses: statuses, nextPageState: nextPageState)
|
updateTimelineWithScrollToTop(newStatuses: newStatuses, statuses: statuses, nextPageState: nextPageState)
|
||||||
|
@ -359,17 +362,17 @@ extension TimelineViewModel: StatusesFetcher {
|
||||||
|
|
||||||
func statusDidAppear(status: Status) {
|
func statusDidAppear(status: Status) {
|
||||||
pendingStatusesObserver.removeStatus(status: status)
|
pendingStatusesObserver.removeStatus(status: status)
|
||||||
visibileStatuses.insert(status, at: 0)
|
visibleStatuses.insert(status, at: 0)
|
||||||
|
|
||||||
if let client, timeline.supportNewestPagination {
|
if let client, timeline.supportNewestPagination {
|
||||||
Task {
|
Task {
|
||||||
await cache.setLatestSeenStatuses(visibileStatuses, for: client, filter: timeline.id)
|
await cache.setLatestSeenStatuses(visibleStatuses, for: client, filter: timeline.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func statusDidDisappear(status: Status) {
|
func statusDidDisappear(status: Status) {
|
||||||
visibileStatuses.removeAll(where: { $0.id == status.id })
|
visibleStatuses.removeAll(where: { $0.id == status.id })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,9 +422,10 @@ extension TimelineViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleDeleteEvent(_ event: StreamEventDelete) async {
|
private func handleDeleteEvent(_ event: StreamEventDelete) async {
|
||||||
await datasource.remove(event.status)
|
if let _ = await datasource.remove(event.status) {
|
||||||
await cache()
|
await cache()
|
||||||
await updateStatusesState()
|
await updateStatusesState()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleStatusUpdateEvent(_ event: StreamEventStatusUpdate, client: Client) async {
|
private func handleStatusUpdateEvent(_ event: StreamEventStatusUpdate, client: Client) async {
|
||||||
|
|
|
@ -67,12 +67,26 @@ actor TimelineDatasource {
|
||||||
func insert(contentOf: [Status], at: Int) {
|
func insert(contentOf: [Status], at: Int) {
|
||||||
statuses.insert(contentsOf: contentOf, at: at)
|
statuses.insert(contentsOf: contentOf, at: at)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func remove(after: Status, safeOffset: Int) {
|
||||||
|
if let index = statuses.firstIndex(of: after) {
|
||||||
|
let safeIndex = index + safeOffset
|
||||||
|
if statuses.count > safeIndex {
|
||||||
|
statuses.removeSubrange(safeIndex..<statuses.endIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func replace(_ status: Status, at: Int) {
|
func replace(_ status: Status, at: Int) {
|
||||||
statuses[at] = status
|
statuses[at] = status
|
||||||
}
|
}
|
||||||
|
|
||||||
func remove(_ statusId: String) {
|
func remove(_ statusId: String) -> Status? {
|
||||||
statuses.removeAll(where: { $0.id == statusId })
|
if let index = statuses.firstIndex(where: { status in
|
||||||
|
status.id == statusId
|
||||||
|
}) {
|
||||||
|
return statuses.remove(at: index)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue