// // ProfileTableViewController.swift // Tusker // // Created by Shadowfacts on 8/27/18. // Copyright © 2018 Shadowfacts. All rights reserved. // import UIKit import MastodonKit import SafariServices class ProfileTableViewController: UITableViewController { static func create(for account: Account) -> UIViewController { guard let profileController = UIStoryboard(name: "Profile", bundle: nil).instantiateInitialViewController() as? ProfileTableViewController else { fatalError() } profileController.account = account return profileController } var account: Account! var statuses: [Status] = [] { didSet { DispatchQueue.main.async { self.tableView.reloadData() } } } var newer: RequestRange? var older: RequestRange? func request(for range: RequestRange? = .default) -> Request<[Status]> { let range = range ?? .default return Accounts.statuses(id: account.id, mediaOnly: false, pinnedOnly: false, excludeReplies: true, range: range) } override func viewDidLoad() { super.viewDidLoad() tableView.rowHeight = UITableView.automaticDimension tableView.estimatedRowHeight = 140 tableView.register(UINib(nibName: "StatusTableViewCell", bundle: nil), forCellReuseIdentifier: "statusCell") tableView.register(UINib(nibName: "ProfileHeaderTableViewCell", bundle: nil), forCellReuseIdentifier: "headerCell") navigationItem.title = account.displayName MastodonController.shared.client.run(request()) { result in guard case let .success(statuses, pagination) = result else { fatalError() } self.statuses = statuses self.newer = pagination?.previous self.older = pagination?.next } } /* // MARK: - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // Get the new view controller using segue.destination. // Pass the selected object to the new view controller. } */ // MARK: - Table view data source override func numberOfSections(in tableView: UITableView) -> Int { return 2 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { switch section { case 0: return 1 case 1: return statuses.count default: return 0 } } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { switch indexPath.section { case 0: guard let cell = tableView.dequeueReusableCell(withIdentifier: "headerCell", for: indexPath) as? ProfileHeaderTableViewCell else { fatalError() } cell.selectionStyle = .none cell.updateUI(for: account) cell.delegate = self return cell case 1: guard let cell = tableView.dequeueReusableCell(withIdentifier: "statusCell", for: indexPath) as? StatusTableViewCell else { fatalError() } let status = statuses[indexPath.row] cell.updateUI(for: status) cell.delegate = self return cell default: fatalError("Invalid section \(indexPath.section) for profile VC") } } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { guard indexPath.section == 1 else { return } guard let cell = tableView.cellForRow(at: indexPath) as? StatusTableViewCell else { fatalError() } cell.didSelect() } override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { if indexPath.section == 1 && indexPath.row == statuses.count - 1 { guard let older = older else { return } MastodonController.shared.client.run(request(for: older)) { result in guard case let .success(newStatuses, pagination) = result else { fatalError() } self.older = pagination?.next self.statuses.append(contentsOf: newStatuses) } } } @IBAction func refreshStatuses(_ sender: Any) { guard let newer = newer else { return } MastodonController.shared.client.run(request(for: newer)) { result in guard case let .success(newStatuses, pagination) = result else { fatalError() } self.newer = pagination?.previous self.statuses.insert(contentsOf: newStatuses, at: 0) DispatchQueue.main.async { self.refreshControl?.endRefreshing() } } } } extension ProfileTableViewController: ProfileHeaderTableViewCellDelegate { }