159 lines
5.2 KiB
Swift
159 lines
5.2 KiB
Swift
import UIKit
|
|
import WidgetKit
|
|
|
|
@MainActor
|
|
final class AppContext {
|
|
let core: GotchaCore
|
|
private let window: UIWindow
|
|
private(set) var tabs = UITabBarController()
|
|
private(set) var navigationControllers: [UINavigationController] = []
|
|
|
|
init(window: UIWindow) {
|
|
self.window = window
|
|
let storageDirectory = FileManager.default.containerURL(
|
|
forSecurityApplicationGroupIdentifier: "group.de.rfc1437.gotcha"
|
|
)?.path
|
|
core = GotchaCore(storageDirectory: storageDirectory)
|
|
applyAppearance()
|
|
}
|
|
|
|
func makeRootController() -> UIViewController {
|
|
let roots: [UIViewController] = [
|
|
HomeViewController(context: self),
|
|
repositoryRoot(mode: .issues),
|
|
repositoryRoot(mode: .commits),
|
|
PullsViewController(context: self),
|
|
repositoryRoot(mode: .milestones),
|
|
]
|
|
let items = [
|
|
("Home", "house", "house.fill"),
|
|
("Issues", "exclamationmark.circle", "exclamationmark.circle.fill"),
|
|
("Repos", "books.vertical", "books.vertical.fill"),
|
|
("PRs", "arrow.triangle.pull", "arrow.triangle.pull"),
|
|
("Milestones", "flag", "flag.fill"),
|
|
]
|
|
navigationControllers = zip(roots, items).map { root, item in
|
|
let navigation = UINavigationController(rootViewController: root)
|
|
navigation.tabBarItem = UITabBarItem(
|
|
title: item.0,
|
|
image: UIImage(systemName: item.1),
|
|
selectedImage: UIImage(systemName: item.2)
|
|
)
|
|
return navigation
|
|
}
|
|
tabs.viewControllers = navigationControllers
|
|
return tabs
|
|
}
|
|
|
|
func showStartupErrorIfNeeded() {
|
|
guard let message = core.startupError() else { return }
|
|
tabs.present(errorAlert(message), animated: true)
|
|
}
|
|
|
|
func selectServer(index: UInt32) throws {
|
|
try core.selectServer(index: index)
|
|
reloadAfterServerChange()
|
|
}
|
|
|
|
func reloadAfterServerChange() {
|
|
let replacements: [(Int, UIViewController)] = [
|
|
(0, HomeViewController(context: self)),
|
|
(1, repositoryRoot(mode: .issues)),
|
|
(2, repositoryRoot(mode: .commits)),
|
|
(3, PullsViewController(context: self)),
|
|
(4, repositoryRoot(mode: .milestones)),
|
|
]
|
|
for (index, root) in replacements {
|
|
navigationControllers[index].setViewControllers([root], animated: false)
|
|
}
|
|
WidgetCenter.shared.reloadAllTimelines()
|
|
}
|
|
|
|
@discardableResult
|
|
func route(widgetURL: URL) -> Bool {
|
|
guard widgetURL.scheme == "gotcha" else { return false }
|
|
let index: Int
|
|
switch widgetURL.host {
|
|
case "home": index = 0
|
|
case "pulls": index = 3
|
|
default: return false
|
|
}
|
|
tabs.selectedIndex = index
|
|
navigationControllers[index].popToRootViewController(animated: false)
|
|
return true
|
|
}
|
|
|
|
func didAddServer(index: UInt32) throws {
|
|
try selectServer(index: index)
|
|
}
|
|
|
|
func applyAppearance() {
|
|
switch core.settings().appearance {
|
|
case 1: window.overrideUserInterfaceStyle = .light
|
|
case 2: window.overrideUserInterfaceStyle = .dark
|
|
default: window.overrideUserInterfaceStyle = .unspecified
|
|
}
|
|
}
|
|
|
|
func route(_ activity: ActivityRow) {
|
|
switch activity.target {
|
|
case .repository:
|
|
tabs.selectedIndex = 1
|
|
navigationControllers[1].pushViewController(
|
|
IssuesViewController(
|
|
context: self,
|
|
owner: activity.owner,
|
|
repository: activity.repository
|
|
),
|
|
animated: true
|
|
)
|
|
case .issue:
|
|
tabs.selectedIndex = 1
|
|
navigationControllers[1].pushViewController(
|
|
IssueViewController(
|
|
context: self,
|
|
owner: activity.owner,
|
|
repository: activity.repository,
|
|
number: activity.number
|
|
),
|
|
animated: true
|
|
)
|
|
case .pullRequest:
|
|
tabs.selectedIndex = 3
|
|
navigationControllers[3].pushViewController(
|
|
PullViewController(
|
|
context: self,
|
|
owner: activity.owner,
|
|
repository: activity.repository,
|
|
number: activity.number
|
|
),
|
|
animated: true
|
|
)
|
|
case .commit:
|
|
tabs.selectedIndex = 2
|
|
navigationControllers[2].pushViewController(
|
|
FilesViewController(
|
|
context: self,
|
|
owner: activity.owner,
|
|
repository: activity.repository,
|
|
sha: activity.sha
|
|
),
|
|
animated: true
|
|
)
|
|
case .none:
|
|
break
|
|
}
|
|
}
|
|
|
|
func symbol(_ name: String) -> UIImage? {
|
|
UIImage(systemName: name)
|
|
}
|
|
|
|
private func repositoryRoot(mode: RepositoryPane) -> UIViewController {
|
|
if core.activeServerIndex() == nil {
|
|
return ServersViewController(context: self)
|
|
}
|
|
return RepositoriesViewController(context: self, mode: mode)
|
|
}
|
|
}
|