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