Improve scroll position maintenance

This commit is contained in:
Justin Mazzocchi 2020-11-02 15:05:09 -08:00
parent df15a8e8af
commit 69b664ce0f
No known key found for this signature in database
GPG key ID: E223E6937AAFB01C

View file

@ -267,7 +267,7 @@ private extension CollectionItemsViewModel {
} }
func process(items: [[CollectionItem]]) { func process(items: [[CollectionItem]]) {
maintainScrollPositionItemId = itemForScrollPositionMaintenance(newItems: items)?.itemId maintainScrollPositionItemId = idForScrollPositionMaintenance(newItems: items)
self.items.send(items) self.items.send(items)
let itemsSet = Set(items.reduce([], +)) let itemsSet = Set(items.reduce([], +))
@ -275,25 +275,18 @@ private extension CollectionItemsViewModel {
viewModelCache = viewModelCache.filter { itemsSet.contains($0.key) } viewModelCache = viewModelCache.filter { itemsSet.contains($0.key) }
} }
// swiftlint:disable:next cyclomatic_complexity function_body_length func idForScrollPositionMaintenance(newItems: [[CollectionItem]]) -> CollectionItem.Id? {
func itemForScrollPositionMaintenance(newItems: [[CollectionItem]]) -> CollectionItem? { let flatItems = items.value.reduce([], +)
let flatNewItems = newItems.reduce([], +) let flatNewItems = newItems.reduce([], +)
if let markerTimeline = collectionService.markerTimeline, if let markerTimeline = collectionService.markerTimeline,
identification.appPreferences.positionBehavior(markerTimeline: markerTimeline) == .rememberPosition, identification.appPreferences.positionBehavior(markerTimeline: markerTimeline) == .rememberPosition,
let localLastReadId = identification.service.getLocalLastReadId(markerTimeline), let localLastReadId = identification.service.getLocalLastReadId(markerTimeline),
!hasRememberedPosition, flatItems.contains(where: { $0.itemId == localLastReadId }),
let lastReadItem = flatNewItems.first(where: { !hasRememberedPosition {
switch $0 {
case let .status(status, _):
return status.id == localLastReadId
default:
return false
}
}) {
hasRememberedPosition = true hasRememberedPosition = true
return lastReadItem return localLastReadId
} }
if collectionService is ContextService, if collectionService is ContextService,
@ -303,9 +296,8 @@ private extension CollectionItemsViewModel {
return configuration.isContextParent // Maintain scroll position of parent after initial load of context return configuration.isContextParent // Maintain scroll position of parent after initial load of context
}) { }) {
return contextParent return contextParent.itemId
} else if collectionService is TimelineService { } else if collectionService is TimelineService {
let flatItems = items.value.reduce([], +)
let difference = flatNewItems.difference(from: flatItems) let difference = flatNewItems.difference(from: flatItems)
if let lastSelectedLoadMore = lastSelectedLoadMore { if let lastSelectedLoadMore = lastSelectedLoadMore {
@ -320,7 +312,7 @@ private extension CollectionItemsViewModel {
return status.id == loadMore.beforeStatusId return status.id == loadMore.beforeStatusId
}) { }) {
return statusAfterLoadMore return statusAfterLoadMore.itemId
} }
} }
} }
@ -330,9 +322,10 @@ private extension CollectionItemsViewModel {
let topVisibleItem = items.value[topVisibleIndexPath.section][topVisibleIndexPath.item] let topVisibleItem = items.value[topVisibleIndexPath.section][topVisibleIndexPath.item]
if newItems.count > topVisibleIndexPath.section, if newItems.count > topVisibleIndexPath.section,
let newIndex = newItems[topVisibleIndexPath.section].firstIndex(of: topVisibleItem), let newIndex = newItems[topVisibleIndexPath.section]
.firstIndex(where: { $0.itemId == topVisibleItem.itemId }),
newIndex > topVisibleIndexPath.item { newIndex > topVisibleIndexPath.item {
return topVisibleItem return topVisibleItem.itemId
} }
} }
} }