mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
Caches Friend Zone patrons to offset slow loading time
The Patreon API doesn’t have a way to fetch just the patrons belonging to our Friend Zone tier. Instead, we need to fetch ALL patrons (including inactive ones) and filter out those not in the tier. This is very inefficient, and takes over a minute to complete as of April 14, 2022, due to the number of patrons we have. We can’t do much to change this, but AltStore will now at least cache the fetched patrons with Core Data. Additionally, AltStore will only perform this long fetch whenever the Friend Zone list actually changes, rather than every time the Patreon screen appears.
This commit is contained in:
@@ -29,8 +29,6 @@ class PatreonViewController: UICollectionViewController
|
||||
|
||||
private var prototypeAboutHeader: AboutPatreonHeaderView!
|
||||
|
||||
private var patronsResult: Result<[Patron], Error>?
|
||||
|
||||
override var preferredStatusBarStyle: UIStatusBarStyle {
|
||||
return .lightContent
|
||||
}
|
||||
@@ -48,6 +46,8 @@ class PatreonViewController: UICollectionViewController
|
||||
self.collectionView.register(PatronsHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "PatronsHeader")
|
||||
self.collectionView.register(PatronsFooterView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionFooter, withReuseIdentifier: "PatronsFooter")
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(PatreonViewController.didUpdatePatrons(_:)), name: AppManager.didUpdatePatronsNotification, object: nil)
|
||||
|
||||
self.update()
|
||||
}
|
||||
|
||||
@@ -75,20 +75,24 @@ class PatreonViewController: UICollectionViewController
|
||||
|
||||
private extension PatreonViewController
|
||||
{
|
||||
func makeDataSource() -> RSTCompositeCollectionViewDataSource<Patron>
|
||||
func makeDataSource() -> RSTCompositeCollectionViewDataSource<PatreonAccount>
|
||||
{
|
||||
let aboutDataSource = RSTDynamicCollectionViewDataSource<Patron>()
|
||||
let aboutDataSource = RSTDynamicCollectionViewDataSource<PatreonAccount>()
|
||||
aboutDataSource.numberOfSectionsHandler = { 1 }
|
||||
aboutDataSource.numberOfItemsHandler = { _ in 0 }
|
||||
|
||||
let dataSource = RSTCompositeCollectionViewDataSource<Patron>(dataSources: [aboutDataSource, self.patronsDataSource])
|
||||
let dataSource = RSTCompositeCollectionViewDataSource<PatreonAccount>(dataSources: [aboutDataSource, self.patronsDataSource])
|
||||
dataSource.proxy = self
|
||||
return dataSource
|
||||
}
|
||||
|
||||
func makePatronsDataSource() -> RSTArrayCollectionViewDataSource<Patron>
|
||||
func makePatronsDataSource() -> RSTFetchedResultsCollectionViewDataSource<PatreonAccount>
|
||||
{
|
||||
let patronsDataSource = RSTArrayCollectionViewDataSource<Patron>(items: [])
|
||||
let fetchRequest: NSFetchRequest<PatreonAccount> = PatreonAccount.fetchRequest()
|
||||
fetchRequest.predicate = NSPredicate(format: "%K == YES", #keyPath(PatreonAccount.isFriendZonePatron))
|
||||
fetchRequest.sortDescriptors = [NSSortDescriptor(key: #keyPath(PatreonAccount.name), ascending: true, selector: #selector(NSString.caseInsensitiveCompare(_:)))]
|
||||
|
||||
let patronsDataSource = RSTFetchedResultsCollectionViewDataSource<PatreonAccount>(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext)
|
||||
patronsDataSource.cellConfigurationHandler = { (cell, patron, indexPath) in
|
||||
let cell = cell as! PatronCollectionViewCell
|
||||
cell.textLabel.text = patron.name
|
||||
@@ -173,31 +177,8 @@ private extension PatreonViewController
|
||||
{
|
||||
@objc func fetchPatrons()
|
||||
{
|
||||
if let result = self.patronsResult, case .failure = result
|
||||
{
|
||||
self.patronsResult = nil
|
||||
self.collectionView.reloadData()
|
||||
}
|
||||
|
||||
PatreonAPI.shared.fetchPatrons { (result) in
|
||||
self.patronsResult = result
|
||||
|
||||
do
|
||||
{
|
||||
let patrons = try result.get()
|
||||
let sortedPatrons = patrons.sorted { $0.name < $1.name }
|
||||
|
||||
self.patronsDataSource.items = sortedPatrons
|
||||
}
|
||||
catch
|
||||
{
|
||||
print("Failed to fetch patrons:", error)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.collectionView.reloadData()
|
||||
}
|
||||
}
|
||||
}
|
||||
AppManager.shared.updatePatronsIfNeeded()
|
||||
self.update()
|
||||
}
|
||||
|
||||
@objc func openPatreonURL(_ sender: UIButton)
|
||||
@@ -263,6 +244,13 @@ private extension PatreonViewController
|
||||
alertController.addAction(.cancel)
|
||||
self.present(alertController, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
@objc func didUpdatePatrons(_ notification: Notification)
|
||||
{
|
||||
DispatchQueue.main.async {
|
||||
self.collectionView.reloadData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension PatreonViewController
|
||||
@@ -291,11 +279,18 @@ extension PatreonViewController
|
||||
footerView.button.isHidden = false
|
||||
footerView.button.addTarget(self, action: #selector(PatreonViewController.fetchPatrons), for: .primaryActionTriggered)
|
||||
|
||||
switch self.patronsResult
|
||||
if self.patronsDataSource.itemCount > 0
|
||||
{
|
||||
case .none: footerView.button.isIndicatingActivity = true
|
||||
case .success?: footerView.button.isHidden = true
|
||||
case .failure?: footerView.button.setTitle(NSLocalizedString("Error Loading Patrons", comment: ""), for: .normal)
|
||||
footerView.button.isHidden = true
|
||||
}
|
||||
else
|
||||
{
|
||||
switch AppManager.shared.updatePatronsResult
|
||||
{
|
||||
case .none: footerView.button.isIndicatingActivity = true
|
||||
case .success?: footerView.button.isHidden = true
|
||||
case .failure?: footerView.button.setTitle(NSLocalizedString("Error Loading Patrons", comment: ""), for: .normal)
|
||||
}
|
||||
}
|
||||
|
||||
return footerView
|
||||
|
||||
Reference in New Issue
Block a user