aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoopesh Chander <roop@roopc.net>2018-11-10 18:50:09 +0530
committerRoopesh Chander <roop@roopc.net>2018-11-11 01:18:36 +0530
commitc5e8b05e8b1a56785b5acb54eb4797029f0fda9e (patch)
tree4e21da8b89bc2470c1b6ae82172718f43775f0e3
parentModel: Add activationType to tunnel configuration (diff)
downloadwireguard-apple-c5e8b05e8b1a56785b5acb54eb4797029f0fda9e.tar.xz
wireguard-apple-c5e8b05e8b1a56785b5acb54eb4797029f0fda9e.zip
Tunnel edit, Tunnel view model: UI for providing On-Demand activation options
Signed-off-by: Roopesh Chander <roop@roopc.net>
-rw-r--r--WireGuard/WireGuard/UI/TunnelViewModel.swift16
-rw-r--r--WireGuard/WireGuard/UI/iOS/TunnelEditTableViewController.swift115
2 files changed, 125 insertions, 6 deletions
diff --git a/WireGuard/WireGuard/UI/TunnelViewModel.swift b/WireGuard/WireGuard/UI/TunnelViewModel.swift
index 94e3e6d..bfcfb15 100644
--- a/WireGuard/WireGuard/UI/TunnelViewModel.swift
+++ b/WireGuard/WireGuard/UI/TunnelViewModel.swift
@@ -372,6 +372,7 @@ class TunnelViewModel {
var interfaceData: InterfaceData
var peersData: [PeerData]
+ var activationType: ActivationType
init(tunnelConfiguration: TunnelConfiguration?) {
let interfaceData: InterfaceData = InterfaceData()
@@ -391,6 +392,20 @@ class TunnelViewModel {
}
self.interfaceData = interfaceData
self.peersData = peersData
+ self.activationType = tunnelConfiguration?.activationType ?? .activateManually
+ }
+
+ func activateOnDemandOptionText(for activationType: ActivationType) -> String {
+ switch (activationType) {
+ case .activateManually:
+ return ""
+ case .useOnDemandOverWifiAndCellular:
+ return "Over wifi and cellular"
+ case .useOnDemandOverWifiOnly:
+ return "Over wifi only"
+ case .useOnDemandOverCellularOnly:
+ return "Over cellular only"
+ }
}
func appendEmptyPeer() {
@@ -442,6 +457,7 @@ class TunnelViewModel {
}
let tunnelConfiguration = TunnelConfiguration(interface: interfaceConfiguration, peers: peerConfigurations)
+ tunnelConfiguration.activationType = self.activationType
return .saved(tunnelConfiguration)
}
}
diff --git a/WireGuard/WireGuard/UI/iOS/TunnelEditTableViewController.swift b/WireGuard/WireGuard/UI/iOS/TunnelEditTableViewController.swift
index 778cbe7..ed3dc83 100644
--- a/WireGuard/WireGuard/UI/iOS/TunnelEditTableViewController.swift
+++ b/WireGuard/WireGuard/UI/iOS/TunnelEditTableViewController.swift
@@ -26,6 +26,12 @@ class TunnelEditTableViewController: UITableViewController {
.deletePeer
]
+ let activateOnDemandOptions: [ActivationType] = [
+ .useOnDemandOverWifiAndCellular,
+ .useOnDemandOverWifiOnly,
+ .useOnDemandOverCellularOnly
+ ]
+
let tunnelsManager: TunnelsManager
let tunnel: TunnelContainer?
let tunnelViewModel: TunnelViewModel
@@ -58,12 +64,12 @@ class TunnelEditTableViewController: UITableViewController {
self.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelTapped))
self.tableView.rowHeight = 44
- self.tableView.allowsSelection = false
self.tableView.register(TunnelEditTableViewKeyValueCell.self, forCellReuseIdentifier: TunnelEditTableViewKeyValueCell.id)
self.tableView.register(TunnelEditTableViewReadOnlyKeyValueCell.self, forCellReuseIdentifier: TunnelEditTableViewReadOnlyKeyValueCell.id)
self.tableView.register(TunnelEditTableViewButtonCell.self, forCellReuseIdentifier: TunnelEditTableViewButtonCell.id)
self.tableView.register(TunnelEditTableViewSwitchCell.self, forCellReuseIdentifier: TunnelEditTableViewSwitchCell.id)
+ self.tableView.register(TunnelEditTableViewSelectionListCell.self, forCellReuseIdentifier: TunnelEditTableViewSelectionListCell.id)
}
@objc func saveTapped() {
@@ -122,7 +128,7 @@ extension TunnelEditTableViewController {
let numberOfInterfaceSections = interfaceFieldsBySection.count
let numberOfPeerSections = tunnelViewModel.peersData.count
- return numberOfInterfaceSections + numberOfPeerSections + 1
+ return numberOfInterfaceSections + numberOfPeerSections + 1 /* Add Peer */ + 1 /* On-Demand */
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
@@ -138,9 +144,16 @@ extension TunnelEditTableViewController {
let peerData = tunnelViewModel.peersData[peerIndex]
let peerFieldsToShow = peerData.shouldAllowExcludePrivateIPsControl ? peerFields : peerFields.filter { $0 != .excludePrivateIPs }
return peerFieldsToShow.count
- } else {
+ } else if (section < (numberOfInterfaceSections + numberOfPeerSections + 1)) {
// Add peer
return 1
+ } else {
+ // On-Demand Rules
+ if (tunnelViewModel.activationType == .activateManually) {
+ return 1
+ } else {
+ return 4
+ }
}
}
@@ -154,9 +167,12 @@ extension TunnelEditTableViewController {
} else if ((numberOfPeerSections > 0) && (section < (numberOfInterfaceSections + numberOfPeerSections))) {
// Peer
return "Peer"
- } else {
+ } else if (section == (numberOfInterfaceSections + numberOfPeerSections)) {
// Add peer
return nil
+ } else {
+ assert(section == (numberOfInterfaceSections + numberOfPeerSections + 1))
+ return "On-Demand Activation"
}
}
@@ -344,8 +360,7 @@ extension TunnelEditTableViewController {
}
return cell
}
- } else {
- assert(section == (numberOfInterfaceSections + numberOfPeerSections))
+ } else if (section == (numberOfInterfaceSections + numberOfPeerSections)) {
// Add peer
let cell = tableView.dequeueReusableCell(withIdentifier: TunnelEditTableViewButtonCell.id, for: indexPath) as! TunnelEditTableViewButtonCell
cell.buttonText = "Add peer"
@@ -365,6 +380,32 @@ extension TunnelEditTableViewController {
}, completion: nil)
}
return cell
+ } else {
+ assert(section == (numberOfInterfaceSections + numberOfPeerSections + 1))
+ if (row == 0) {
+ let cell = tableView.dequeueReusableCell(withIdentifier: TunnelEditTableViewSwitchCell.id, for: indexPath) as! TunnelEditTableViewSwitchCell
+ cell.message = "Activate on demand"
+ cell.isOn = (tunnelViewModel.activationType != .activateManually)
+ cell.onSwitchToggled = { [weak self] (isOn) in
+ guard let s = self else { return }
+ let indexPaths: [IndexPath] = (1 ..< 4).map { IndexPath(row: $0, section: section) }
+ if (isOn) {
+ s.tunnelViewModel.activationType = .useOnDemandOverWifiAndCellular
+ s.tableView.insertRows(at: indexPaths, with: .automatic)
+ } else {
+ s.tunnelViewModel.activationType = .activateManually
+ s.tableView.deleteRows(at: indexPaths, with: .automatic)
+ }
+ }
+ return cell
+ } else {
+ assert(row < 4)
+ let cell = tableView.dequeueReusableCell(withIdentifier: TunnelEditTableViewSelectionListCell.id, for: indexPath) as! TunnelEditTableViewSelectionListCell
+ let option = activateOnDemandOptions[row - 1]
+ cell.message = tunnelViewModel.activateOnDemandOptionText(for: option)
+ cell.isChecked = (tunnelViewModel.activationType == option)
+ return cell
+ }
}
}
@@ -406,6 +447,41 @@ extension TunnelEditTableViewController {
}
}
+// MARK: UITableViewDelegate
+
+extension TunnelEditTableViewController {
+ override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
+ let numberOfInterfaceSections = interfaceFieldsBySection.count
+ let numberOfPeerSections = tunnelViewModel.peersData.count
+
+ let section = indexPath.section
+ let row = indexPath.row
+
+ if (section == (numberOfInterfaceSections + numberOfPeerSections + 1)) {
+ return (row > 0) ? indexPath : nil
+ } else {
+ return nil
+ }
+ }
+
+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ let numberOfInterfaceSections = interfaceFieldsBySection.count
+ let numberOfPeerSections = tunnelViewModel.peersData.count
+
+ let section = indexPath.section
+ let row = indexPath.row
+
+ assert(section == (numberOfInterfaceSections + numberOfPeerSections + 1))
+ assert(row > 0)
+
+ let option = activateOnDemandOptions[row - 1]
+ tunnelViewModel.activationType = option
+
+ let indexPaths: [IndexPath] = (1 ..< 4).map { IndexPath(row: $0, section: section) }
+ tableView.reloadRows(at: indexPaths, with: .automatic)
+ }
+}
+
class TunnelEditTableViewKeyValueCell: UITableViewCell {
static let id: String = "TunnelEditTableViewKeyValueCell"
var key: String {
@@ -665,3 +741,30 @@ class TunnelEditTableViewSwitchCell: UITableViewCell {
isOn = false
}
}
+
+class TunnelEditTableViewSelectionListCell: UITableViewCell {
+ static let id: String = "TunnelEditTableViewSelectionListCell"
+ var message: String {
+ get { return textLabel?.text ?? "" }
+ set(value) { textLabel!.text = value }
+ }
+ var isChecked: Bool {
+ didSet {
+ accessoryType = isChecked ? .checkmark : .none
+ }
+ }
+ override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
+ isChecked = false
+ super.init(style: .default, reuseIdentifier: reuseIdentifier)
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ override func prepareForReuse() {
+ super.prepareForReuse()
+ message = ""
+ isChecked = false
+ }
+}