Allow refreshing bookmarks list

This commit is contained in:
Shadowfacts 2023-01-28 15:30:09 -05:00
parent 5e2b551045
commit 942df433b3
1 changed files with 72 additions and 5 deletions

View File

@ -10,7 +10,7 @@ import UIKit
import Pachyderm import Pachyderm
import CoreData import CoreData
class BookmarksViewController: UIViewController, CollectionViewController { class BookmarksViewController: UIViewController, CollectionViewController, RefreshableViewController {
private static let pageSize = 40 private static let pageSize = 40
@ -95,6 +95,13 @@ class BookmarksViewController: UIViewController, CollectionViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
#if !targetEnvironment(macCatalyst)
collectionView.refreshControl = UIRefreshControl()
collectionView.refreshControl!.addTarget(self, action: #selector(refresh), for: .valueChanged)
#endif
addKeyCommand(MenuController.refreshCommand(discoverabilityTitle: "Refresh Bookmarks"))
NotificationCenter.default.addObserver(self, selector: #selector(handleStatusDeleted), name: .statusDeleted, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(handleStatusDeleted), name: .statusDeleted, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(managedObjectsDidChange), name: .NSManagedObjectContextObjectsDidChange, object: mastodonController.persistentContainer.viewContext) NotificationCenter.default.addObserver(self, selector: #selector(managedObjectsDidChange), name: .NSManagedObjectContextObjectsDidChange, object: mastodonController.persistentContainer.viewContext)
} }
@ -176,8 +183,6 @@ class BookmarksViewController: UIViewController, CollectionViewController {
snapshot.deleteItems([.loadingIndicator]) snapshot.deleteItems([.loadingIndicator])
snapshot.appendItems(statuses.map { .status(id: $0.id, state: .unknown, addedLocally: false) }) snapshot.appendItems(statuses.map { .status(id: $0.id, state: .unknown, addedLocally: false) })
await apply(snapshot: snapshot, animatingDifferences: true) await apply(snapshot: snapshot, animatingDifferences: true)
state = .loaded
} catch { } catch {
let config = ToastConfiguration(from: error, with: "Error Loading Older Bookmarks", in: self) { [weak self] toast in let config = ToastConfiguration(from: error, with: "Error Loading Older Bookmarks", in: self) { [weak self] toast in
toast.dismissToast(animated: true) toast.dismissToast(animated: true)
@ -187,10 +192,10 @@ class BookmarksViewController: UIViewController, CollectionViewController {
snapshot.deleteItems([.loadingIndicator]) snapshot.deleteItems([.loadingIndicator])
await apply(snapshot: snapshot, animatingDifferences: false) await apply(snapshot: snapshot, animatingDifferences: false)
}
state = .loaded state = .loaded
} }
}
@objc private func handleStatusDeleted(_ notification: Foundation.Notification) { @objc private func handleStatusDeleted(_ notification: Foundation.Notification) {
guard let userInfo = notification.userInfo, guard let userInfo = notification.userInfo,
@ -249,6 +254,67 @@ class BookmarksViewController: UIViewController, CollectionViewController {
} }
} }
// MARK: Interaction
@objc func refresh() {
guard case .loaded = state,
let newer else {
#if !targetEnvironment(macCatalyst)
collectionView.refreshControl!.endRefreshing()
#endif
return
}
state = .loadingNewer
Task {
do {
let req = Client.getBookmarks(range: newer.withCount(BookmarksViewController.pageSize))
let (statuses, pagination) = try await mastodonController.run(req)
self.newer = pagination?.newer
await mastodonController.persistentContainer.addAll(statuses: statuses)
var snapshot = dataSource.snapshot()
let localItems: [String: CollapseState] = Dictionary(uniqueKeysWithValues: snapshot.itemIdentifiers.compactMap({
if case .status(id: let id, state: let state, addedLocally: true) = $0 {
return (id, state)
} else {
return nil
}
}))
var newItems: [Item] = []
for status in statuses {
let state: CollapseState
if let existing = localItems[status.id] {
state = existing
snapshot.deleteItems([.status(id: status.id, state: existing, addedLocally: true)])
} else {
state = .unknown
}
newItems.append(.status(id: status.id, state: state, addedLocally: false))
}
if let first = snapshot.itemIdentifiers.first {
snapshot.insertItems(newItems, beforeItem: first)
} else {
snapshot.appendItems(newItems)
}
await apply(snapshot: snapshot, animatingDifferences: true)
} catch {
let config = ToastConfiguration(from: error, with: "Error Refreshing Bookmarks", in: self) { [weak self] toast in
toast.dismissToast(animated: true)
self?.refresh()
}
showToast(configuration: config, animated: true)
}
#if !targetEnvironment(macCatalyst)
collectionView.refreshControl!.endRefreshing()
#endif
state = .loaded
}
}
} }
extension BookmarksViewController { extension BookmarksViewController {
@ -297,6 +363,7 @@ extension BookmarksViewController {
case loadingInitial case loadingInitial
case loaded case loaded
case loadingOlder case loadingOlder
case loadingNewer
} }
} }