Add loading indicator to Trends screen

This commit is contained in:
Shadowfacts 2023-02-11 18:32:37 -05:00
parent ae7ca9c91c
commit 205bdffebd
1 changed files with 49 additions and 2 deletions

View File

@ -42,6 +42,12 @@ class TrendsViewController: UIViewController, CollectionViewController {
let layout = UICollectionViewCompositionalLayout { [unowned self] sectionIndex, environment in
let sectionIdentifier = self.dataSource.snapshot().sectionIdentifiers[sectionIndex]
switch sectionIdentifier {
case .loadingIndicator:
var listConfig = UICollectionLayoutListConfiguration(appearance: .grouped)
listConfig.backgroundColor = .appGroupedBackground
listConfig.showsSeparators = false
return .list(using: listConfig, layoutEnvironment: environment)
case .trendingHashtags:
var listConfig = UICollectionLayoutListConfiguration(appearance: .grouped)
listConfig.headerMode = .supplementary
@ -107,6 +113,9 @@ class TrendsViewController: UIViewController, CollectionViewController {
headerView.contentConfiguration = config
}
let loadingCell = UICollectionView.CellRegistration<LoadingCollectionViewCell, Void> { cell, indexPath, itemIdentifier in
cell.indicator.startAnimating()
}
let trendingHashtagCell = UICollectionView.CellRegistration<TrendingHashtagCollectionViewCell, Hashtag> { (cell, indexPath, hashtag) in
cell.updateUI(hashtag: hashtag)
}
@ -125,7 +134,7 @@ class TrendsViewController: UIViewController, CollectionViewController {
let moreCell = UICollectionView.SupplementaryRegistration<MoreTrendsFooterCollectionViewCell>(elementKind: UICollectionView.elementKindSectionFooter) { [unowned self] supplementaryView, elementKind, indexPath in
supplementaryView.delegate = self
switch self.dataSource.sectionIdentifier(for: indexPath.section) {
case nil, .trendingStatuses:
case nil, .loadingIndicator, .trendingStatuses:
fatalError()
case .trendingHashtags:
supplementaryView.updateUI(.hashtags)
@ -138,6 +147,9 @@ class TrendsViewController: UIViewController, CollectionViewController {
let dataSource = UICollectionViewDiffableDataSource<Section, Item>(collectionView: collectionView) { collectionView, indexPath, item in
switch item {
case .loadingIndicator:
return collectionView.dequeueConfiguredReusableCell(using: loadingCell, for: indexPath, item: ())
case let .tag(hashtag):
return collectionView.dequeueConfiguredReusableCell(using: trendingHashtagCell, for: indexPath, item: hashtag)
@ -189,6 +201,11 @@ class TrendsViewController: UIViewController, CollectionViewController {
}
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
snapshot.appendSections([.loadingIndicator])
snapshot.appendItems([.loadingIndicator])
await apply(snapshot: snapshot)
snapshot = NSDiffableDataSourceSnapshot()
let hashtagsReq = Client.getTrendingHashtags(limit: 5)
let hashtags = try? await mastodonController.run(hashtagsReq).0
@ -271,13 +288,16 @@ class TrendsViewController: UIViewController, CollectionViewController {
extension TrendsViewController {
enum Section {
case loadingIndicator
case trendingHashtags
case trendingLinks
case profileSuggestions
case trendingStatuses
var title: String {
var title: String? {
switch self {
case .loadingIndicator:
return nil
case .trendingHashtags:
return "Trending Hashtags"
case .trendingLinks:
@ -290,6 +310,7 @@ extension TrendsViewController {
}
}
enum Item: Equatable, Hashable {
case loadingIndicator
case status(String, CollapseState)
case tag(Hashtag)
case link(Card)
@ -297,6 +318,8 @@ extension TrendsViewController {
static func == (lhs: Item, rhs: Item) -> Bool {
switch (lhs, rhs) {
case (.loadingIndicator, .loadingIndicator):
return true
case let (.status(a, _), .status(b, _)):
return a == b
case let (.tag(a), .tag(b)):
@ -312,6 +335,8 @@ extension TrendsViewController {
func hash(into hasher: inout Hasher) {
switch self {
case .loadingIndicator:
hasher.combine("loadingIndicator")
case let .status(id, _):
hasher.combine("status")
hasher.combine(id)
@ -326,15 +351,31 @@ extension TrendsViewController {
hasher.combine(id)
}
}
var shouldSelect: Bool {
switch self {
case .loadingIndicator:
return false
default:
return true
}
}
}
}
extension TrendsViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
return dataSource.itemIdentifier(for: indexPath)?.shouldSelect ?? false
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let item = dataSource.itemIdentifier(for: indexPath) else {
return
}
switch item {
case .loadingIndicator:
return
case let .tag(hashtag):
show(HashtagTimelineViewController(for: hashtag, mastodonController: mastodonController), sender: nil)
@ -358,6 +399,9 @@ extension TrendsViewController: UICollectionViewDelegate {
}
switch item {
case .loadingIndicator:
return nil
case let .tag(hashtag):
return UIContextMenuConfiguration(identifier: nil) {
HashtagTimelineViewController(for: hashtag, mastodonController: self.mastodonController)
@ -443,6 +487,9 @@ extension TrendsViewController: UICollectionViewDragDelegate {
return []
}
switch item {
case .loadingIndicator:
return []
case let .tag(hashtag):
guard let url = URL(hashtag.url) else {
return []