mirror of
https://github.com/yggdrasil-network/yggdrasil-ios.git
synced 2025-04-28 06:05:09 +03:00
Update iOS app
This commit is contained in:
parent
56919b83a8
commit
9bd084c8b7
20 changed files with 328 additions and 719 deletions
|
@ -49,7 +49,7 @@ class PeersViewController: UITableViewController {
|
|||
|
||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
switch section {
|
||||
case 0: return app.yggdrasilSwitchPeers.count
|
||||
case 0: return app.yggdrasilPeers.count
|
||||
case 1:
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
if let peers = config.get("Peers") as? [String] {
|
||||
|
@ -58,9 +58,6 @@ class PeersViewController: UITableViewController {
|
|||
}
|
||||
return 0
|
||||
case 2:
|
||||
if UIDevice.current.hasCellularCapabilites {
|
||||
return 3
|
||||
}
|
||||
return 2
|
||||
default: return 0
|
||||
}
|
||||
|
@ -70,20 +67,18 @@ class PeersViewController: UITableViewController {
|
|||
switch indexPath.section {
|
||||
case 0:
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "discoveredPeerPrototype", for: indexPath)
|
||||
let peers = app.yggdrasilSwitchPeers.sorted { (a, b) -> Bool in
|
||||
let peers = app.yggdrasilPeers.sorted { (a, b) -> Bool in
|
||||
return (a["Port"] as! Int) < (b["Port"] as! Int)
|
||||
}
|
||||
|
||||
if indexPath.row < peers.count {
|
||||
let value = peers[indexPath.row]
|
||||
let proto = value["Protocol"] as? String ?? "tcp"
|
||||
let sent = value["BytesSent"] as? Double ?? 0
|
||||
let recvd = value["BytesRecvd"] as? Double ?? 0
|
||||
let rx = self.format(bytes: sent)
|
||||
let tx = self.format(bytes: recvd)
|
||||
let remote = value["Remote"] as? String ?? "unknown"
|
||||
let prio = value["Priority"] as? Int ?? 0
|
||||
|
||||
cell.textLabel?.text = "\(value["Endpoint"] ?? "unknown")"
|
||||
cell.detailTextLabel?.text = "\(proto.uppercased()) peer on port \(value["Port"] ?? "unknown"), sent \(tx), received \(rx)"
|
||||
cell.textLabel?.text = "\(value["IP"] ?? "(unknown)")"
|
||||
cell.detailTextLabel?.text = "\(proto.uppercased()): \(remote)"
|
||||
}
|
||||
return cell
|
||||
case 1:
|
||||
|
@ -101,33 +96,24 @@ class PeersViewController: UITableViewController {
|
|||
case 0:
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "togglePrototype", for: indexPath) as! ToggleTableViewCell
|
||||
cell.isUserInteractionEnabled = true
|
||||
cell.label?.text = "Search for multicast peers"
|
||||
cell.label?.text = "Discoverable over multicast"
|
||||
cell.label?.isEnabled = true
|
||||
cell.toggle?.addTarget(self, action: #selector(toggledMulticast), for: .valueChanged)
|
||||
cell.toggle?.addTarget(self, action: #selector(toggledMulticastBeacons), for: .valueChanged)
|
||||
cell.toggle?.isEnabled = true
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
let interfaces = config.get("MulticastInterfaces") as? [String] ?? []
|
||||
cell.toggle?.isOn = interfaces.contains("en*")
|
||||
cell.toggle?.isOn = config.multicastBeacons
|
||||
}
|
||||
return cell
|
||||
case 1:
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "togglePrototype", for: indexPath) as! ToggleTableViewCell
|
||||
cell.isUserInteractionEnabled = false
|
||||
cell.label?.text = "Search for nearby iOS peers"
|
||||
cell.label?.isEnabled = false
|
||||
cell.toggle?.addTarget(self, action: #selector(toggledAWDL), for: .valueChanged)
|
||||
cell.toggle?.setOn(false, animated: false)
|
||||
cell.toggle?.isEnabled = false
|
||||
/*if let config = self.app.yggdrasilConfig {
|
||||
let interfaces = config.get("MulticastInterfaces") as? [String] ?? []
|
||||
cell.toggle?.isOn = interfaces.contains("awdl0")
|
||||
}*/
|
||||
return cell
|
||||
case 2:
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "menuPrototype", for: indexPath)
|
||||
cell.isUserInteractionEnabled = true
|
||||
cell.textLabel?.text = "Device settings"
|
||||
cell.textLabel?.isEnabled = true
|
||||
cell.label?.text = "Search for multicast peers"
|
||||
cell.label?.isEnabled = true
|
||||
cell.toggle?.addTarget(self, action: #selector(toggledMulticastListen), for: .valueChanged)
|
||||
cell.toggle?.isEnabled = true
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
cell.toggle?.isOn = config.multicastListen
|
||||
}
|
||||
return cell
|
||||
default:
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "menuPrototype", for: indexPath)
|
||||
|
@ -163,28 +149,16 @@ class PeersViewController: UITableViewController {
|
|||
return "\(numberString) \(suffix)"
|
||||
}
|
||||
|
||||
@objc func toggledMulticast(_ sender: UISwitch) {
|
||||
@objc func toggledMulticastBeacons(_ sender: UISwitch) {
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
var interfaces = config.get("MulticastInterfaces") as! [String]
|
||||
if sender.isOn {
|
||||
interfaces.append("en*")
|
||||
} else {
|
||||
interfaces.removeAll(where: { $0 == "en*" })
|
||||
}
|
||||
config.set("MulticastInterfaces", to: interfaces as [String])
|
||||
config.multicastBeacons = sender.isOn
|
||||
try? config.save(to: &app.vpnManager)
|
||||
}
|
||||
}
|
||||
|
||||
@objc func toggledAWDL(_ sender: UISwitch) {
|
||||
@objc func toggledMulticastListen(_ sender: UISwitch) {
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
var interfaces = config.get("MulticastInterfaces") as! [String]
|
||||
if sender.isOn {
|
||||
interfaces.append("awdl0")
|
||||
} else {
|
||||
interfaces.removeAll(where: { $0 == "awdl0" })
|
||||
}
|
||||
config.set("MulticastInterfaces", to: interfaces as [String])
|
||||
config.multicastListen = sender.isOn
|
||||
try? config.save(to: &app.vpnManager)
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +188,7 @@ class PeersViewController: UITableViewController {
|
|||
override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
|
||||
switch section {
|
||||
case 1:
|
||||
return "Yggdrasil will automatically attempt to connect to configured peers when started."
|
||||
return "Yggdrasil will automatically attempt to connect to configured peers when started. If you configure more than one peer, your device may carry traffic on behalf of other network nodes. Avoid this by configuring only a single peer."
|
||||
case 2:
|
||||
var str = "Multicast peers will be discovered on the same Wi-Fi network or via USB."
|
||||
if UIDevice.current.hasCellularCapabilites {
|
||||
|
|
|
@ -13,28 +13,18 @@ class SettingsViewController: UITableViewController, UIDocumentBrowserViewContro
|
|||
|
||||
@IBOutlet weak var deviceNameField: UITextField!
|
||||
|
||||
@IBOutlet weak var encryptionPublicKeyLabel: UILabel!
|
||||
@IBOutlet weak var signingPublicKeyLabel: UILabel!
|
||||
|
||||
@IBOutlet weak var autoStartWiFiCell: UITableViewCell!
|
||||
@IBOutlet weak var autoStartMobileCell: UITableViewCell!
|
||||
|
||||
@IBOutlet weak var sessionFirewallPeeredCell: UITableViewCell!
|
||||
@IBOutlet weak var sessionFirewallOtherCell: UITableViewCell!
|
||||
@IBOutlet weak var sessionFirewallOutboundCell: UITableViewCell!
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
deviceNameField.text = config.get("name", inSection: "NodeInfo") as? String ?? ""
|
||||
encryptionPublicKeyLabel.text = config.get("EncryptionPublicKey") as? String ?? "Unknown"
|
||||
signingPublicKeyLabel.text = config.get("SigningPublicKey") as? String ?? "Unknown"
|
||||
|
||||
sessionFirewallPeeredCell.accessoryType = config.get("AllowFromDirect", inSection: "SessionFirewall") as? Bool ?? true ? .checkmark : .none
|
||||
sessionFirewallOtherCell.accessoryType = config.get("AllowFromRemote", inSection: "SessionFirewall") as? Bool ?? true ? .checkmark : .none
|
||||
sessionFirewallOutboundCell.accessoryType = config.get("AlwaysAllowOutbound", inSection: "SessionFirewall") as? Bool ?? true ? .checkmark : .none
|
||||
|
||||
signingPublicKeyLabel.text = config.get("PublicKey") as? String ?? config.get("SigningPublicKey") as? String ?? "Unknown"
|
||||
|
||||
autoStartWiFiCell.accessoryType = config.get("WiFi", inSection: "AutoStart") as? Bool ?? false ? .checkmark : .none
|
||||
autoStartMobileCell.accessoryType = config.get("Mobile", inSection: "AutoStart") as? Bool ?? false ? .checkmark : .none
|
||||
}
|
||||
|
@ -61,20 +51,7 @@ class SettingsViewController: UITableViewController, UIDocumentBrowserViewContro
|
|||
try? config.save(to: &app.vpnManager)
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
let settings = [
|
||||
"AllowFromDirect",
|
||||
"AllowFromRemote",
|
||||
"AlwaysAllowOutbound"
|
||||
]
|
||||
if let cell = tableView.cellForRow(at: indexPath) {
|
||||
cell.accessoryType = cell.accessoryType == .checkmark ? .none : .checkmark
|
||||
if let config = self.app.yggdrasilConfig {
|
||||
config.set(settings[indexPath.last!], inSection: "SessionFirewall", to: cell.accessoryType == .checkmark)
|
||||
try? config.save(to: &app.vpnManager)
|
||||
}
|
||||
}
|
||||
case 4:
|
||||
case 3:
|
||||
switch indexPath.last {
|
||||
case 0: // import
|
||||
if #available(iOS 11.0, *) {
|
||||
|
@ -113,7 +90,7 @@ class SettingsViewController: UITableViewController, UIDocumentBrowserViewContro
|
|||
default:
|
||||
break
|
||||
}
|
||||
case 5:
|
||||
case 4:
|
||||
let alert = UIAlertController(title: "Warning", message: "This operation will reset your configuration and generate new keys. This is not reversible unless your configuration has been exported. Changes will not take effect until the next time Yggdrasil is restarted.", preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "Reset", style: .destructive, handler: { action in
|
||||
self.app.yggdrasilConfig = ConfigurationProxy()
|
||||
|
@ -133,7 +110,6 @@ class SettingsViewController: UITableViewController, UIDocumentBrowserViewContro
|
|||
self.dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
@available(iOS 11.0, *)
|
||||
func documentBrowser(_ controller: UIDocumentBrowserViewController, didPickDocumentsAt documentURLs: [URL]) {
|
||||
do {
|
||||
if let url = documentURLs.first {
|
||||
|
|
|
@ -14,5 +14,14 @@ class SplitViewController: UISplitViewController, UISplitViewControllerDelegate
|
|||
self.delegate = self
|
||||
self.preferredDisplayMode = .allVisible
|
||||
}
|
||||
|
||||
|
||||
func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@available(iOS 14.0,*)
|
||||
func splitViewController(_ svc: UISplitViewController, topColumnForCollapsingToProposedTopColumn proposedTopColumn: UISplitViewController.Column) -> UISplitViewController.Column {
|
||||
return .primary
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,10 +20,12 @@ class TableViewController: UITableViewController {
|
|||
@IBOutlet var statsSelfCoords: UILabel!
|
||||
@IBOutlet var statsSelfPeers: UILabel!
|
||||
|
||||
@IBOutlet var statsVersion: UILabel!
|
||||
|
||||
override func viewDidLoad() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilSelfUpdated), name: NSNotification.Name.YggdrasilSelfUpdated, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilPeersUpdated), name: NSNotification.Name.YggdrasilPeersUpdated, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilSwitchPeersUpdated), name: NSNotification.Name.YggdrasilSwitchPeersUpdated, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilDHTUpdated), name: NSNotification.Name.YggdrasilDHTUpdated, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilSettingsUpdated), name: NSNotification.Name.YggdrasilSettingsUpdated, object: nil)
|
||||
}
|
||||
|
||||
|
@ -39,6 +41,8 @@ class TableViewController: UITableViewController {
|
|||
if let row = self.tableView.indexPathForSelectedRow {
|
||||
self.tableView.deselectRow(at: row, animated: true)
|
||||
}
|
||||
|
||||
self.statsVersion.text = Yggdrasil.MobileGetVersion()
|
||||
}
|
||||
|
||||
override func viewWillDisappear(_ animated: Bool) {
|
||||
|
@ -65,18 +69,18 @@ class TableViewController: UITableViewController {
|
|||
|
||||
if let footer = toggleTableView.footerView(forSection: 0) {
|
||||
if let label = footer.textLabel {
|
||||
label.text = app.vpnManager.isOnDemandEnabled ? "Yggdrasil will automatically stop and start based on settings." : "You must restart Yggdrasil to make configuration changes effective."
|
||||
label.text = app.vpnManager.isOnDemandEnabled ? "Yggdrasil is configured to automatically start and stop based on available connectivity." : "Yggdrasil is configured to start and stop manually."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateConnectedStatus() {
|
||||
if self.app.vpnManager.connection.status == .connected {
|
||||
if app.yggdrasilSwitchPeers.count > 0 {
|
||||
connectedStatusLabel.text = "Connected"
|
||||
if app.yggdrasilDHT.count > 0 {
|
||||
connectedStatusLabel.text = "Enabled"
|
||||
connectedStatusLabel.textColor = UIColor(red: 0.37, green: 0.79, blue: 0.35, alpha: 1.0)
|
||||
} else {
|
||||
connectedStatusLabel.text = "No active connections"
|
||||
connectedStatusLabel.text = "No connectivity"
|
||||
connectedStatusLabel.textColor = UIColor.red
|
||||
}
|
||||
} else {
|
||||
|
@ -104,12 +108,12 @@ class TableViewController: UITableViewController {
|
|||
self.updateConnectedStatus()
|
||||
}
|
||||
|
||||
@objc func onYggdrasilSwitchPeersUpdated(notification: NSNotification) {
|
||||
@objc func onYggdrasilDHTUpdated(notification: NSNotification) {
|
||||
self.updateConnectedStatus()
|
||||
}
|
||||
|
||||
@objc func onYggdrasilPeersUpdated(notification: NSNotification) {
|
||||
let peercount = app.yggdrasilSwitchPeers.count
|
||||
let peercount = app.yggdrasilPeers.count
|
||||
if peercount <= 0 {
|
||||
statsSelfPeers.text = "No peers"
|
||||
} else if peercount == 1 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue