ios: update servers API/UI (#2149)

* ios: update servers API/UI

* fix UI

* fix
This commit is contained in:
Evgeny Poberezkin
2023-04-06 22:48:32 +01:00
committed by GitHub
parent d250e503b0
commit 5ae0afe1fe
8 changed files with 150 additions and 103 deletions
+11 -25
View File
@@ -391,36 +391,22 @@ func apiDeleteToken(token: DeviceToken) async throws {
try await sendCommandOkResp(.apiDeleteToken(token: token))
}
func getUserProtocolServers(_ p: ServerProtocol) throws -> ([ServerCfg], [String]) {
if case .smp = p {
return try getUserSMPServers()
}
throw RuntimeError("not supported")
}
private func getUserSMPServers() throws -> ([ServerCfg], [String]) {
let userId = try currentUserId("getUserSMPServers")
let r = chatSendCmdSync(.apiGetUserSMPServers(userId: userId))
if case let .userSMPServers(_, smpServers, presetServers) = r { return (smpServers, presetServers) }
func getUserProtoServers(_ serverProtocol: ServerProtocol) throws -> UserProtoServers {
let userId = try currentUserId("getUserProtoServers")
let r = chatSendCmdSync(.apiGetUserProtoServers(userId: userId, serverProtocol: serverProtocol))
if case let .userProtoServers(_, servers) = r { return servers }
throw r
}
func setUserProtocolServers(_ p: ServerProtocol, servers: [ServerCfg]) async throws {
if case .smp = p {
return try await setUserSMPServers(smpServers: servers)
}
throw RuntimeError("not supported")
func setUserProtoServers(_ serverProtocol: ServerProtocol, servers: [ServerCfg]) async throws {
let userId = try currentUserId("setUserProtoServers")
try await sendCommandOkResp(.apiSetUserProtoServers(userId: userId, serverProtocol: serverProtocol, servers: servers))
}
private func setUserSMPServers(smpServers: [ServerCfg]) async throws {
let userId = try currentUserId("setUserSMPServers")
try await sendCommandOkResp(.apiSetUserSMPServers(userId: userId, smpServers: smpServers))
}
func testSMPServer(smpServer: String) async throws -> Result<(), SMPTestFailure> {
let userId = try currentUserId("testSMPServer")
let r = await chatSendCmd(.apiTestSMPServer(userId: userId, smpServer: smpServer))
if case let .smpTestResult(_, testFailure) = r {
func testProtoServer(server: String) async throws -> Result<(), ProtocolTestFailure> {
let userId = try currentUserId("testProtoServer")
let r = await chatSendCmd(.apiTestProtoServer(userId: userId, server: server))
if case let .serverTestResult(_, _, testFailure) = r {
if let t = testFailure {
return .failure(t)
}
@@ -25,6 +25,7 @@ private enum NetworkAlert: Identifiable {
struct NetworkAndServers: View {
@AppStorage(DEFAULT_DEVELOPER_TOOLS) private var developerTools = false
@AppStorage(GROUP_DEFAULT_XFTP_SEND_ENABLED, store: groupDefaults) private var xftpSendEnabled = false
@State private var cfgLoaded = false
@State private var currentNetCfg = NetCfg.defaults
@State private var netCfg = NetCfg.defaults
@@ -43,6 +44,15 @@ struct NetworkAndServers: View {
Text("SMP servers")
}
if xftpSendEnabled {
NavigationLink {
ProtocolServersView(serverProtocol: .xftp)
.navigationTitle("Your XFTP servers")
} label: {
Text("XFTP servers")
}
}
Picker("Use .onion hosts", selection: $onionHosts) {
ForEach(OnionHosts.values, id: \.self) { Text($0.text) }
}
@@ -62,7 +72,7 @@ struct NetworkAndServers: View {
Text("Advanced network settings")
}
} header: {
Text("Messages")
Text("Messages & files")
} footer: {
Text("Using .onion hosts requires compatible VPN provider.")
}
@@ -16,7 +16,7 @@ struct ProtocolServerView: View {
@State var serverToEdit: ServerCfg
@State private var showTestFailure = false
@State private var testing = false
@State private var testFailure: SMPTestFailure?
@State private var testFailure: ProtocolTestFailure?
var proto: String { serverProtocol.rawValue.uppercased() }
@@ -60,7 +60,8 @@ struct ProtocolServerView: View {
private func customServer() -> some View {
VStack {
let valid = parseServerAddress(serverToEdit.server)?.valid == true
let serverAddress = parseServerAddress(serverToEdit.server)
let valid = serverAddress?.valid == true && serverAddress?.serverProtocol == serverProtocol
List {
Section {
TextEditor(text: $serverToEdit.server)
@@ -147,18 +148,17 @@ struct BackButton: ViewModifier {
}
}
func testServerConnection(server: Binding<ServerCfg>) async -> SMPTestFailure? {
func testServerConnection(server: Binding<ServerCfg>) async -> ProtocolTestFailure? {
do {
let r = try await testSMPServer(smpServer: server.wrappedValue.server)
switch r {
case .success:
await MainActor.run { server.wrappedValue.tested = true }
return nil
case let .failure(f):
await MainActor.run { server.wrappedValue.tested = false }
return f
}
let r = try await testProtoServer(server: server.wrappedValue.server)
switch r {
case .success:
await MainActor.run { server.wrappedValue.tested = true }
return nil
case let .failure(f):
await MainActor.run { server.wrappedValue.tested = false }
return f
}
} catch let error {
logger.error("testServerConnection \(responseError(error))")
await MainActor.run {
@@ -21,7 +21,8 @@ struct ProtocolServersView: View {
@State private var servers: [ServerCfg] = []
@State private var selectedServer: String? = nil
@State private var showAddServer = false
@State private var showScanSMPServer = false
@State private var showScanProtoServer = false
@State private var justOpened = true
@State private var testing = false
@State private var alert: ServerAlert? = nil
@State private var showSaveDialog = false
@@ -38,7 +39,7 @@ struct ProtocolServersView: View {
}
enum ServerAlert: Identifiable {
case testsFailed(failures: [String: SMPTestFailure])
case testsFailed(failures: [String: ProtocolTestFailure])
case error(title: LocalizedStringKey, error: LocalizedStringKey = "")
var id: String {
@@ -87,16 +88,17 @@ struct ProtocolServersView: View {
servers.append(ServerCfg.empty)
selectedServer = servers.last?.id
}
Button("Scan server QR code") { showScanSMPServer = true }
Button("Scan server QR code") { showScanProtoServer = true }
Button("Add preset servers", action: addAllPresets)
.disabled(hasAllPresets())
}
.sheet(isPresented: $showScanSMPServer) {
.sheet(isPresented: $showScanProtoServer) {
ScanProtocolServer(servers: $servers)
}
.modifier(BackButton {
if saveDisabled {
dismiss()
justOpened = false
} else {
showSaveDialog = true
}
@@ -105,6 +107,7 @@ struct ProtocolServersView: View {
Button("Save") {
saveServers()
dismiss()
justOpened = false
}
Button("Exit without saving") { dismiss() }
}
@@ -125,8 +128,12 @@ struct ProtocolServersView: View {
}
}
.onAppear {
// this condition is needed to prevent re-setting the servers when exiting single server view
if !justOpened { return }
do {
(currServers, presetServers) = try getUserProtocolServers(serverProtocol)
let r = try getUserProtoServers(serverProtocol)
currServers = r.protoServers
presetServers = r.presetServers
servers = currServers
} catch let error {
alert = .error(
@@ -134,6 +141,7 @@ struct ProtocolServersView: View {
error: "Error: \(responseError(error))"
)
}
justOpened = false
}
}
@@ -158,7 +166,7 @@ struct ProtocolServersView: View {
let srv = server.wrappedValue
return NavigationLink(tag: srv.id, selection: $selectedServer) {
ProtocolServerView(
serverProtocol: .smp,
serverProtocol: serverProtocol,
server: server,
serverToEdit: srv
)
@@ -258,8 +266,8 @@ struct ProtocolServersView: View {
}
}
private func runServersTest() async -> [String: SMPTestFailure] {
var fs: [String: SMPTestFailure] = [:]
private func runServersTest() async -> [String: ProtocolTestFailure] {
var fs: [String: ProtocolTestFailure] = [:]
for i in 0..<servers.count {
if servers[i].enabled {
if let f = await testServerConnection(server: $servers[i]) {
@@ -273,7 +281,7 @@ struct ProtocolServersView: View {
func saveServers() {
Task {
do {
try await setUserProtocolServers(serverProtocol, servers: servers)
try await setUserProtoServers(serverProtocol, servers: servers)
await MainActor.run {
currServers = servers
editMode?.wrappedValue = .inactive