mobile: UI to choose transport isolation mode (#1813)

* mobile: UI to choose transport isolation mode

* typo

Co-authored-by: JRoberts <8711996+jr-simplex@users.noreply.github.com>

* ios: update alerts

Co-authored-by: JRoberts <8711996+jr-simplex@users.noreply.github.com>
This commit is contained in:
Evgeny Poberezkin
2023-01-21 16:05:09 +00:00
committed by GitHub
parent c337a6888d
commit 8bec0004cc
7 changed files with 200 additions and 29 deletions

View File

@@ -9,13 +9,15 @@
import SwiftUI
import SimpleXChat
enum OnionHostsAlert: Identifiable {
case update(hosts: OnionHosts)
private enum NetworkAlert: Identifiable {
case updateOnionHosts(hosts: OnionHosts)
case updateSessionMode(mode: TransportSessionMode)
case error(err: String)
var id: String {
switch self {
case let .update(hosts): return "update \(hosts)"
case let .updateOnionHosts(hosts): return "updateOnionHosts \(hosts)"
case let .updateSessionMode(mode): return "updateSessionMode \(mode)"
case let .error(err): return "error \(err)"
}
}
@@ -27,7 +29,8 @@ struct NetworkAndServers: View {
@State private var currentNetCfg = NetCfg.defaults
@State private var netCfg = NetCfg.defaults
@State private var onionHosts: OnionHosts = .no
@State private var showOnionHostsAlert: OnionHostsAlert?
@State private var sessionMode: TransportSessionMode = .user
@State private var alert: NetworkAlert?
var body: some View {
VStack {
@@ -45,6 +48,12 @@ struct NetworkAndServers: View {
}
.frame(height: 36)
if developerTools {
Picker("Transport isolation", selection: $sessionMode) {
ForEach(TransportSessionMode.values, id: \.self) { Text($0.text) }
}
}
NavigationLink {
AdvancedNetworkSettings()
.navigationTitle("Network settings")
@@ -75,17 +84,37 @@ struct NetworkAndServers: View {
}
.onChange(of: onionHosts) { _ in
if onionHosts != OnionHosts(netCfg: currentNetCfg) {
showOnionHostsAlert = .update(hosts: onionHosts)
alert = .updateOnionHosts(hosts: onionHosts)
}
}
.alert(item: $showOnionHostsAlert) { a in
.onChange(of: sessionMode) { _ in
if sessionMode != netCfg.sessionMode {
alert = .updateSessionMode(mode: sessionMode)
}
}
.alert(item: $alert) { a in
switch a {
case let .update(hosts):
case let .updateOnionHosts(hosts):
return Alert(
title: Text("Update .onion hosts setting?"),
message: Text(onionHostsInfo()) + Text("\n") + Text("Updating this setting will re-connect the client to all servers."),
message: Text(onionHostsInfo(hosts)) + Text("\n") + Text("Updating this setting will re-connect the client to all servers."),
primaryButton: .default(Text("Ok")) {
saveNetCfg(hosts)
let (hostMode, requiredHostMode) = hosts.hostMode
netCfg.hostMode = hostMode
netCfg.requiredHostMode = requiredHostMode
saveNetCfg()
},
secondaryButton: .cancel() {
resetNetCfgView()
}
)
case let .updateSessionMode(mode):
return Alert(
title: Text("Update transport isolation mode?"),
message: Text(sessionModeInfo(mode)) + Text("\n") + Text("Updating this setting will re-connect the client to all servers."),
primaryButton: .default(Text("Ok")) {
netCfg.sessionMode = mode
saveNetCfg()
},
secondaryButton: .cancel() {
resetNetCfgView()
@@ -100,11 +129,8 @@ struct NetworkAndServers: View {
}
}
private func saveNetCfg(_ hosts: OnionHosts) {
private func saveNetCfg() {
do {
let (hostMode, requiredHostMode) = hosts.hostMode
netCfg.hostMode = hostMode
netCfg.requiredHostMode = requiredHostMode
let def = netCfg.hostMode == .onionHost ? NetCfg.proxyDefaults : NetCfg.defaults
netCfg.tcpConnectTimeout = def.tcpConnectTimeout
netCfg.tcpTimeout = def.tcpTimeout
@@ -114,7 +140,7 @@ struct NetworkAndServers: View {
} catch let error {
let err = responseError(error)
resetNetCfgView()
showOnionHostsAlert = .error(err: err)
alert = .error(err: err)
logger.error("\(err)")
}
}
@@ -122,15 +148,23 @@ struct NetworkAndServers: View {
private func resetNetCfgView() {
netCfg = currentNetCfg
onionHosts = OnionHosts(netCfg: netCfg)
sessionMode = netCfg.sessionMode
}
private func onionHostsInfo() -> LocalizedStringKey {
switch onionHosts {
private func onionHostsInfo(_ hosts: OnionHosts) -> LocalizedStringKey {
switch hosts {
case .no: return "Onion hosts will not be used."
case .prefer: return "Onion hosts will be used when available. Requires enabling VPN."
case .require: return "Onion hosts will be required for connection. Requires enabling VPN."
}
}
private func sessionModeInfo(_ mode: TransportSessionMode) -> LocalizedStringKey {
switch mode {
case .user: return "A separate TCP connection will be used **for each chat profile you have in the app**."
case .entity: return "A separate TCP connection will be used **for each contact and group member**.\n**Please note**: if you have many connections, your battery and traffic consumption can be substantially higher and some connections may fail."
}
}
}
struct NetworkServersView_Previews: PreviewProvider {