forked from shadowfacts/Tusker
Switch hashtag/instance/list timelines to use new collection view impl
This commit is contained in:
parent
658c08010d
commit
b1d83f2746
|
@ -9,7 +9,7 @@
|
|||
import UIKit
|
||||
import Pachyderm
|
||||
|
||||
class ListTimelineViewController: TimelineTableViewController {
|
||||
class ListTimelineViewController: TimelineViewController {
|
||||
|
||||
let list: List
|
||||
|
||||
|
@ -57,8 +57,11 @@ class ListTimelineViewController: TimelineTableViewController {
|
|||
@objc func editListDoneButtonPressed() {
|
||||
dismiss(animated: true)
|
||||
|
||||
// todo: show loading indicator
|
||||
reloadInitial()
|
||||
// TODO: only reload if there were changes
|
||||
Task {
|
||||
applyInitialSnapshot()
|
||||
await controller.loadInitial()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import UIKit
|
||||
import Pachyderm
|
||||
|
||||
class HashtagTimelineViewController: TimelineTableViewController {
|
||||
class HashtagTimelineViewController: TimelineViewController {
|
||||
|
||||
let hashtag: Hashtag
|
||||
|
||||
|
|
|
@ -7,13 +7,14 @@
|
|||
//
|
||||
|
||||
import UIKit
|
||||
import Pachyderm
|
||||
|
||||
protocol InstanceTimelineViewControllerDelegate: AnyObject {
|
||||
func didSaveInstance(url: URL)
|
||||
func didUnsaveInstance(url: URL)
|
||||
}
|
||||
|
||||
class InstanceTimelineViewController: TimelineTableViewController {
|
||||
class InstanceTimelineViewController: TimelineViewController {
|
||||
|
||||
weak var delegate: InstanceTimelineViewControllerDelegate?
|
||||
|
||||
|
@ -68,19 +69,15 @@ class InstanceTimelineViewController: TimelineTableViewController {
|
|||
toggleSaveButton.title = toggleSaveButtonTitle
|
||||
}
|
||||
|
||||
// MARK: - Table view data source
|
||||
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = super.tableView(tableView, cellForRowAt: indexPath) as! TimelineStatusTableViewCell
|
||||
override func configureStatusCell(_ cell: TimelineStatusCollectionViewCell, id: String, state: StatusState) {
|
||||
cell.delegate = browsingEnabled ? self : nil
|
||||
return cell
|
||||
cell.overrideMastodonController = mastodonController
|
||||
cell.updateUI(statusID: id, state: state)
|
||||
}
|
||||
|
||||
// MARK: - Table view delegate
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||
guard browsingEnabled else { return }
|
||||
super.tableView(tableView, didSelectRowAt: indexPath)
|
||||
super.collectionView(collectionView, didSelectItemAt: indexPath)
|
||||
}
|
||||
|
||||
// MARK: - Interaction
|
||||
|
|
|
@ -34,6 +34,7 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
|
|||
|
||||
self.controller = TimelineLikeController(delegate: self)
|
||||
|
||||
self.navigationItem.title = timeline.title
|
||||
addKeyCommand(MenuController.refreshCommand(discoverabilityTitle: "Refresh Timeline"))
|
||||
}
|
||||
|
||||
|
@ -84,10 +85,15 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
|
|||
super.viewDidLoad()
|
||||
}
|
||||
|
||||
// separate method because InstanceTimelineViewController needs to be able to customize it
|
||||
func configureStatusCell(_ cell: TimelineStatusCollectionViewCell, id: String, state: StatusState) {
|
||||
cell.delegate = self
|
||||
cell.updateUI(statusID: id, state: state)
|
||||
}
|
||||
|
||||
private func createDataSource() -> UICollectionViewDiffableDataSource<Section, Item> {
|
||||
let statusCell = UICollectionView.CellRegistration<TimelineStatusCollectionViewCell, (String, StatusState)> { [unowned self] cell, indexPath, item in
|
||||
cell.delegate = self
|
||||
cell.updateUI(statusID: item.0, state: item.1)
|
||||
self.configureStatusCell(cell, id: item.0, state: item.1)
|
||||
}
|
||||
let timelineDescriptionCell = UICollectionView.CellRegistration<PublicTimelineDescriptionCollectionViewCell, Item> { [unowned self] cell, indexPath, item in
|
||||
guard case .public(let local) = timeline else {
|
||||
|
@ -114,15 +120,16 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro
|
|||
}
|
||||
}
|
||||
|
||||
private func applyInitialSnapshot() {
|
||||
// non-private, because ListTimelineViewController needs to be able to reload it from scratch
|
||||
func applyInitialSnapshot() {
|
||||
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
||||
if case .public(let local) = timeline,
|
||||
(local && !Preferences.shared.hasShownLocalTimelineDescription) ||
|
||||
(!local && !Preferences.shared.hasShownFederatedTimelineDescription) {
|
||||
var snapshot = dataSource.snapshot()
|
||||
snapshot.appendSections([.header])
|
||||
snapshot.appendItems([.publicTimelineDescription], toSection: .header)
|
||||
dataSource.apply(snapshot, animatingDifferences: false)
|
||||
}
|
||||
dataSource.apply(snapshot, animatingDifferences: false)
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
|
|
|
@ -51,7 +51,7 @@ actor TimelineLikeController<Item> {
|
|||
}
|
||||
|
||||
func loadInitial() async {
|
||||
guard state == .notLoadedInitial else {
|
||||
guard state == .notLoadedInitial || state == .idle else {
|
||||
return
|
||||
}
|
||||
let token = LoadAttemptToken()
|
||||
|
@ -175,14 +175,14 @@ actor TimelineLikeController<Item> {
|
|||
switch self {
|
||||
case .notLoadedInitial:
|
||||
switch to {
|
||||
case .loadingInitial(_, hasAddedLoadingIndicator: _):
|
||||
case .loadingInitial(_, _):
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
case .idle:
|
||||
switch to {
|
||||
case .loadingNewer(_), .loadingOlder(_, _):
|
||||
case .loadingInitial(_, _), .loadingNewer(_), .loadingOlder(_, _):
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
|
|
|
@ -30,6 +30,7 @@ protocol StatusCollectionViewCell: UICollectionViewCell, AttachmentViewDelegate
|
|||
var moreButton: UIButton { get }
|
||||
|
||||
var delegate: StatusCollectionViewCellDelegate? { get }
|
||||
var mastodonController: MastodonController! { get }
|
||||
|
||||
var showStatusAutomatically: Bool { get }
|
||||
var showReplyIndicator: Bool { get }
|
||||
|
@ -75,8 +76,6 @@ extension StatusCollectionViewCell {
|
|||
}
|
||||
|
||||
func doUpdateUI(status: StatusMO) {
|
||||
precondition(delegate != nil, "StatusCollectionViewCell must have delegate")
|
||||
|
||||
statusID = status.id
|
||||
accountID = status.account.id
|
||||
|
||||
|
|
|
@ -227,6 +227,8 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti
|
|||
private var mainContainerBottomToActionsConstraint: NSLayoutConstraint!
|
||||
private var mainContainerBottomToSelfConstraint: NSLayoutConstraint!
|
||||
|
||||
weak var overrideMastodonController: MastodonController?
|
||||
var mastodonController: MastodonController! { overrideMastodonController ?? delegate?.apiController }
|
||||
weak var delegate: StatusCollectionViewCellDelegate?
|
||||
var showStatusAutomatically: Bool {
|
||||
// TODO: needed once conversation controller refactored
|
||||
|
|
Loading…
Reference in New Issue