162 lines
5.3 KiB
Swift
162 lines
5.3 KiB
Swift
import UIKit
|
|
|
|
@MainActor
|
|
final class RepositoriesViewController: RefreshingTableViewController {
|
|
private let context: AppContext
|
|
private let mode: RepositoryPane
|
|
private var rows: [RepositoryRow] = []
|
|
private var currentPage: UInt32 = 0
|
|
|
|
private var panelTitle: String {
|
|
switch mode {
|
|
case .issues: return "Issues"
|
|
case .commits: return "Repositories"
|
|
case .milestones: return "Milestones"
|
|
case .actions: return "Actions"
|
|
}
|
|
}
|
|
|
|
init(context: AppContext, mode: RepositoryPane) {
|
|
self.context = context
|
|
self.mode = mode
|
|
super.init()
|
|
setPanelTitle(self, panelTitle, server: context.core.activeServerName())
|
|
}
|
|
|
|
@available(*, unavailable)
|
|
required init?(coder: NSCoder) { fatalError("init(coder:) is not supported") }
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
loadContent(refreshing: false)
|
|
}
|
|
|
|
override func viewWillAppear(_ animated: Bool) {
|
|
super.viewWillAppear(animated)
|
|
if navigationController?.viewControllers.first === self {
|
|
navigationItem.leftBarButtonItem = UIBarButtonItem(
|
|
image: context.symbol("server.rack"),
|
|
primaryAction: UIAction { [weak self] _ in
|
|
guard let self else { return }
|
|
self.navigationController?.pushViewController(
|
|
ServersViewController(context: self.context),
|
|
animated: true
|
|
)
|
|
}
|
|
)
|
|
} else {
|
|
navigationItem.leftBarButtonItem = nil
|
|
}
|
|
}
|
|
|
|
override func loadContent(refreshing: Bool) {
|
|
loadPage(1, refreshing: refreshing)
|
|
}
|
|
|
|
override func loadMoreContent() {
|
|
loadPage(currentPage + 1, refreshing: false)
|
|
}
|
|
|
|
private func loadPage(_ page: UInt32, refreshing: Bool) {
|
|
if page == 1 {
|
|
resetPagination()
|
|
beginLoading(refreshing: refreshing)
|
|
}
|
|
loadingTask?.cancel()
|
|
loadingTask = Task {
|
|
do {
|
|
let result = try await context.core.repositories(page: page, pane: mode)
|
|
rows = result.rows
|
|
currentPage = page
|
|
finishPagination(hasMore: result.hasMore)
|
|
tableView.reloadData()
|
|
tableView.backgroundView = rows.isEmpty
|
|
? EmptyBackgroundView(
|
|
title: "No repositories",
|
|
detail: "This account does not own any repositories on this server."
|
|
)
|
|
: nil
|
|
} catch {
|
|
if !Task.isCancelled {
|
|
show(error: error)
|
|
failPagination()
|
|
}
|
|
}
|
|
if page == 1 { endLoading() }
|
|
}
|
|
}
|
|
|
|
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
|
rows.count
|
|
}
|
|
|
|
override func tableView(
|
|
_ tableView: UITableView,
|
|
cellForRowAt indexPath: IndexPath
|
|
) -> UITableViewCell {
|
|
let cell = tableView.dequeueReusableCell(withIdentifier: "repository")
|
|
?? UITableViewCell(style: .subtitle, reuseIdentifier: "repository")
|
|
let row = rows[indexPath.row]
|
|
configureTextCell(cell, title: row.name, detail: "\(row.description)\n\(row.meta)")
|
|
let button = UIButton(type: .system, primaryAction: UIAction { [weak self] _ in
|
|
self?.toggleFavorite(row)
|
|
})
|
|
button.setImage(context.symbol(row.favorite ? "star.fill" : "star"), for: .normal)
|
|
button.tintColor = row.favorite ? .systemYellow : .tertiaryLabel
|
|
button.frame.size = CGSize(width: 44, height: 44)
|
|
cell.accessoryView = button
|
|
return cell
|
|
}
|
|
|
|
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
|
|
96
|
|
}
|
|
|
|
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
|
tableView.deselectRow(at: indexPath, animated: true)
|
|
let row = rows[indexPath.row]
|
|
let destination: UIViewController
|
|
switch mode {
|
|
case .issues:
|
|
destination = IssuesViewController(
|
|
context: context,
|
|
owner: row.owner,
|
|
repository: row.name
|
|
)
|
|
case .commits:
|
|
destination = CommitsViewController(
|
|
context: context,
|
|
owner: row.owner,
|
|
repository: row.name
|
|
)
|
|
case .milestones:
|
|
destination = MilestonesViewController(
|
|
context: context,
|
|
owner: row.owner,
|
|
repository: row.name
|
|
)
|
|
case .actions:
|
|
destination = ActionsViewController(
|
|
context: context,
|
|
owner: row.owner,
|
|
repository: row.name,
|
|
defaultBranch: row.defaultBranch
|
|
)
|
|
}
|
|
navigationController?.pushViewController(destination, animated: true)
|
|
}
|
|
|
|
private func toggleFavorite(_ row: RepositoryRow) {
|
|
do {
|
|
rows = try context.core.toggleFavorite(
|
|
owner: row.owner,
|
|
repository: row.name,
|
|
pane: mode
|
|
)
|
|
tableView.reloadData()
|
|
} catch {
|
|
show(error: error)
|
|
}
|
|
}
|
|
}
|