Prepare Gotcha 1.0 for release
This commit is contained in:
95
ios/Sources/DiffScreen.swift
Normal file
95
ios/Sources/DiffScreen.swift
Normal file
@@ -0,0 +1,95 @@
|
||||
import UIKit
|
||||
|
||||
enum DiffSource {
|
||||
case commit(owner: String, repository: String, sha: String, path: String)
|
||||
case pull(owner: String, repository: String, number: Int64, path: String)
|
||||
}
|
||||
|
||||
@MainActor
|
||||
final class DiffViewController: UIViewController {
|
||||
private let context: AppContext
|
||||
private let source: DiffSource
|
||||
private let codeView = CodeScrollView()
|
||||
private let spinner = UIActivityIndicatorView(style: .medium)
|
||||
private var loadingTask: Task<Void, Never>?
|
||||
|
||||
init(context: AppContext, source: DiffSource) {
|
||||
self.context = context
|
||||
self.source = source
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) { fatalError("init(coder:) is not supported") }
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
view.backgroundColor = .systemBackground
|
||||
codeView.refreshControl = UIRefreshControl()
|
||||
codeView.refreshControl?.addTarget(self, action: #selector(reload), for: .valueChanged)
|
||||
view.addSubview(codeView)
|
||||
NSLayoutConstraint.activate([
|
||||
codeView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
|
||||
codeView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
|
||||
codeView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
|
||||
codeView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
|
||||
])
|
||||
beginNavigationLoading(spinner)
|
||||
reload()
|
||||
}
|
||||
|
||||
deinit { loadingTask?.cancel() }
|
||||
|
||||
@objc private func reload() {
|
||||
loadingTask?.cancel()
|
||||
loadingTask = Task {
|
||||
do {
|
||||
let page: DiffPage
|
||||
switch source {
|
||||
case let .commit(owner, repository, sha, path):
|
||||
page = try await context.core.commitDiff(
|
||||
owner: owner,
|
||||
repository: repository,
|
||||
sha: sha,
|
||||
path: path
|
||||
)
|
||||
case let .pull(owner, repository, number, path):
|
||||
page = try await context.core.pullDiff(
|
||||
owner: owner,
|
||||
repository: repository,
|
||||
number: number,
|
||||
path: path
|
||||
)
|
||||
}
|
||||
title = page.title
|
||||
codeView.display(diffText(page))
|
||||
} catch {
|
||||
if !Task.isCancelled { show(error: error) }
|
||||
}
|
||||
endNavigationLoading(spinner)
|
||||
codeView.refreshControl?.endRefreshing()
|
||||
}
|
||||
}
|
||||
|
||||
private func diffText(_ page: DiffPage) -> NSAttributedString {
|
||||
let output = NSMutableAttributedString()
|
||||
let font = UIFont.monospacedSystemFont(ofSize: 12, weight: .regular)
|
||||
for line in page.lines {
|
||||
let text = String(format: "%4@ %4@ %@\n", line.oldNumber, line.newNumber, line.text)
|
||||
let color: UIColor
|
||||
switch line.kind {
|
||||
case .addition: color = UIColor.systemGreen.withAlphaComponent(0.16)
|
||||
case .removal: color = UIColor.systemRed.withAlphaComponent(0.16)
|
||||
case .hunk: color = UIColor.systemBlue.withAlphaComponent(0.14)
|
||||
case .header: color = UIColor.systemGray.withAlphaComponent(0.14)
|
||||
case .context: color = .clear
|
||||
}
|
||||
output.append(NSAttributedString(string: text, attributes: [
|
||||
.font: font,
|
||||
.foregroundColor: UIColor.label,
|
||||
.backgroundColor: color,
|
||||
]))
|
||||
}
|
||||
return output
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user