diff --git a/apps/ios/Shared/Views/UserSettings/NetworkAndServers/AllServersView.swift b/apps/ios/Shared/Views/UserSettings/NetworkAndServers/AllServersView.swift index 5662415732..ecaef0bcb3 100644 --- a/apps/ios/Shared/Views/UserSettings/NetworkAndServers/AllServersView.swift +++ b/apps/ios/Shared/Views/UserSettings/NetworkAndServers/AllServersView.swift @@ -38,6 +38,13 @@ struct AllServersView: View { Text("Other servers") .foregroundColor(theme.colors.secondary) } + + Section { + Button("Reset") {} + .disabled(true) + Button("Save") {} + .disabled(true) + } } } .onAppear { @@ -46,10 +53,11 @@ struct AllServersView: View { } @ViewBuilder private func operatorsSection() -> some View { - let servers = [ServerCfg.sampleData.preset, ServerCfg.sampleData.untested] + let smpServers = [ServerCfg.sampleData.preset, ServerCfg.sampleData.preset] + let xftpServers = [ServerCfg.sampleData.xftpPreset, ServerCfg.sampleData.xftpPreset] Section { ForEach($serverOperators) { srvOperator in - serverOperatorView(srvOperator, servers) + serverOperatorView(srvOperator, smpServers, xftpServers) } } header: { Text("Operators") @@ -57,15 +65,19 @@ struct AllServersView: View { } } - @ViewBuilder private func serverOperatorView(_ serverOperator: Binding, _ servers: [ServerCfg]) -> some View { + @ViewBuilder private func serverOperatorView( + _ serverOperator: Binding, + _ smpServers: [ServerCfg], + _ xftpServers: [ServerCfg] + ) -> some View { let srvOperator = serverOperator.wrappedValue NavigationLink() { OperatorView( - serverProtocol: .smp, serverOperator: serverOperator, serverOperatorToEdit: srvOperator, useOperator: srvOperator.enabled, - currServers: servers + currSMPServers: smpServers, + currXFTPServers: xftpServers ) .navigationBarTitle("\(srvOperator.name) servers") .modifier(ThemedBackground(grouped: true)) diff --git a/apps/ios/Shared/Views/UserSettings/NetworkAndServers/OperatorView.swift b/apps/ios/Shared/Views/UserSettings/NetworkAndServers/OperatorView.swift index 73b46480bc..5f2500eef9 100644 --- a/apps/ios/Shared/Views/UserSettings/NetworkAndServers/OperatorView.swift +++ b/apps/ios/Shared/Views/UserSettings/NetworkAndServers/OperatorView.swift @@ -14,19 +14,18 @@ import SimpleXChat struct OperatorView: View { @Environment(\.dismiss) var dismiss: DismissAction @EnvironmentObject var theme: AppTheme - let serverProtocol: ServerProtocol @Binding var serverOperator: ServerOperator @State var serverOperatorToEdit: ServerOperator @State var useOperator: Bool @State private var useOperatorToggleReset: Bool = false @State private var showConditionsSheet: Bool = false - @State var currServers: [ServerCfg] - @State var servers: [ServerCfg] = [] + @State var currSMPServers: [ServerCfg] + @State var smpServers: [ServerCfg] = [] + @State var currXFTPServers: [ServerCfg] + @State var xftpServers: [ServerCfg] = [] @State private var selectedServer: String? = nil @State private var justOpened = true - var proto: String { serverProtocol.rawValue.uppercased() } - var body: some View { VStack { List { @@ -54,12 +53,19 @@ struct OperatorView: View { if serverOperatorToEdit.enabled { usageRolesSection() - serversSection() + serversSection($smpServers, .smp) + serversSection($xftpServers, .xftp) } Section { - Button("Reset") { servers = currServers } - .disabled(Set(servers) == Set(currServers)) + Button("Reset") { + smpServers = currSMPServers + xftpServers = currXFTPServers + } + .disabled( + Set(smpServers) == Set(currSMPServers) && + Set(xftpServers) == Set(currXFTPServers) + ) if serverOperatorToEdit.enabled { Button("Test servers") {} } @@ -76,7 +82,8 @@ struct OperatorView: View { .onAppear { // this condition is needed to prevent re-setting the servers when exiting single server view if justOpened { - servers = currServers + smpServers = currSMPServers + xftpServers = currXFTPServers justOpened = false } } @@ -102,7 +109,7 @@ struct OperatorView: View { } } } - + private func useOperatorToggle() -> some View { Toggle("Use operator", isOn: $useOperator) .onChange(of: useOperator) { useOperatorToggle in @@ -161,13 +168,14 @@ struct OperatorView: View { } } - private func serversSection() -> some View { + @ViewBuilder private func serversSection(_ servers: Binding<[ServerCfg]>, _ serverProtocol: ServerProtocol) -> some View { + let proto = serverProtocol.rawValue.uppercased() Section { - ForEach($servers) { srv in - protocolServerView(srv) + ForEach(servers) { srv in + protocolServerView(srv, serverProtocol) } } header: { - Text("\(serverOperator.name) \(proto) servers") + Text("\(proto) servers") .foregroundColor(theme.colors.secondary) } footer: { Text("The servers for new connections of your current chat profile **\(ChatModel.shared.currentUser?.displayName ?? "")**.") @@ -176,13 +184,16 @@ struct OperatorView: View { } } - private func protocolServerView(_ server: Binding) -> some View { + // TODO Refactor (similar function in ProtocolServersView) / Keep modified for operator servers? (some things are not applicable) + // TODO Check all servers across all operators (uniqueAddress in ProtocolServersView) / Validate via api (per server?) + private func protocolServerView(_ server: Binding, _ serverProtocol: ServerProtocol) -> some View { let srv = server.wrappedValue return NavigationLink(tag: srv.id, selection: $selectedServer) { ProtocolServerView( serverProtocol: serverProtocol, server: server, - serverToEdit: srv + serverToEdit: srv, + backLabel: "\(serverOperator.name) servers" ) .navigationBarTitle("\(serverOperator.name) server") .modifier(ThemedBackground(grouped: true)) @@ -191,42 +202,21 @@ struct OperatorView: View { let address = parseServerAddress(srv.server) HStack { Group { - if let address = address { - if !address.valid || address.serverProtocol != serverProtocol { - invalidServer() - } else if !uniqueAddress(srv, address) { - Image(systemName: "exclamationmark.circle").foregroundColor(.red) - } else if !srv.enabled { - Image(systemName: "slash.circle").foregroundColor(theme.colors.secondary) - } else { - showTestStatus(server: srv) - } + if !srv.enabled { + Image(systemName: "slash.circle").foregroundColor(theme.colors.secondary) } else { - invalidServer() + showTestStatus(server: srv) } } - .frame(width: 16, alignment: .center) - .padding(.trailing, 4) - - let v = Text(address?.hostnames.first ?? srv.server).lineLimit(1) - if srv.enabled { - v - } else { - v.foregroundColor(theme.colors.secondary) - } } - } - } + .frame(width: 16, alignment: .center) + .padding(.trailing, 4) - private func invalidServer() -> some View { - Image(systemName: "exclamationmark.circle").foregroundColor(.red) - } - - // TODO all servers across all operators - private func uniqueAddress(_ s: ServerCfg, _ address: ServerAddress) -> Bool { - servers.allSatisfy { srv in - address.hostnames.allSatisfy { host in - srv.id == s.id || !srv.server.contains(host) + let v = Text(address?.hostnames.first ?? srv.server).lineLimit(1) + if srv.enabled { + v + } else { + v.foregroundColor(theme.colors.secondary) } } } @@ -378,10 +368,10 @@ struct UsageConditionsView: View { #Preview { OperatorView( - serverProtocol: .smp, serverOperator: Binding.constant(ServerOperator.sampleData1), serverOperatorToEdit: ServerOperator.sampleData1, useOperator: ServerOperator.sampleData1.enabled, - currServers: [ServerCfg.sampleData.preset] + currSMPServers: [ServerCfg.sampleData.preset], + currXFTPServers: [ServerCfg.sampleData.xftpPreset] ) } diff --git a/apps/ios/Shared/Views/UserSettings/NetworkAndServers/ProtocolServerView.swift b/apps/ios/Shared/Views/UserSettings/NetworkAndServers/ProtocolServerView.swift index da29dfac29..eb881069a7 100644 --- a/apps/ios/Shared/Views/UserSettings/NetworkAndServers/ProtocolServerView.swift +++ b/apps/ios/Shared/Views/UserSettings/NetworkAndServers/ProtocolServerView.swift @@ -15,6 +15,7 @@ struct ProtocolServerView: View { let serverProtocol: ServerProtocol @Binding var server: ServerCfg @State var serverToEdit: ServerCfg + var backLabel: LocalizedStringKey @State private var showTestFailure = false @State private var testing = false @State private var testFailure: ProtocolTestFailure? @@ -32,7 +33,7 @@ struct ProtocolServerView: View { ProgressView().scaleEffect(2) } } - .modifier(BackButton(label: "Your \(proto) servers", disabled: Binding.constant(false)) { + .modifier(BackButton(label: backLabel, disabled: Binding.constant(false)) { server = serverToEdit dismiss() }) @@ -180,7 +181,8 @@ struct ProtocolServerView_Previews: PreviewProvider { ProtocolServerView( serverProtocol: .smp, server: Binding.constant(ServerCfg.sampleData.custom), - serverToEdit: ServerCfg.sampleData.custom + serverToEdit: ServerCfg.sampleData.custom, + backLabel: "Your SMP servers" ) } } diff --git a/apps/ios/Shared/Views/UserSettings/NetworkAndServers/ProtocolServersView.swift b/apps/ios/Shared/Views/UserSettings/NetworkAndServers/ProtocolServersView.swift index 9ebab9de53..2f31850d0c 100644 --- a/apps/ios/Shared/Views/UserSettings/NetworkAndServers/ProtocolServersView.swift +++ b/apps/ios/Shared/Views/UserSettings/NetworkAndServers/ProtocolServersView.swift @@ -201,14 +201,14 @@ struct ProtocolServersView: View { allServers.allSatisfy { !$0.enabled } } - // TODO remove private func protocolServerView(_ server: Binding) -> some View { let srv = server.wrappedValue return NavigationLink(tag: srv.id, selection: $selectedServer) { ProtocolServerView( serverProtocol: serverProtocol, server: server, - serverToEdit: srv + serverToEdit: srv, + backLabel: "Your \(proto) servers" ) .navigationBarTitle(srv.preset ? "Preset server" : "Your server") .modifier(ThemedBackground(grouped: true)) diff --git a/apps/ios/SimpleXChat/APITypes.swift b/apps/ios/SimpleXChat/APITypes.swift index 16be45f4cb..9c7aafcd1a 100644 --- a/apps/ios/SimpleXChat/APITypes.swift +++ b/apps/ios/SimpleXChat/APITypes.swift @@ -1319,6 +1319,7 @@ public struct ServerCfg: Identifiable, Equatable, Codable, Hashable { public var preset: ServerCfg public var custom: ServerCfg public var untested: ServerCfg + public var xftpPreset: ServerCfg } public static var sampleData = SampleData( @@ -1339,6 +1340,12 @@ public struct ServerCfg: Identifiable, Equatable, Codable, Hashable { preset: false, tested: nil, enabled: true + ), + xftpPreset: ServerCfg( + server: "xftp://abcd@xftp8.simplex.im", + preset: true, + tested: true, + enabled: true ) )