forked from shadowfacts/Tusker
Allow refreshing bookmarks list
This commit is contained in:
parent
5e2b551045
commit
942df433b3
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue