mirror of
https://github.com/metabolist/metatext.git
synced 2024-11-25 17:50:59 +00:00
Fix scroll position maintenance
This commit is contained in:
parent
79b1c531f0
commit
7840a35e29
5 changed files with 31 additions and 8 deletions
|
@ -10,6 +10,8 @@ public enum CollectionItem: Hashable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension CollectionItem {
|
public extension CollectionItem {
|
||||||
|
typealias Id = String
|
||||||
|
|
||||||
struct StatusConfiguration: Hashable {
|
struct StatusConfiguration: Hashable {
|
||||||
public let showContentToggled: Bool
|
public let showContentToggled: Bool
|
||||||
public let showAttachmentsToggled: Bool
|
public let showAttachmentsToggled: Bool
|
||||||
|
@ -32,6 +34,19 @@ public extension CollectionItem {
|
||||||
self.hasReplyFollowing = hasReplyFollowing
|
self.hasReplyFollowing = hasReplyFollowing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var itemId: Id? {
|
||||||
|
switch self {
|
||||||
|
case let .status(status, _):
|
||||||
|
return status.id
|
||||||
|
case .loadMore:
|
||||||
|
return nil
|
||||||
|
case let .account(account):
|
||||||
|
return account.id
|
||||||
|
case let .notification(notification, _):
|
||||||
|
return notification.id
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension CollectionItem.StatusConfiguration {
|
public extension CollectionItem.StatusConfiguration {
|
||||||
|
|
|
@ -42,3 +42,11 @@ final class TableViewDataSource: UITableViewDiffableDataSource<Int, CollectionIt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension TableViewDataSource {
|
||||||
|
func indexPath(itemId: CollectionItem.Id) -> IndexPath? {
|
||||||
|
guard let item = snapshot().itemIdentifiers.first(where: { $0.itemId == itemId }) else { return nil }
|
||||||
|
|
||||||
|
return indexPath(for: item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -260,8 +260,8 @@ private extension TableViewController {
|
||||||
var offsetFromNavigationBar: CGFloat?
|
var offsetFromNavigationBar: CGFloat?
|
||||||
|
|
||||||
if
|
if
|
||||||
let item = update.maintainScrollPosition,
|
let itemId = update.maintainScrollPositionItemId,
|
||||||
let indexPath = dataSource.indexPath(for: item),
|
let indexPath = dataSource.indexPath(itemId: itemId),
|
||||||
let navigationBar = navigationController?.navigationBar {
|
let navigationBar = navigationController?.navigationBar {
|
||||||
let navigationBarMaxY = tableView.convert(navigationBar.bounds, from: navigationBar).maxY
|
let navigationBarMaxY = tableView.convert(navigationBar.bounds, from: navigationBar).maxY
|
||||||
offsetFromNavigationBar = tableView.rectForRow(at: indexPath).origin.y - navigationBarMaxY
|
offsetFromNavigationBar = tableView.rectForRow(at: indexPath).origin.y - navigationBarMaxY
|
||||||
|
@ -271,8 +271,8 @@ private extension TableViewController {
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
|
|
||||||
if
|
if
|
||||||
let item = update.maintainScrollPosition,
|
let itemId = update.maintainScrollPositionItemId,
|
||||||
let indexPath = self.dataSource.indexPath(for: item) {
|
let indexPath = self.dataSource.indexPath(itemId: itemId) {
|
||||||
if self.viewModel.shouldAdjustContentInset {
|
if self.viewModel.shouldAdjustContentInset {
|
||||||
self.tableView.contentInset.bottom = max(
|
self.tableView.contentInset.bottom = max(
|
||||||
0,
|
0,
|
||||||
|
|
|
@ -16,7 +16,7 @@ final public class CollectionItemsViewModel: ObservableObject {
|
||||||
private let eventsSubject = PassthroughSubject<CollectionItemEvent, Never>()
|
private let eventsSubject = PassthroughSubject<CollectionItemEvent, Never>()
|
||||||
private let loadingSubject = PassthroughSubject<Bool, Never>()
|
private let loadingSubject = PassthroughSubject<Bool, Never>()
|
||||||
private let expandAllSubject: CurrentValueSubject<ExpandAllState, Never>
|
private let expandAllSubject: CurrentValueSubject<ExpandAllState, Never>
|
||||||
private var maintainScrollPosition: CollectionItem?
|
private var maintainScrollPositionItemId: CollectionItem.Id?
|
||||||
private var topVisibleIndexPath = IndexPath(item: 0, section: 0)
|
private var topVisibleIndexPath = IndexPath(item: 0, section: 0)
|
||||||
private let lastReadId = CurrentValueSubject<String?, Never>(nil)
|
private let lastReadId = CurrentValueSubject<String?, Never>(nil)
|
||||||
private var lastSelectedLoadMore: LoadMore?
|
private var lastSelectedLoadMore: LoadMore?
|
||||||
|
@ -57,7 +57,7 @@ extension CollectionItemsViewModel: CollectionViewModel {
|
||||||
public var updates: AnyPublisher<CollectionUpdate, Never> {
|
public var updates: AnyPublisher<CollectionUpdate, Never> {
|
||||||
items.map { [weak self] in
|
items.map { [weak self] in
|
||||||
CollectionUpdate(items: $0,
|
CollectionUpdate(items: $0,
|
||||||
maintainScrollPosition: self?.maintainScrollPosition)
|
maintainScrollPositionItemId: self?.maintainScrollPositionItemId)
|
||||||
}
|
}
|
||||||
.eraseToAnyPublisher()
|
.eraseToAnyPublisher()
|
||||||
}
|
}
|
||||||
|
@ -267,7 +267,7 @@ private extension CollectionItemsViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
func process(items: [[CollectionItem]]) {
|
func process(items: [[CollectionItem]]) {
|
||||||
maintainScrollPosition = itemForScrollPositionMaintenance(newItems: items)
|
maintainScrollPositionItemId = itemForScrollPositionMaintenance(newItems: items)?.itemId
|
||||||
self.items.send(items)
|
self.items.send(items)
|
||||||
|
|
||||||
let itemsSet = Set(items.reduce([], +))
|
let itemsSet = Set(items.reduce([], +))
|
||||||
|
|
|
@ -2,5 +2,5 @@
|
||||||
|
|
||||||
public struct CollectionUpdate: Hashable {
|
public struct CollectionUpdate: Hashable {
|
||||||
public let items: [[CollectionItem]]
|
public let items: [[CollectionItem]]
|
||||||
public let maintainScrollPosition: CollectionItem?
|
public let maintainScrollPositionItemId: String?
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue