Use timeline segments for profile view controller

This commit is contained in:
Shadowfacts 2019-08-02 18:23:45 -06:00
parent 84cfa923ca
commit abd73fbe3b
Signed by untrusted user: shadowfacts
GPG Key ID: 94A5AB95422746E5
1 changed files with 28 additions and 26 deletions

View File

@ -22,7 +22,7 @@ class ProfileTableViewController: EnhancedTableViewController {
} }
} }
var statusIDs: [String] = [] { var timelineSegments: [TimelineSegment<Status>] = [] {
didSet { didSet {
DispatchQueue.main.async { DispatchQueue.main.async {
self.tableView.reloadData() self.tableView.reloadData()
@ -120,8 +120,10 @@ class ProfileTableViewController: EnhancedTableViewController {
getStatuses() { response in getStatuses() { response in
guard case let .success(statuses, pagination) = response else { fatalError() } guard case let .success(statuses, pagination) = response else { fatalError() }
MastodonCache.addAll(statuses: statuses) MastodonCache.addAll(statuses: statuses)
self.statusIDs = statuses.map { $0.id } self.timelineSegments.append(TimelineSegment(objects: statuses))
self.older = pagination?.older self.older = pagination?.older
self.newer = pagination?.newer self.newer = pagination?.newer
} }
@ -146,47 +148,44 @@ class ProfileTableViewController: EnhancedTableViewController {
// MARK: - Table view data source // MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int { override func numberOfSections(in tableView: UITableView) -> Int {
return 2 return 1 + timelineSegments.count
} }
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section { if section == 0 {
case 0:
return accountID == nil || MastodonCache.account(for: accountID) == nil ? 0 : 1 return accountID == nil || MastodonCache.account(for: accountID) == nil ? 0 : 1
case 1: } else {
return statusIDs.count return timelineSegments[section - 1].count
default:
return 0
} }
} }
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.section { if indexPath.section == 0 {
case 0:
guard let cell = tableView.dequeueReusableCell(withIdentifier: "headerCell", for: indexPath) as? ProfileHeaderTableViewCell else { fatalError() } guard let cell = tableView.dequeueReusableCell(withIdentifier: "headerCell", for: indexPath) as? ProfileHeaderTableViewCell else { fatalError() }
cell.selectionStyle = .none cell.selectionStyle = .none
cell.delegate = self cell.delegate = self
cell.updateUI(for: accountID) cell.updateUI(for: accountID)
return cell return cell
case 1: } else {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "statusCell", for: indexPath) as? StatusTableViewCell else { fatalError() } guard let cell = tableView.dequeueReusableCell(withIdentifier: "statusCell", for: indexPath) as? StatusTableViewCell else { fatalError() }
cell.updateUI(statusID: statusIDs[indexPath.row]) let statusID = timelineSegments[indexPath.section - 1][indexPath.row]
cell.updateUI(statusID: statusID)
cell.delegate = self cell.delegate = self
return cell return cell
default:
fatalError("Invalid section \(indexPath.section) for profile VC")
} }
} }
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.section == 1 && indexPath.row == statusIDs.count - 1 { if indexPath.section == timelineSegments.count && indexPath.row == timelineSegments[indexPath.section - 1].count - 1 {
guard let older = older else { return } guard let older = older else { return }
getStatuses(for: older) { response in getStatuses(for: older) { response in
guard case let .success(newStatuses, pagination) = response else { fatalError() } guard case let .success(newStatuses, pagination) = response else { fatalError() }
self.older = pagination?.older
MastodonCache.addAll(statuses: newStatuses) MastodonCache.addAll(statuses: newStatuses)
self.statusIDs.append(contentsOf: newStatuses.map { $0.id }) self.timelineSegments[indexPath.section - 1].append(objects: newStatuses)
self.older = pagination?.older
} }
} }
} }
@ -208,9 +207,12 @@ class ProfileTableViewController: EnhancedTableViewController {
getStatuses(for: newer) { response in getStatuses(for: newer) { response in
guard case let .success(newStatuses, pagination) = response else { fatalError() } guard case let .success(newStatuses, pagination) = response else { fatalError() }
self.newer = pagination?.newer
MastodonCache.addAll(statuses: newStatuses) MastodonCache.addAll(statuses: newStatuses)
self.statusIDs.insert(contentsOf: newStatuses.map { $0.id }, at: 0) self.timelineSegments[0].insertAtBeginning(objects: newStatuses)
self.newer = pagination?.newer
DispatchQueue.main.async { DispatchQueue.main.async {
self.refreshControl?.endRefreshing() self.refreshControl?.endRefreshing()
} }
@ -272,9 +274,9 @@ extension ProfileTableViewController: ProfileHeaderTableViewCellDelegate {
extension ProfileTableViewController: UITableViewDataSourcePrefetching { extension ProfileTableViewController: UITableViewDataSourcePrefetching {
func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) { func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) {
for indexPath in indexPaths { for indexPath in indexPaths where indexPath.section > 0 {
guard indexPath.section == 1, let statusID = timelineSegments[indexPath.section - 1][indexPath.row]
let status = MastodonCache.status(for: statusIDs[indexPath.row]) else { continue } guard let status = MastodonCache.status(for: statusID) else { continue }
ImageCache.avatars.get(status.account.avatar, completion: nil) ImageCache.avatars.get(status.account.avatar, completion: nil)
for attachment in status.attachments { for attachment in status.attachments {
ImageCache.attachments.get(attachment.url, completion: nil) ImageCache.attachments.get(attachment.url, completion: nil)
@ -283,9 +285,9 @@ extension ProfileTableViewController: UITableViewDataSourcePrefetching {
} }
func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) { func tableView(_ tableView: UITableView, cancelPrefetchingForRowsAt indexPaths: [IndexPath]) {
for indexPath in indexPaths { for indexPath in indexPaths where indexPath.section > 0 {
guard indexPath.section == 1, let statusID = timelineSegments[indexPath.section - 1][indexPath.row]
let status = MastodonCache.status(for: statusIDs[indexPath.row]) else { continue } guard let status = MastodonCache.status(for: statusID) else { continue }
ImageCache.avatars.cancel(status.account.avatar) ImageCache.avatars.cancel(status.account.avatar)
for attachment in status.attachments { for attachment in status.attachments {
ImageCache.attachments.cancel(attachment.url) ImageCache.attachments.cancel(attachment.url)