Add server editing and deletion
This commit is contained in:
@@ -671,10 +671,14 @@ public protocol GotchaCoreProtocol: AnyObject, Sendable {
|
||||
|
||||
func addServer(name: String, url: String, token: String, provider: ServerProvider) async throws -> UInt32
|
||||
|
||||
func deleteServer(index: UInt32) async throws
|
||||
|
||||
func home(page: UInt32, filter: HomeActivityFilter) async throws -> HomePage
|
||||
|
||||
func selectServer(index: UInt32) throws
|
||||
|
||||
func serverEditor(index: UInt32) throws -> ServerEditor
|
||||
|
||||
func servers() -> [ServerRow]
|
||||
|
||||
func setAppearance(index: UInt32) throws
|
||||
@@ -687,6 +691,8 @@ public protocol GotchaCoreProtocol: AnyObject, Sendable {
|
||||
|
||||
func startupError() -> String?
|
||||
|
||||
func updateServer(index: UInt32, name: String, url: String, token: String, provider: ServerProvider) async throws
|
||||
|
||||
}
|
||||
open class GotchaCore: GotchaCoreProtocol, @unchecked Sendable {
|
||||
fileprivate let handle: UInt64
|
||||
@@ -1240,6 +1246,22 @@ open func addServer(name: String, url: String, token: String, provider: ServerPr
|
||||
)
|
||||
}
|
||||
|
||||
open func deleteServer(index: UInt32)async throws {
|
||||
return
|
||||
try await uniffiRustCallAsync(
|
||||
rustFutureFunc: {
|
||||
uniffi_gotcha_core_fn_method_gotchacore_delete_server(
|
||||
self.uniffiCloneHandle(),FfiConverterUInt32.lower(index)
|
||||
)
|
||||
},
|
||||
pollFunc: ffi_gotcha_core_rust_future_poll_void,
|
||||
completeFunc: ffi_gotcha_core_rust_future_complete_void,
|
||||
freeFunc: ffi_gotcha_core_rust_future_free_void,
|
||||
liftFunc: { $0 },
|
||||
errorHandler: FfiConverterTypeGotchaError_lift
|
||||
)
|
||||
}
|
||||
|
||||
open func home(page: UInt32, filter: HomeActivityFilter)async throws -> HomePage {
|
||||
return
|
||||
try await uniffiRustCallAsync(
|
||||
@@ -1265,6 +1287,16 @@ open func selectServer(index: UInt32)throws {try rustCallWithError(FfiConverte
|
||||
}
|
||||
}
|
||||
|
||||
open func serverEditor(index: UInt32)throws -> ServerEditor {
|
||||
return try FfiConverterTypeServerEditor_lift(try rustCallWithError(FfiConverterTypeGotchaError_lift) {
|
||||
uniffiCallStatus in
|
||||
uniffi_gotcha_core_fn_method_gotchacore_server_editor(
|
||||
self.uniffiCloneHandle(),
|
||||
FfiConverterUInt32.lower(index),uniffiCallStatus
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
open func servers() -> [ServerRow] {
|
||||
return try! FfiConverterSequenceTypeServerRow.lift(try! rustCall() {
|
||||
uniffiCallStatus in
|
||||
@@ -1319,6 +1351,22 @@ open func startupError() -> String? {
|
||||
})
|
||||
}
|
||||
|
||||
open func updateServer(index: UInt32, name: String, url: String, token: String, provider: ServerProvider)async throws {
|
||||
return
|
||||
try await uniffiRustCallAsync(
|
||||
rustFutureFunc: {
|
||||
uniffi_gotcha_core_fn_method_gotchacore_update_server(
|
||||
self.uniffiCloneHandle(),FfiConverterUInt32.lower(index),FfiConverterString.lower(name),FfiConverterString.lower(url),FfiConverterString.lower(token),FfiConverterTypeServerProvider_lower(provider)
|
||||
)
|
||||
},
|
||||
pollFunc: ffi_gotcha_core_rust_future_poll_void,
|
||||
completeFunc: ffi_gotcha_core_rust_future_complete_void,
|
||||
freeFunc: ffi_gotcha_core_rust_future_free_void,
|
||||
liftFunc: { $0 },
|
||||
errorHandler: FfiConverterTypeGotchaError_lift
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -3415,6 +3463,58 @@ public func FfiConverterTypeRepositoryRow_lower(_ value: RepositoryRow) -> RustB
|
||||
}
|
||||
|
||||
|
||||
public struct ServerEditor: Equatable, Hashable {
|
||||
public var name: String
|
||||
public var url: String
|
||||
public var provider: ServerProvider
|
||||
|
||||
// Default memberwise initializers are never public by default, so we
|
||||
// declare one manually.
|
||||
public init(name: String, url: String, provider: ServerProvider) {
|
||||
self.name = name
|
||||
self.url = url
|
||||
self.provider = provider
|
||||
}
|
||||
}
|
||||
|
||||
#if compiler(>=6)
|
||||
extension ServerEditor: Sendable {}
|
||||
#endif
|
||||
|
||||
#if swift(>=5.8)
|
||||
@_documentation(visibility: private)
|
||||
#endif
|
||||
public struct FfiConverterTypeServerEditor: FfiConverterRustBuffer {
|
||||
public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ServerEditor {
|
||||
return
|
||||
try ServerEditor(
|
||||
name: FfiConverterString.read(from: &buf),
|
||||
url: FfiConverterString.read(from: &buf),
|
||||
provider: FfiConverterTypeServerProvider.read(from: &buf)
|
||||
)
|
||||
}
|
||||
|
||||
public static func write(_ value: ServerEditor, into buf: inout [UInt8]) {
|
||||
FfiConverterString.write(value.name, into: &buf)
|
||||
FfiConverterString.write(value.url, into: &buf)
|
||||
FfiConverterTypeServerProvider.write(value.provider, into: &buf)
|
||||
}
|
||||
}
|
||||
|
||||
#if swift(>=5.8)
|
||||
@_documentation(visibility: private)
|
||||
#endif
|
||||
public func FfiConverterTypeServerEditor_lift(_ buf: RustBuffer) throws -> ServerEditor {
|
||||
return try FfiConverterTypeServerEditor.lift(buf)
|
||||
}
|
||||
|
||||
#if swift(>=5.8)
|
||||
@_documentation(visibility: private)
|
||||
#endif
|
||||
public func FfiConverterTypeServerEditor_lower(_ value: ServerEditor) -> RustBuffer {
|
||||
return FfiConverterTypeServerEditor.lower(value)
|
||||
}
|
||||
|
||||
public struct ServerRow: Equatable, Hashable {
|
||||
public var name: String
|
||||
public var url: String
|
||||
@@ -5012,12 +5112,18 @@ private let initializationResult: InitializationResult = {
|
||||
if (uniffi_gotcha_core_checksum_method_gotchacore_add_server() != 51168) {
|
||||
return InitializationResult.apiChecksumMismatch
|
||||
}
|
||||
if (uniffi_gotcha_core_checksum_method_gotchacore_delete_server() != 5208) {
|
||||
return InitializationResult.apiChecksumMismatch
|
||||
}
|
||||
if (uniffi_gotcha_core_checksum_method_gotchacore_home() != 37602) {
|
||||
return InitializationResult.apiChecksumMismatch
|
||||
}
|
||||
if (uniffi_gotcha_core_checksum_method_gotchacore_select_server() != 10204) {
|
||||
return InitializationResult.apiChecksumMismatch
|
||||
}
|
||||
if (uniffi_gotcha_core_checksum_method_gotchacore_server_editor() != 36193) {
|
||||
return InitializationResult.apiChecksumMismatch
|
||||
}
|
||||
if (uniffi_gotcha_core_checksum_method_gotchacore_servers() != 16732) {
|
||||
return InitializationResult.apiChecksumMismatch
|
||||
}
|
||||
@@ -5036,6 +5142,9 @@ private let initializationResult: InitializationResult = {
|
||||
if (uniffi_gotcha_core_checksum_method_gotchacore_startup_error() != 58843) {
|
||||
return InitializationResult.apiChecksumMismatch
|
||||
}
|
||||
if (uniffi_gotcha_core_checksum_method_gotchacore_update_server() != 31001) {
|
||||
return InitializationResult.apiChecksumMismatch
|
||||
}
|
||||
if (uniffi_gotcha_core_checksum_constructor_gotchacore_new() != 35044) {
|
||||
return InitializationResult.apiChecksumMismatch
|
||||
}
|
||||
@@ -5056,4 +5165,4 @@ public func uniffiEnsureGotchaCoreInitialized() {
|
||||
}
|
||||
}
|
||||
|
||||
// swiftlint:enable all
|
||||
// swiftlint:enable all
|
||||
|
||||
@@ -429,6 +429,11 @@ RustBuffer uniffi_gotcha_core_fn_method_gotchacore_active_server_name(uint64_t p
|
||||
uint64_t uniffi_gotcha_core_fn_method_gotchacore_add_server(uint64_t ptr, RustBuffer name, RustBuffer url, RustBuffer token, RustBuffer provider
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_FN_METHOD_GOTCHACORE_DELETE_SERVER
|
||||
#define UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_FN_METHOD_GOTCHACORE_DELETE_SERVER
|
||||
uint64_t uniffi_gotcha_core_fn_method_gotchacore_delete_server(uint64_t ptr, uint32_t index
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_FN_METHOD_GOTCHACORE_HOME
|
||||
#define UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_FN_METHOD_GOTCHACORE_HOME
|
||||
uint64_t uniffi_gotcha_core_fn_method_gotchacore_home(uint64_t ptr, uint32_t page, RustBuffer filter
|
||||
@@ -439,6 +444,11 @@ uint64_t uniffi_gotcha_core_fn_method_gotchacore_home(uint64_t ptr, uint32_t pag
|
||||
void uniffi_gotcha_core_fn_method_gotchacore_select_server(uint64_t ptr, uint32_t index, RustCallStatus *_Nonnull out_status
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_FN_METHOD_GOTCHACORE_SERVER_EDITOR
|
||||
#define UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_FN_METHOD_GOTCHACORE_SERVER_EDITOR
|
||||
RustBuffer uniffi_gotcha_core_fn_method_gotchacore_server_editor(uint64_t ptr, uint32_t index, RustCallStatus *_Nonnull out_status
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_FN_METHOD_GOTCHACORE_SERVERS
|
||||
#define UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_FN_METHOD_GOTCHACORE_SERVERS
|
||||
RustBuffer uniffi_gotcha_core_fn_method_gotchacore_servers(uint64_t ptr, RustCallStatus *_Nonnull out_status
|
||||
@@ -469,6 +479,11 @@ RustBuffer uniffi_gotcha_core_fn_method_gotchacore_settings(uint64_t ptr, RustCa
|
||||
RustBuffer uniffi_gotcha_core_fn_method_gotchacore_startup_error(uint64_t ptr, RustCallStatus *_Nonnull out_status
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_FN_METHOD_GOTCHACORE_UPDATE_SERVER
|
||||
#define UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_FN_METHOD_GOTCHACORE_UPDATE_SERVER
|
||||
uint64_t uniffi_gotcha_core_fn_method_gotchacore_update_server(uint64_t ptr, uint32_t index, RustBuffer name, RustBuffer url, RustBuffer token, RustBuffer provider
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_FFI_GOTCHA_CORE_RUSTBUFFER_ALLOC
|
||||
#define UNIFFI_FFIDEF_FFI_GOTCHA_CORE_RUSTBUFFER_ALLOC
|
||||
RustBuffer ffi_gotcha_core_rustbuffer_alloc(uint64_t size, RustCallStatus *_Nonnull out_status
|
||||
@@ -931,6 +946,12 @@ uint16_t uniffi_gotcha_core_checksum_method_gotchacore_active_server_name(void
|
||||
#define UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_CHECKSUM_METHOD_GOTCHACORE_ADD_SERVER
|
||||
uint16_t uniffi_gotcha_core_checksum_method_gotchacore_add_server(void
|
||||
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_CHECKSUM_METHOD_GOTCHACORE_DELETE_SERVER
|
||||
#define UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_CHECKSUM_METHOD_GOTCHACORE_DELETE_SERVER
|
||||
uint16_t uniffi_gotcha_core_checksum_method_gotchacore_delete_server(void
|
||||
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_CHECKSUM_METHOD_GOTCHACORE_HOME
|
||||
@@ -943,6 +964,12 @@ uint16_t uniffi_gotcha_core_checksum_method_gotchacore_home(void
|
||||
#define UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_CHECKSUM_METHOD_GOTCHACORE_SELECT_SERVER
|
||||
uint16_t uniffi_gotcha_core_checksum_method_gotchacore_select_server(void
|
||||
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_CHECKSUM_METHOD_GOTCHACORE_SERVER_EDITOR
|
||||
#define UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_CHECKSUM_METHOD_GOTCHACORE_SERVER_EDITOR
|
||||
uint16_t uniffi_gotcha_core_checksum_method_gotchacore_server_editor(void
|
||||
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_CHECKSUM_METHOD_GOTCHACORE_SERVERS
|
||||
@@ -979,6 +1006,12 @@ uint16_t uniffi_gotcha_core_checksum_method_gotchacore_settings(void
|
||||
#define UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_CHECKSUM_METHOD_GOTCHACORE_STARTUP_ERROR
|
||||
uint16_t uniffi_gotcha_core_checksum_method_gotchacore_startup_error(void
|
||||
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_CHECKSUM_METHOD_GOTCHACORE_UPDATE_SERVER
|
||||
#define UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_CHECKSUM_METHOD_GOTCHACORE_UPDATE_SERVER
|
||||
uint16_t uniffi_gotcha_core_checksum_method_gotchacore_update_server(void
|
||||
|
||||
);
|
||||
#endif
|
||||
#ifndef UNIFFI_FFIDEF_UNIFFI_GOTCHA_CORE_CHECKSUM_CONSTRUCTOR_GOTCHACORE_NEW
|
||||
|
||||
@@ -47,12 +47,16 @@ final class AppContext {
|
||||
|
||||
func selectServer(index: UInt32) throws {
|
||||
try core.selectServer(index: index)
|
||||
reloadAfterServerChange()
|
||||
}
|
||||
|
||||
func reloadAfterServerChange() {
|
||||
let replacements: [(Int, UIViewController)] = [
|
||||
(0, HomeViewController(context: self)),
|
||||
(1, RepositoriesViewController(context: self, mode: .issues)),
|
||||
(2, RepositoriesViewController(context: self, mode: .commits)),
|
||||
(1, repositoryRoot(mode: .issues)),
|
||||
(2, repositoryRoot(mode: .commits)),
|
||||
(3, PullsViewController(context: self)),
|
||||
(4, RepositoriesViewController(context: self, mode: .milestones)),
|
||||
(4, repositoryRoot(mode: .milestones)),
|
||||
]
|
||||
for (index, root) in replacements {
|
||||
navigationControllers[index].setViewControllers([root], animated: false)
|
||||
|
||||
@@ -4,6 +4,7 @@ import UIKit
|
||||
final class ServersViewController: UITableViewController {
|
||||
private let context: AppContext
|
||||
private var servers: [ServerRow] = []
|
||||
private var mutationTask: Task<Void, Never>?
|
||||
|
||||
init(context: AppContext) {
|
||||
self.context = context
|
||||
@@ -16,16 +17,16 @@ final class ServersViewController: UITableViewController {
|
||||
@available(*, unavailable)
|
||||
required init?(coder: NSCoder) { fatalError("init(coder:) is not supported") }
|
||||
|
||||
deinit {
|
||||
mutationTask?.cancel()
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
servers = context.core.servers()
|
||||
tableView.reloadData()
|
||||
tableView.backgroundView = servers.isEmpty
|
||||
? EmptyBackgroundView(title: "No servers", detail: "Add a code hosting server to get started.")
|
||||
: nil
|
||||
reloadServers()
|
||||
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
||||
systemItem: .add,
|
||||
primaryAction: UIAction { [weak self] _ in self?.showAddServer() }
|
||||
primaryAction: UIAction { [weak self] _ in self?.showServerEditor() }
|
||||
)
|
||||
}
|
||||
|
||||
@@ -54,18 +55,101 @@ final class ServersViewController: UITableViewController {
|
||||
}
|
||||
}
|
||||
|
||||
private func showAddServer() {
|
||||
let controller = AddServerViewController(context: context) { [weak self] in
|
||||
guard let self else { return }
|
||||
self.servers = self.context.core.servers()
|
||||
self.tableView.reloadData()
|
||||
override func tableView(
|
||||
_ tableView: UITableView,
|
||||
trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath
|
||||
) -> UISwipeActionsConfiguration? {
|
||||
let server = servers[indexPath.row]
|
||||
let deleteAction = UIContextualAction(style: .destructive, title: "Delete") {
|
||||
[weak self] _, _, completion in
|
||||
self?.confirmDelete(server, index: indexPath.row, completion: completion)
|
||||
?? completion(false)
|
||||
}
|
||||
present(UINavigationController(rootViewController: controller), animated: true)
|
||||
deleteAction.image = context.symbol("trash")
|
||||
|
||||
let editAction = UIContextualAction(style: .normal, title: "Edit") {
|
||||
[weak self] _, _, completion in
|
||||
self?.showServerEditor(index: indexPath.row, completion: completion)
|
||||
?? completion(false)
|
||||
}
|
||||
editAction.image = context.symbol("pencil")
|
||||
|
||||
let configuration = UISwipeActionsConfiguration(actions: [deleteAction, editAction])
|
||||
configuration.performsFirstActionWithFullSwipe = true
|
||||
return configuration
|
||||
}
|
||||
|
||||
private func reloadServers() {
|
||||
servers = context.core.servers()
|
||||
tableView.reloadData()
|
||||
tableView.backgroundView = servers.isEmpty
|
||||
? EmptyBackgroundView(title: "No servers", detail: "Add a code hosting server to get started.")
|
||||
: nil
|
||||
}
|
||||
|
||||
private func showServerEditor(
|
||||
index: Int? = nil,
|
||||
completion swipeCompletion: ((Bool) -> Void)? = nil
|
||||
) {
|
||||
do {
|
||||
let editor = try index.map { try context.core.serverEditor(index: UInt32($0)) }
|
||||
let controller = ServerEditorViewController(
|
||||
context: context,
|
||||
index: index.map(UInt32.init),
|
||||
editor: editor
|
||||
) { [weak self] in
|
||||
self?.reloadServers()
|
||||
}
|
||||
present(UINavigationController(rootViewController: controller), animated: true) {
|
||||
swipeCompletion?(true)
|
||||
}
|
||||
} catch {
|
||||
swipeCompletion?(false)
|
||||
show(error: error)
|
||||
}
|
||||
}
|
||||
|
||||
private func confirmDelete(
|
||||
_ server: ServerRow,
|
||||
index: Int,
|
||||
completion: @escaping (Bool) -> Void
|
||||
) {
|
||||
let alert = UIAlertController(
|
||||
title: "Delete “\(server.name)”?",
|
||||
message: "This removes the server configuration and access token from this device. It doesn’t change anything on the server.",
|
||||
preferredStyle: .alert
|
||||
)
|
||||
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in completion(false) })
|
||||
alert.addAction(UIAlertAction(title: "Delete", style: .destructive) { [weak self] _ in
|
||||
guard let self else {
|
||||
completion(false)
|
||||
return
|
||||
}
|
||||
self.mutationTask?.cancel()
|
||||
self.mutationTask = Task {
|
||||
do {
|
||||
try await self.context.core.deleteServer(index: UInt32(index))
|
||||
guard !Task.isCancelled else {
|
||||
completion(false)
|
||||
return
|
||||
}
|
||||
completion(true)
|
||||
self.reloadServers()
|
||||
self.context.reloadAfterServerChange()
|
||||
} catch {
|
||||
completion(false)
|
||||
if !Task.isCancelled { self.show(error: error) }
|
||||
}
|
||||
}
|
||||
})
|
||||
present(alert, animated: true)
|
||||
}
|
||||
}
|
||||
@MainActor
|
||||
final class AddServerViewController: UITableViewController, UITextFieldDelegate {
|
||||
final class ServerEditorViewController: UITableViewController, UITextFieldDelegate {
|
||||
private let context: AppContext
|
||||
private let index: UInt32?
|
||||
private let editor: ServerEditor?
|
||||
private let completion: () -> Void
|
||||
private let nameField = UITextField()
|
||||
private let urlField = UITextField()
|
||||
@@ -74,11 +158,19 @@ final class AddServerViewController: UITableViewController, UITextFieldDelegate
|
||||
private var provider = ServerProvider.gitea
|
||||
private var saveButton: UIBarButtonItem!
|
||||
|
||||
init(context: AppContext, completion: @escaping () -> Void) {
|
||||
init(
|
||||
context: AppContext,
|
||||
index: UInt32?,
|
||||
editor: ServerEditor?,
|
||||
completion: @escaping () -> Void
|
||||
) {
|
||||
self.context = context
|
||||
self.index = index
|
||||
self.editor = editor
|
||||
self.completion = completion
|
||||
provider = editor?.provider ?? .gitea
|
||||
super.init(style: .insetGrouped)
|
||||
title = "Add Server"
|
||||
title = index == nil ? "Add Server" : "Edit Server"
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
@@ -91,7 +183,7 @@ final class AddServerViewController: UITableViewController, UITextFieldDelegate
|
||||
primaryAction: UIAction { [weak self] _ in self?.dismiss(animated: true) }
|
||||
)
|
||||
saveButton = UIBarButtonItem(
|
||||
title: "Add",
|
||||
title: index == nil ? "Add" : "Save",
|
||||
style: .done,
|
||||
target: self,
|
||||
action: #selector(save)
|
||||
@@ -106,6 +198,11 @@ final class AddServerViewController: UITableViewController, UITextFieldDelegate
|
||||
tokenField.autocapitalizationType = .none
|
||||
tokenField.returnKeyType = .done
|
||||
configureProviderButton()
|
||||
nameField.text = editor?.name
|
||||
urlField.text = editor?.url
|
||||
if editor != nil {
|
||||
tokenField.placeholder = "Leave unchanged"
|
||||
}
|
||||
}
|
||||
|
||||
override func numberOfSections(in tableView: UITableView) -> Int { 4 }
|
||||
@@ -150,13 +247,24 @@ final class AddServerViewController: UITableViewController, UITextFieldDelegate
|
||||
navigationItem.rightBarButtonItem = UIBarButtonItem(customView: spinner)
|
||||
Task {
|
||||
do {
|
||||
let index = try await context.core.addServer(
|
||||
name: nameField.text ?? "",
|
||||
url: urlField.text ?? "",
|
||||
token: tokenField.text ?? "",
|
||||
provider: provider
|
||||
)
|
||||
try context.didAddServer(index: index)
|
||||
if let index {
|
||||
try await context.core.updateServer(
|
||||
index: index,
|
||||
name: nameField.text ?? "",
|
||||
url: urlField.text ?? "",
|
||||
token: tokenField.text ?? "",
|
||||
provider: provider
|
||||
)
|
||||
context.reloadAfterServerChange()
|
||||
} else {
|
||||
let index = try await context.core.addServer(
|
||||
name: nameField.text ?? "",
|
||||
url: urlField.text ?? "",
|
||||
token: tokenField.text ?? "",
|
||||
provider: provider
|
||||
)
|
||||
try context.didAddServer(index: index)
|
||||
}
|
||||
completion()
|
||||
dismiss(animated: true)
|
||||
} catch {
|
||||
@@ -186,14 +294,14 @@ final class AddServerViewController: UITableViewController, UITextFieldDelegate
|
||||
providerButton.showsMenuAsPrimaryAction = true
|
||||
providerButton.changesSelectionAsPrimaryAction = true
|
||||
providerButton.accessibilityLabel = "API provider"
|
||||
providerButton.accessibilityValue = "Gitea"
|
||||
providerButton.accessibilityValue = provider == .gitea ? "Gitea" : "Forgejo"
|
||||
providerButton.menu = UIMenu(options: .singleSelection, children: [
|
||||
UIAction(title: "Gitea", state: .on) { [weak self] _ in
|
||||
UIAction(title: "Gitea", state: provider == .gitea ? .on : .off) { [weak self] _ in
|
||||
self?.provider = .gitea
|
||||
self?.urlField.placeholder = "https://gitea.example.com"
|
||||
self?.providerButton.accessibilityValue = "Gitea"
|
||||
},
|
||||
UIAction(title: "Forgejo") { [weak self] _ in
|
||||
UIAction(title: "Forgejo", state: provider == .forgejo ? .on : .off) { [weak self] _ in
|
||||
self?.provider = .forgejo
|
||||
self?.urlField.placeholder = "https://forgejo.example.com"
|
||||
self?.providerButton.accessibilityValue = "Forgejo"
|
||||
|
||||
Reference in New Issue
Block a user