156 lines
5.6 KiB
Swift
156 lines
5.6 KiB
Swift
// Copyright © 2023 Mastodon gGmbH. All rights reserved.
|
|
|
|
import UIKit
|
|
import MastodonSDK
|
|
|
|
protocol AboutInstanceViewControllerDelegate: AnyObject {
|
|
func showAdminAccount(_ viewController: AboutInstanceViewController, account: Mastodon.Entity.Account)
|
|
func sendEmailToAdmin(_ viewController: AboutInstanceViewController, emailAddress: String)
|
|
}
|
|
|
|
class AboutInstanceViewController: UIViewController {
|
|
|
|
weak var delegate: AboutInstanceViewControllerDelegate?
|
|
var dataSource: AboutInstanceTableViewDataSource?
|
|
|
|
let tableView: UITableView
|
|
let headerView: AboutInstanceTableHeaderView
|
|
let footerView: AboutInstanceTableFooterView
|
|
|
|
var instance: Mastodon.Entity.V2.Instance?
|
|
|
|
init() {
|
|
tableView = UITableView(frame: .zero, style: .insetGrouped)
|
|
tableView.translatesAutoresizingMaskIntoConstraints = false
|
|
tableView.register(ContactAdminTableViewCell.self, forCellReuseIdentifier: ContactAdminTableViewCell.reuseIdentifier)
|
|
tableView.register(AdminTableViewCell.self, forCellReuseIdentifier: AdminTableViewCell.reuseIdentifier)
|
|
|
|
headerView = AboutInstanceTableHeaderView()
|
|
footerView = AboutInstanceTableFooterView()
|
|
|
|
super.init(nibName: nil, bundle: nil)
|
|
|
|
let dataSource = AboutInstanceTableViewDataSource(tableView: tableView) { tableView, indexPath, itemIdentifier in
|
|
switch itemIdentifier {
|
|
|
|
case .adminAccount(let account):
|
|
guard let cell = tableView.dequeueReusableCell(withIdentifier: AdminTableViewCell.reuseIdentifier, for: indexPath) as? AdminTableViewCell else { fatalError("WTF?! Wrong cell.") }
|
|
|
|
cell.condensedUserView.configure(with: account, showFollowers: false)
|
|
|
|
return cell
|
|
|
|
case .contactAdmin:
|
|
guard let cell = tableView.dequeueReusableCell(withIdentifier: ContactAdminTableViewCell.reuseIdentifier, for: indexPath) as? ContactAdminTableViewCell else { fatalError("WTF?! Wrong cell.") }
|
|
|
|
cell.configure()
|
|
|
|
return cell
|
|
}
|
|
}
|
|
|
|
tableView.delegate = self
|
|
tableView.dataSource = dataSource
|
|
|
|
self.dataSource = dataSource
|
|
|
|
view.addSubview(tableView)
|
|
|
|
setupConstraints()
|
|
}
|
|
|
|
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
|
|
|
|
private func setupConstraints() {
|
|
let constraints = [
|
|
tableView.topAnchor.constraint(equalTo: view.topAnchor),
|
|
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
|
view.trailingAnchor.constraint(equalTo: tableView.trailingAnchor),
|
|
view.bottomAnchor.constraint(equalTo: tableView.bottomAnchor),
|
|
]
|
|
|
|
NSLayoutConstraint.activate(constraints)
|
|
}
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
tableView.tableHeaderView = headerView
|
|
tableView.tableFooterView = footerView
|
|
}
|
|
|
|
override func viewWillLayoutSubviews() {
|
|
super.viewWillLayoutSubviews()
|
|
|
|
if let tableHeaderView = tableView.tableHeaderView {
|
|
let size = tableHeaderView.systemLayoutSizeFitting(.init(width: self.tableView.frame.width, height: 10_000))
|
|
tableHeaderView.frame.size = size
|
|
tableView.tableHeaderView = tableHeaderView
|
|
}
|
|
|
|
if let tableFooterView = tableView.tableFooterView {
|
|
let size = tableFooterView.systemLayoutSizeFitting(.init(width: self.tableView.frame.width, height: 10_000))
|
|
tableFooterView.frame.size = size
|
|
tableView.tableFooterView = tableFooterView
|
|
}
|
|
|
|
super.viewWillLayoutSubviews()
|
|
}
|
|
|
|
func update(with instance: Mastodon.Entity.V2.Instance) {
|
|
|
|
self.instance = instance
|
|
var snapshot = NSDiffableDataSourceSnapshot<AboutInstanceSection, AboutInstanceItem>()
|
|
|
|
snapshot.appendSections([.main])
|
|
if let account = instance.contact?.account {
|
|
snapshot.appendItems([.adminAccount(account)], toSection: .main)
|
|
}
|
|
|
|
if let email = instance.contact?.email {
|
|
snapshot.appendItems([.contactAdmin(email)], toSection: .main)
|
|
}
|
|
|
|
dataSource?.apply(snapshot, animatingDifferences: false)
|
|
|
|
guard let thumbnailUrlString = instance.thumbnail?.url, let thumbnailUrl = URL(string: thumbnailUrlString) else { return }
|
|
|
|
DispatchQueue.main.async {
|
|
self.headerView.updateImage(with: thumbnailUrl) { [weak self] in
|
|
DispatchQueue.main.async {
|
|
guard let self else { return }
|
|
|
|
self.view.setNeedsLayout()
|
|
self.view.layoutIfNeeded()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func updateFooter(with extendedDescription: Mastodon.Entity.ExtendedDescription) {
|
|
DispatchQueue.main.async {
|
|
self.footerView.update(with: extendedDescription)
|
|
|
|
self.view.setNeedsLayout()
|
|
self.view.layoutIfNeeded()
|
|
}
|
|
}
|
|
}
|
|
|
|
extension AboutInstanceViewController: UITableViewDelegate {
|
|
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
|
guard let snapshot = dataSource?.snapshot() else {
|
|
return tableView.deselectRow(at: indexPath, animated: true)
|
|
}
|
|
|
|
switch snapshot.itemIdentifiers(inSection: .main)[indexPath.row] {
|
|
case .adminAccount(let account):
|
|
delegate?.showAdminAccount(self, account: account)
|
|
case .contactAdmin(let email):
|
|
delegate?.sendEmailToAdmin(self, emailAddress: email)
|
|
}
|
|
|
|
tableView.deselectRow(at: indexPath, animated: true)
|
|
}
|
|
}
|