trimming, edge cases

This commit is contained in:
Avently
2025-01-22 13:34:18 -08:00
parent 702e405bb4
commit c52cad5167
5 changed files with 43 additions and 34 deletions
@@ -9,7 +9,7 @@
import SimpleXChat
import SwiftUI
let TRIM_KEEP_COUNT = 20000
let TRIM_KEEP_COUNT = 200
func apiLoadMessages(
_ chatType: ChatType,
@@ -19,6 +19,7 @@ func apiLoadMessages(
_ search: String = "",
_ visibleItemIndexesNonReversed: @MainActor () -> ClosedRange<Int> = { 0 ... 0 }
) async {
//try? await Task.sleep(nanoseconds: 2000_000000)
let chat: Chat
let navInfo: NavigationInfo
do {
@@ -209,6 +210,7 @@ private func removeDuplicatesAndModifySplitsOnBeforePagination(
index += 1
return (invisibleItemToTrim && prevItemWasTrimmed) || newIds.contains($0.id)
})
logger.debug("LALAL TRIMMED COUNT \(trimmedIds.count) \(visibleItemIndexes) \(trimRange) \(prevItemTrimRange)")
// will remove any splits that now becomes obsolete because items were merged
newSplits = newSplits.filter { split in !newIds.contains(split) && !trimmedIds.contains(split) }
return ModifiedSplits(oldUnreadSplitIndex: oldUnreadSplitIndex, newUnreadSplitIndex: newUnreadSplitIndex, trimmedIds: trimmedIds, newSplits: newSplits)
@@ -135,8 +135,8 @@ enum MergedItem: Hashable, Equatable {
var hash: String {
switch self {
case .single(_, _, let hash): hash
case .grouped(_, _, _, _, _, _, _, let hash): hash
case .single(_, _, let hash): hash + " 1"
case .grouped(let items, _, _, _, _, _, _, let hash): hash + " \(items.boxedValue.count)"
}
}
@@ -10,7 +10,6 @@ import SwiftUI
import SimpleXChat
func loadLastItems(_ loadingMoreItems: Binding<Bool>, _ chatInfo: ChatInfo) {
//return ()
if ItemsModel.shared.chatState.totalAfter == 0 {
return
}
@@ -124,6 +123,7 @@ private func findLastIndexToLoadFromInSplits(_ firstVisibleIndex: Int, _ lastVis
return nil
}
// LALAL DELETE?
func tryBlockAndSetLoadingMore(_ loadingMoreItems: Binding<Bool>, _ block: @escaping () async throws -> Void) async {
do {
await MainActor.run {
@@ -577,8 +577,8 @@ struct ComposeView: View {
}
}
.onAppear {
// LALAL
// for i in 301 ... 600 {
//LALAL
// for i in 0 ... 500 {
// Task {
// await sendMessageAsync("\(i)", live: false, ttl: nil)
// }
+35 -28
View File
@@ -114,6 +114,7 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
private var scrollToRowOnAppear = 0
private var prevFirstVisible = -1
private var prevItemsCount = -1
// it's set when .around call will be executed which requires to insert more items and skip scrolling
var scrollToItemInProgress = false
@@ -260,7 +261,7 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
if #available(iOS 16.0, *) {
animated = true
}
if tableView.numberOfRows(inSection: 0) > index && index >= 0 {
if prevSnapshot.numberOfItems > index && index >= 0 {
tableView.scrollToRow(
at: IndexPath(row: index, section: 0),
at: position,
@@ -280,9 +281,7 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
// in case of listener will not be called
await MainActor.run {
representer.scrollState = .atDestination
if let listState = self.getListState() {
self.preloadIfNeeded(listState)
}
self.preloadIfNeeded()
}
} catch {}
}
@@ -290,9 +289,7 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
task.cancel()
self.representer.scrollState = .atDestination
self.runBlockOnEndScrolling = nil
if let listState = self.getListState() {
self.preloadIfNeeded(listState)
}
self.preloadIfNeeded()
}
}
@@ -371,6 +368,9 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
nil
}
let nowFirstIndex: Int? = if let wasFirstId { indexInParentItems[wasFirstId] } else { nil }
//logger.debug("LALAL DIFF start")
//let diff = snapshot.itemIdentifiers.difference(from: prevSnapshot.itemIdentifiers)
//logger.debug("LALAL DIFFERENCES \(diff.insertions.count) \(diff.removals.count)")
self.prevSnapshot = snapshot
self.prevMergedItems = mergedItems
dataSource.apply(
@@ -381,15 +381,15 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
nowFirstIndex - wasFirstIndex
} else { 0 }
//logger.debug("LALAL NEARSPLIT split lower WAS LISTSTATE \(listState?.firstVisibleItemIndex ?? -3) now \(self.getListState()?.firstVisibleItemIndex ?? -4) countDiff \(countDiff) wasFirstIndex \(wasFirstIndex ?? -5) nowIndex \(nowFirstIndex ?? -1) wasFirstId \(wasFirstId ?? -1) count \(self.prevSnapshot.itemIdentifiers.count)")
logger.debug("LALAL NEARSPLIT split lower WAS LISTSTATE \(listState?.firstVisibleItemIndex ?? -3) now \(self.getListState()?.firstVisibleItemIndex ?? -4) countDiff \(countDiff) wasFirstIndex \(wasFirstIndex ?? -5) nowIndex \(nowFirstIndex ?? -1) wasFirstId \(wasFirstId ?? -1) count \(self.prevSnapshot.itemIdentifiers.count)")
if countDiff <= 0 {
if countDiff == 0 {
// added new items to top, nothing to do, scrolling position is correct
} else {
self.stopScrolling()
// added new items to bottom
//logger.debug("LALAL BEFORE SCROLLTOROW \(snapshot.numberOfItems - 1) \(countDiff) \(wasFirstIndex ?? -5) \(self.tableView.contentOffset.y) \(wasFirstVisibleOffset) \(String(describing: self.representer.mergedItems.splits))")
//self.getListState()
logger.debug("LALAL BEFORE SCROLLTOROW \(snapshot.numberOfItems - 1) \(countDiff) \(wasFirstIndex ?? -5) \(self.tableView.contentOffset.y) \(wasFirstVisibleOffset) \(String(describing: self.representer.mergedItems.splits))")
self.getListState()
self.tableView.scrollToRow(
at: IndexPath(row: max(0, min(snapshot.numberOfItems - 1, countDiff + (wasFirstIndex ?? 0))), section: 0),
at: .top,
@@ -429,6 +429,8 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
updatingInProgress = false
tableView.panGestureRecognizer.isEnabled = true
}
// covered edge case when you open a chat with a lot of groupped items which smaller than screen size
self.preloadIfNeeded()
updateFloatingButtons.send()
logger.debug("LALAL STEP 6")
}
@@ -452,7 +454,7 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
}
}
} else {
preloadIfNeeded(listState)
preloadIfNeeded()
}
}
}
@@ -597,23 +599,28 @@ struct ReverseList<Content: View>: UIViewControllerRepresentable {
}
}
func preloadIfNeeded(_ state: ListState) {
func preloadIfNeeded() {
let mergedItems = self.representer.mergedItems
logger.debug("LALAL LOADING BEFORE ANYTHING \(state.firstVisibleItemIndex) \(self.prevSnapshot.itemIdentifiers[state.firstVisibleItemIndex].newest().item.id) \(self.representer.$mergedItems.wrappedValue.items[state.firstVisibleItemIndex].newest().item.id)")
if representer.scrollState == .atDestination, prevFirstVisible != state.firstVisibleItemIndex, !preloading {
logger.debug("LALAL LOADING before \(mergedItems.indexInParentItems.count) \(ItemsModel.shared.reversedChatItems.count)")
prevFirstVisible = state.firstVisibleItemIndex
preloading = true
Task {
defer {
preloading = false
}
logger.debug("LALAL LOADING BEFORE INSIDE \(state.firstVisibleItemIndex) \(self.prevSnapshot.itemIdentifiers[state.firstVisibleItemIndex].newest().item.id) \(mergedItems.items[state.firstVisibleItemIndex].newest().item.id) \(mergedItems.splits)")
await preloadItems(mergedItems, self.representer.allowLoadMoreItems, state, self.representer.$ignoreLoadingRequests) { pagination in
logger.debug("LALAL LOADING INSIDE \(mergedItems.items[state.firstVisibleItemIndex].newest().item.id) \(mergedItems.splits)")
let triedToLoad = await self.representer.loadItems(false, pagination, { self.visibleItemIndexesNonReversed(self.prevMergedItems) })
return triedToLoad
}
guard let state = self.getListState(),
representer.scrollState == .atDestination,
prevFirstVisible != state.firstVisibleItemIndex || prevItemsCount != mergedItems.indexInParentItems.count,
!preloading
else {
return
}
//logger.debug("LALAL LOADING BEFORE ANYTHING \(state.firstVisibleItemIndex) \(self.prevSnapshot.itemIdentifiers[state.firstVisibleItemIndex].newest().item.id) \(self.representer.$mergedItems.wrappedValue.items[state.firstVisibleItemIndex].newest().item.id)")
prevFirstVisible = state.firstVisibleItemIndex
prevItemsCount = mergedItems.indexInParentItems.count
preloading = true
Task {
defer {
preloading = false
}
//logger.debug("LALAL LOADING BEFORE INSIDE \(state.firstVisibleItemIndex) \(self.prevSnapshot.itemIdentifiers[state.firstVisibleItemIndex].newest().item.id) \(mergedItems.items[state.firstVisibleItemIndex].newest().item.id) \(mergedItems.splits)")
await preloadItems(mergedItems, self.representer.allowLoadMoreItems, state, self.representer.$ignoreLoadingRequests) { pagination in
let triedToLoad = await self.representer.loadItems(false, pagination, { self.visibleItemIndexesNonReversed(self.prevMergedItems) })
logger.debug("LALAL LOADING INSIDE \(mergedItems.items[state.firstVisibleItemIndex].newest().item.id) \(mergedItems.splits), triedToLoad: \(triedToLoad)")
return triedToLoad
}
}
}