Add loading indicator to Trends screen
This commit is contained in:
parent
ae7ca9c91c
commit
205bdffebd
|
@ -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 []
|
||||||
|
|
Loading…
Reference in New Issue