Fix a race condition when refreshing My Profile before initial load is complete
This commit is contained in:
parent
781c37fbae
commit
f31c909517
|
@ -40,6 +40,11 @@ class ProfileStatusesViewController: DiffableTimelineLikeTableViewController<Pro
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
tableView.register(UINib(nibName: "TimelineStatusTableViewCell", bundle: .main), forCellReuseIdentifier: "statusCell")
|
tableView.register(UINib(nibName: "TimelineStatusTableViewCell", bundle: .main), forCellReuseIdentifier: "statusCell")
|
||||||
|
|
||||||
|
// setup the initial snapshot with the sections in the right order, so we don't have to worry about order later
|
||||||
|
var snapshot = Snapshot()
|
||||||
|
snapshot.appendSections([.pinned, .statuses])
|
||||||
|
dataSource.apply(snapshot, animatingDifferences: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateUI(account: AccountMO) {
|
func updateUI(account: AccountMO) {
|
||||||
|
@ -72,6 +77,10 @@ class ProfileStatusesViewController: DiffableTimelineLikeTableViewController<Pro
|
||||||
}
|
}
|
||||||
|
|
||||||
getStatuses { (response) in
|
getStatuses { (response) in
|
||||||
|
guard self.state == .loadingInitial else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch response {
|
switch response {
|
||||||
case let .failure(error):
|
case let .failure(error):
|
||||||
completion(.failure(.client(error)))
|
completion(.failure(.client(error)))
|
||||||
|
@ -83,7 +92,6 @@ class ProfileStatusesViewController: DiffableTimelineLikeTableViewController<Pro
|
||||||
self.mastodonController.persistentContainer.addAll(statuses: statuses) {
|
self.mastodonController.persistentContainer.addAll(statuses: statuses) {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
var snapshot = self.dataSource.snapshot()
|
var snapshot = self.dataSource.snapshot()
|
||||||
snapshot.appendSections([.statuses])
|
|
||||||
snapshot.appendItems(statuses.map { Item(id: $0.id, state: .unknown) }, toSection: .statuses)
|
snapshot.appendItems(statuses.map { Item(id: $0.id, state: .unknown) }, toSection: .statuses)
|
||||||
if self.kind == .statuses {
|
if self.kind == .statuses {
|
||||||
self.loadPinnedStatuses(snapshot: { snapshot }, completion: completion)
|
self.loadPinnedStatuses(snapshot: { snapshot }, completion: completion)
|
||||||
|
@ -110,10 +118,7 @@ class ProfileStatusesViewController: DiffableTimelineLikeTableViewController<Pro
|
||||||
self.mastodonController.persistentContainer.addAll(statuses: statuses) {
|
self.mastodonController.persistentContainer.addAll(statuses: statuses) {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
var snapshot = snapshot()
|
var snapshot = snapshot()
|
||||||
if snapshot.indexOfSection(.pinned) != nil {
|
snapshot.deleteItems(snapshot.itemIdentifiers(inSection: .pinned))
|
||||||
snapshot.deleteSections([.pinned])
|
|
||||||
}
|
|
||||||
snapshot.insertSections([.pinned], beforeSection: .statuses)
|
|
||||||
snapshot.appendItems(statuses.map { Item(id: $0.id, state: .unknown) }, toSection: .pinned)
|
snapshot.appendItems(statuses.map { Item(id: $0.id, state: .unknown) }, toSection: .pinned)
|
||||||
completion(.success(snapshot))
|
completion(.success(snapshot))
|
||||||
}
|
}
|
||||||
|
@ -209,7 +214,9 @@ class ProfileStatusesViewController: DiffableTimelineLikeTableViewController<Pro
|
||||||
override func refresh() {
|
override func refresh() {
|
||||||
super.refresh()
|
super.refresh()
|
||||||
|
|
||||||
if kind == .statuses {
|
// only refresh pinned if the super call actually succeded (put the state into .loadingNewer)
|
||||||
|
if state == .loadingNewer,
|
||||||
|
kind == .statuses {
|
||||||
loadPinnedStatuses(snapshot: dataSource.snapshot) { (result) in
|
loadPinnedStatuses(snapshot: dataSource.snapshot) { (result) in
|
||||||
switch result {
|
switch result {
|
||||||
case .failure(_):
|
case .failure(_):
|
||||||
|
|
|
@ -195,7 +195,12 @@ class DiffableTimelineLikeTableViewController<Section: Hashable & CaseIterable,
|
||||||
// MARK: - RefreshableViewController
|
// MARK: - RefreshableViewController
|
||||||
|
|
||||||
func refresh() {
|
func refresh() {
|
||||||
guard state != .loadingNewer else { return }
|
// if we're unloaded, there's nothing "newer" to load
|
||||||
|
// if we're performing some other operation, we don't want to step on its toes
|
||||||
|
guard state == .loaded else {
|
||||||
|
self.refreshControl?.endRefreshing()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
state = .loadingNewer
|
state = .loadingNewer
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue