forked from shadowfacts/Tusker
Extract more things to TimelineLikeCollectionViewController
This commit is contained in:
parent
a682c8f5cc
commit
253fb8d27d
|
@ -62,6 +62,7 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
|
||||||
collectionView.delegate = self
|
collectionView.delegate = self
|
||||||
// collectionView.dragDelegate = self
|
// collectionView.dragDelegate = self
|
||||||
|
|
||||||
|
registerTimelineLikeCells()
|
||||||
dataSource = createDataSource()
|
dataSource = createDataSource()
|
||||||
applyInitialSnapshot()
|
applyInitialSnapshot()
|
||||||
|
|
||||||
|
@ -93,27 +94,14 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
|
||||||
config.text = try! doc.text()
|
config.text = try! doc.text()
|
||||||
cell.contentConfiguration = config
|
cell.contentConfiguration = config
|
||||||
}
|
}
|
||||||
collectionView.register(LoadingCollectionViewCell.self, forCellWithReuseIdentifier: "loadingIndicator")
|
|
||||||
collectionView.register(ConfirmLoadMoreCollectionViewCell.self, forCellWithReuseIdentifier: "confirmLoadMore")
|
|
||||||
return UICollectionViewDiffableDataSource(collectionView: collectionView) { [unowned self] collectionView, indexPath, itemIdentifier in
|
return UICollectionViewDiffableDataSource(collectionView: collectionView) { [unowned self] collectionView, indexPath, itemIdentifier in
|
||||||
switch itemIdentifier {
|
switch itemIdentifier {
|
||||||
case .status(_, _):
|
case .status(_, _):
|
||||||
return collectionView.dequeueConfiguredReusableCell(using: listCell, for: indexPath, item: itemIdentifier)
|
return collectionView.dequeueConfiguredReusableCell(using: listCell, for: indexPath, item: itemIdentifier)
|
||||||
case .loadingIndicator:
|
case .loadingIndicator:
|
||||||
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "loadingIndicator", for: indexPath) as! LoadingCollectionViewCell
|
return loadingIndicatorCell(for: indexPath)
|
||||||
cell.indicator.startAnimating()
|
|
||||||
return cell
|
|
||||||
case .confirmLoadMore:
|
case .confirmLoadMore:
|
||||||
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "confirmLoadMore", for: indexPath) as! ConfirmLoadMoreCollectionViewCell
|
return confirmLoadMoreCell(for: indexPath)
|
||||||
cell.confirmLoadMore = self.confirmLoadMore
|
|
||||||
Task {
|
|
||||||
if case .loadingOlder(_, _) = await controller.state {
|
|
||||||
cell.isLoading = true
|
|
||||||
} else {
|
|
||||||
cell.isLoading = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return cell
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,7 +183,7 @@ extension TimelineViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - TimelineLikeControllerDelegate
|
// MARK: TimelineLikeControllerDelegate
|
||||||
extension TimelineViewController {
|
extension TimelineViewController {
|
||||||
typealias TimelineItem = String // status ID
|
typealias TimelineItem = String // status ID
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ protocol TimelineLikeCollectionViewError: Error, Equatable {
|
||||||
static var allCaughtUp: Self { get }
|
static var allCaughtUp: Self { get }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: TimelineLikeControllerDelegate
|
||||||
extension TimelineLikeCollectionViewController {
|
extension TimelineLikeCollectionViewController {
|
||||||
func canLoadOlder() async -> Bool {
|
func canLoadOlder() async -> Bool {
|
||||||
if Preferences.shared.disableInfiniteScrolling {
|
if Preferences.shared.disableInfiniteScrolling {
|
||||||
|
@ -185,3 +186,29 @@ extension TimelineLikeCollectionViewController {
|
||||||
await dataSource.apply(snapshot, animatingDifferences: false)
|
await dataSource.apply(snapshot, animatingDifferences: false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension TimelineLikeCollectionViewController {
|
||||||
|
func registerTimelineLikeCells() {
|
||||||
|
collectionView.register(LoadingCollectionViewCell.self, forCellWithReuseIdentifier: "loadingIndicator")
|
||||||
|
collectionView.register(ConfirmLoadMoreCollectionViewCell.self, forCellWithReuseIdentifier: "confirmLoadMore")
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadingIndicatorCell(for indexPath: IndexPath) -> UICollectionViewCell {
|
||||||
|
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "loadingIndicator", for: indexPath) as! LoadingCollectionViewCell
|
||||||
|
cell.indicator.startAnimating()
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
|
||||||
|
func confirmLoadMoreCell(for indexPath: IndexPath) -> UICollectionViewCell {
|
||||||
|
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "confirmLoadMore", for: indexPath) as! ConfirmLoadMoreCollectionViewCell
|
||||||
|
cell.confirmLoadMore = self.confirmLoadMore
|
||||||
|
Task {
|
||||||
|
if case .loadingOlder(_, _) = await controller.state {
|
||||||
|
cell.isLoading = true
|
||||||
|
} else {
|
||||||
|
cell.isLoading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -86,11 +86,7 @@ actor TimelineLikeController<Item> {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let token = LoadAttemptToken()
|
let token = LoadAttemptToken()
|
||||||
// TODO: does the waiting state need to include the token?
|
|
||||||
// TODO: does this even need to be a separate state? maybe we should just await the delegate's permission, since it can suspend until user input. then the prompt could appear, and the user could scroll back to the top and still be able to refresh
|
|
||||||
// state = .waitingForLoadOlderPermission
|
|
||||||
guard await delegate.canLoadOlder() else {
|
guard await delegate.canLoadOlder() else {
|
||||||
// state = .idle
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
state = .loadingOlder(token, hasAddedLoadingIndicator: false)
|
state = .loadingOlder(token, hasAddedLoadingIndicator: false)
|
||||||
|
@ -124,7 +120,6 @@ actor TimelineLikeController<Item> {
|
||||||
case idle
|
case idle
|
||||||
case loadingInitial(LoadAttemptToken, hasAddedLoadingIndicator: Bool)
|
case loadingInitial(LoadAttemptToken, hasAddedLoadingIndicator: Bool)
|
||||||
case loadingNewer(LoadAttemptToken)
|
case loadingNewer(LoadAttemptToken)
|
||||||
// case waitingForLoadOlderPermission
|
|
||||||
case loadingOlder(LoadAttemptToken, hasAddedLoadingIndicator: Bool)
|
case loadingOlder(LoadAttemptToken, hasAddedLoadingIndicator: Bool)
|
||||||
|
|
||||||
var debugDescription: String {
|
var debugDescription: String {
|
||||||
|
@ -137,8 +132,6 @@ actor TimelineLikeController<Item> {
|
||||||
return "loadingInitial(\(ObjectIdentifier(token)), hasAddedLoadingIndicator: \(hasAddedLoadingIndicator))"
|
return "loadingInitial(\(ObjectIdentifier(token)), hasAddedLoadingIndicator: \(hasAddedLoadingIndicator))"
|
||||||
case .loadingNewer(let token):
|
case .loadingNewer(let token):
|
||||||
return "loadingNewer(\(ObjectIdentifier(token)))"
|
return "loadingNewer(\(ObjectIdentifier(token)))"
|
||||||
// case .waitingForLoadOlderPermission:
|
|
||||||
// return "waitingForLoadOlderPermission"
|
|
||||||
case .loadingOlder(let token, let hasAddedLoadingIndicator):
|
case .loadingOlder(let token, let hasAddedLoadingIndicator):
|
||||||
return "loadingOlder(\(ObjectIdentifier(token)), hasAddedLoadingIndicator: \(hasAddedLoadingIndicator))"
|
return "loadingOlder(\(ObjectIdentifier(token)), hasAddedLoadingIndicator: \(hasAddedLoadingIndicator))"
|
||||||
}
|
}
|
||||||
|
@ -155,7 +148,7 @@ actor TimelineLikeController<Item> {
|
||||||
}
|
}
|
||||||
case .idle:
|
case .idle:
|
||||||
switch to {
|
switch to {
|
||||||
case .loadingNewer(_)/*, .waitingForLoadOlderPermission*/, .loadingOlder(_, _):
|
case .loadingNewer(_), .loadingOlder(_, _):
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
|
@ -166,13 +159,6 @@ actor TimelineLikeController<Item> {
|
||||||
return to == .idle
|
return to == .idle
|
||||||
case .loadingOlder(let token, let hasAddedLoadingIndicator):
|
case .loadingOlder(let token, let hasAddedLoadingIndicator):
|
||||||
return to == .idle || (!hasAddedLoadingIndicator && to == .loadingOlder(token, hasAddedLoadingIndicator: true))
|
return to == .idle || (!hasAddedLoadingIndicator && to == .loadingOlder(token, hasAddedLoadingIndicator: true))
|
||||||
// case .waitingForLoadOlderPermission:
|
|
||||||
// switch to {
|
|
||||||
// case .idle, .loadingOlder(_, _):
|
|
||||||
// return true
|
|
||||||
// default:
|
|
||||||
// return false
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue