forked from shadowfacts/Tusker
Add loading indicator to conversation screen
This commit is contained in:
parent
ccd1672e72
commit
63ed3b6e10
|
@ -94,6 +94,9 @@ class ConversationCollectionViewController: UIViewController, CollectionViewCont
|
|||
let expandThreadCell = UICollectionView.CellRegistration<ExpandThreadCollectionViewCell, ([ConversationNode], Bool)> { cell, indexPath, item in
|
||||
cell.updateUI(childThreads: item.0, inline: item.1)
|
||||
}
|
||||
let loadingCell = UICollectionView.CellRegistration<LoadingCollectionViewCell, Void> { cell, indexPath, itemIdentifier in
|
||||
cell.indicator.startAnimating()
|
||||
}
|
||||
return UICollectionViewDiffableDataSource(collectionView: collectionView) { [unowned self] collectionView, indexPath, itemIdentifier in
|
||||
switch itemIdentifier {
|
||||
case let .status(id: id, state: state, prevLink: prevLink, nextLink: nextLink):
|
||||
|
@ -104,17 +107,31 @@ class ConversationCollectionViewController: UIViewController, CollectionViewCont
|
|||
}
|
||||
case .expandThread(childThreads: let childThreads, inline: let inline):
|
||||
return collectionView.dequeueConfiguredReusableCell(using: expandThreadCell, for: indexPath, item: (childThreads, inline))
|
||||
case .loadingIndicator:
|
||||
return collectionView.dequeueConfiguredReusableCell(using: loadingCell, for: indexPath, item: ())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
clearSelectionOnAppear(animated: animated)
|
||||
}
|
||||
|
||||
func addMainStatus(_ status: StatusMO) {
|
||||
loadViewIfNeeded()
|
||||
|
||||
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
||||
snapshot.appendSections([.statuses])
|
||||
|
||||
if status.inReplyToID != nil {
|
||||
snapshot.appendItems([.loadingIndicator], toSection: .statuses)
|
||||
}
|
||||
|
||||
let mainStatusItem = Item.status(id: mainStatusID, state: mainStatusState, prevLink: status.inReplyToID != nil, nextLink: false)
|
||||
snapshot.appendItems([mainStatusItem], toSection: .statuses)
|
||||
|
||||
dataSource.apply(snapshot, animatingDifferences: false)
|
||||
}
|
||||
|
||||
|
@ -125,6 +142,7 @@ class ConversationCollectionViewController: UIViewController, CollectionViewCont
|
|||
await mastodonController.persistentContainer.addAll(statuses: parentStatuses + context.descendants)
|
||||
|
||||
var snapshot = dataSource.snapshot()
|
||||
snapshot.deleteItems([.loadingIndicator])
|
||||
let mainStatusItem = Item.status(id: mainStatusID, state: mainStatusState, prevLink: mainStatus.inReplyToID != nil, nextLink: false)
|
||||
let parentItems = parentIDs.enumerated().map { index, id in
|
||||
Item.status(id: id, state: .unknown, prevLink: index > 0, nextLink: true)
|
||||
|
@ -299,6 +317,7 @@ extension ConversationCollectionViewController {
|
|||
enum Item: Hashable {
|
||||
case status(id: String, state: CollapseState, prevLink: Bool, nextLink: Bool)
|
||||
case expandThread(childThreads: [ConversationNode], inline: Bool)
|
||||
case loadingIndicator
|
||||
|
||||
static func ==(lhs: Item, rhs: Item) -> Bool {
|
||||
switch (lhs, rhs) {
|
||||
|
@ -306,6 +325,8 @@ extension ConversationCollectionViewController {
|
|||
return a == b && aPrev == bPrev && aNext == bNext
|
||||
case let (.expandThread(childThreads: a, inline: aInline), .expandThread(childThreads: b, inline: bInline)):
|
||||
return a.count == b.count && zip(a, b).allSatisfy { $0.status.id == $1.status.id } && aInline == bInline
|
||||
case (.loadingIndicator, .loadingIndicator):
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
@ -324,6 +345,8 @@ extension ConversationCollectionViewController {
|
|||
hasher.combine(thread.status.id)
|
||||
}
|
||||
hasher.combine(inline)
|
||||
case .loadingIndicator:
|
||||
hasher.combine(2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -331,11 +354,13 @@ extension ConversationCollectionViewController {
|
|||
|
||||
extension ConversationCollectionViewController: UICollectionViewDelegate {
|
||||
func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
|
||||
if case .status(id: let id, _, _, _) = dataSource.itemIdentifier(for: indexPath),
|
||||
id == mainStatusID {
|
||||
return false
|
||||
} else {
|
||||
switch dataSource.itemIdentifier(for: indexPath) {
|
||||
case .status(id: let id, state: _, prevLink: _, nextLink: _):
|
||||
return id != mainStatusID
|
||||
case .expandThread(childThreads: _, inline: _):
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -343,6 +368,8 @@ extension ConversationCollectionViewController: UICollectionViewDelegate {
|
|||
switch dataSource.itemIdentifier(for: indexPath) {
|
||||
case nil:
|
||||
break
|
||||
case .loadingIndicator:
|
||||
break
|
||||
case .status(id: let id, state: let state, _, _):
|
||||
selected(status: id, state: state.copy())
|
||||
case .expandThread(childThreads: let childThreads, inline: _):
|
||||
|
|
Loading…
Reference in New Issue