iOS/Sources/App/Servers/ServerSelectViewController....

104 lines
2.7 KiB
Swift

import Eureka
import PromiseKit
import Shared
import UIKit
class ServerSelectViewController: HAFormViewController, ServerObserver, UIAdaptivePresentationControllerDelegate {
let result: Promise<AccountRowValue>
private let resultSeal: Resolver<AccountRowValue>
enum ServerSelectError: Error, CancellableError {
case cancelled
var isCancelled: Bool {
switch self {
case .cancelled: return true
}
}
}
var prompt: String? {
didSet {
setupForm()
}
}
var allowAll: Bool = false {
didSet {
setupForm()
}
}
override init() {
(self.result, self.resultSeal) = Promise<AccountRowValue>.pending()
super.init()
title = L10n.Settings.ServerSelect.pageTitle
navigationItem.leftBarButtonItems = [
UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancel(_:))),
]
}
override func viewDidLoad() {
super.viewDidLoad()
setupForm()
Current.servers.add(observer: self)
}
@objc private func cancel(_ sender: UIBarButtonItem) {
resultSeal.reject(ServerSelectError.cancelled)
}
override func willMove(toParent parent: UIViewController?) {
super.willMove(toParent: parent)
if let parent = parent as? UINavigationController, parent.viewControllers == [self] {
parent.presentationController?.delegate = self
// sheet is a little annoying (even with large detent) with many servers
if Current.servers.all.count <= 4 {
with(parent.sheetPresentationController) {
$0?.detents = [.medium(), .large()]
}
}
}
}
func serversDidChange(_ serverManager: ServerManager) {
UIView.performWithoutAnimation {
setupForm()
}
}
func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
resultSeal.reject(ServerSelectError.cancelled)
}
private func setupForm() {
form.removeAll()
if let prompt, !prompt.isEmpty {
form +++ InfoLabelRow {
$0.title = prompt
}
}
var rows = [AccountRowValue]()
if allowAll {
rows.append(.all)
}
rows.append(contentsOf: Current.servers.all.map { .server($0) })
form +++ Section(rows.map { value in
HomeAssistantAccountRow {
$0.value = value
$0.onCellSelection { [resultSeal] _, _ in
resultSeal.fulfill(value)
}
}
})
}
}