aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoopesh Chander <roop@roopc.net>2018-10-23 22:18:45 +0530
committerRoopesh Chander <roop@roopc.net>2018-10-27 15:13:01 +0530
commitc14d816b879d05b876bc486ff0bfd86f3f39b5a1 (patch)
tree90eb3fb5b9790d3ea72bc1635ba752b527c2714c
parentTunnel view model: Add copy public key (diff)
downloadwireguard-apple-c14d816b879d05b876bc486ff0bfd86f3f39b5a1.tar.xz
wireguard-apple-c14d816b879d05b876bc486ff0bfd86f3f39b5a1.zip
Tunnel detail: Start off with the tunnel detail view
Signed-off-by: Roopesh Chander <roop@roopc.net>
-rw-r--r--WireGuard/WireGuard.xcodeproj/project.pbxproj4
-rw-r--r--WireGuard/WireGuard/UI/iOS/TunnelDetailTableViewController.swift222
-rw-r--r--WireGuard/WireGuard/UI/iOS/TunnelsListTableViewController.swift12
3 files changed, 238 insertions, 0 deletions
diff --git a/WireGuard/WireGuard.xcodeproj/project.pbxproj b/WireGuard/WireGuard.xcodeproj/project.pbxproj
index 99690b2..17f8d5b 100644
--- a/WireGuard/WireGuard.xcodeproj/project.pbxproj
+++ b/WireGuard/WireGuard.xcodeproj/project.pbxproj
@@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
6F628C3D217F09E9003482A3 /* TunnelViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F628C3C217F09E9003482A3 /* TunnelViewModel.swift */; };
6F628C3F217F3413003482A3 /* DNSServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F628C3E217F3413003482A3 /* DNSServer.swift */; };
+ 6F628C41217F47DB003482A3 /* TunnelDetailTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F628C40217F47DB003482A3 /* TunnelDetailTableViewController.swift */; };
6F693A562179E556008551C1 /* Endpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F693A552179E556008551C1 /* Endpoint.swift */; };
6F7774E1217181B1006A79B3 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7774DF217181B1006A79B3 /* MainViewController.swift */; };
6F7774E2217181B1006A79B3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7774E0217181B1006A79B3 /* AppDelegate.swift */; };
@@ -25,6 +26,7 @@
/* Begin PBXFileReference section */
6F628C3C217F09E9003482A3 /* TunnelViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelViewModel.swift; sourceTree = "<group>"; };
6F628C3E217F3413003482A3 /* DNSServer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DNSServer.swift; sourceTree = "<group>"; };
+ 6F628C40217F47DB003482A3 /* TunnelDetailTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TunnelDetailTableViewController.swift; sourceTree = "<group>"; };
6F693A552179E556008551C1 /* Endpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Endpoint.swift; sourceTree = "<group>"; };
6F7774DF217181B1006A79B3 /* MainViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = "<group>"; };
6F7774E0217181B1006A79B3 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@@ -70,6 +72,7 @@
6F7774DF217181B1006A79B3 /* MainViewController.swift */,
6F7774E321718281006A79B3 /* TunnelsListTableViewController.swift */,
6F7774F221774263006A79B3 /* TunnelEditTableViewController.swift */,
+ 6F628C40217F47DB003482A3 /* TunnelDetailTableViewController.swift */,
);
path = iOS;
sourceTree = "<group>";
@@ -216,6 +219,7 @@
6F628C3D217F09E9003482A3 /* TunnelViewModel.swift in Sources */,
6F7774EA217229DB006A79B3 /* IPAddressRange.swift in Sources */,
6F7774E82172020C006A79B3 /* Configuration.swift in Sources */,
+ 6F628C41217F47DB003482A3 /* TunnelDetailTableViewController.swift in Sources */,
6F7774F321774263006A79B3 /* TunnelEditTableViewController.swift in Sources */,
6F7774E1217181B1006A79B3 /* MainViewController.swift in Sources */,
);
diff --git a/WireGuard/WireGuard/UI/iOS/TunnelDetailTableViewController.swift b/WireGuard/WireGuard/UI/iOS/TunnelDetailTableViewController.swift
new file mode 100644
index 0000000..3ed1a86
--- /dev/null
+++ b/WireGuard/WireGuard/UI/iOS/TunnelDetailTableViewController.swift
@@ -0,0 +1,222 @@
+//
+// TunnelDetailTableViewController.swift
+// WireGuard
+//
+// Created by Roopesh Chander on 17/10/18.
+// Copyright © 2018 Roopesh Chander. All rights reserved.
+//
+
+import UIKit
+
+// MARK: TunnelDetailTableViewController
+
+class TunnelDetailTableViewController: UITableViewController {
+
+ let interfaceFieldsBySection: [[TunnelViewModel.InterfaceField]] = [
+ [.name],
+ [.publicKey, .copyPublicKey],
+ [.addresses, .listenPort, .mtu, .dns]
+ ]
+
+ let peerFieldsBySection: [[TunnelViewModel.PeerField]] = [
+ [.publicKey, .preSharedKey, .endpoint,
+ .allowedIPs, .persistentKeepAlive]
+ ]
+
+ let tunnelsManager: TunnelsManager
+ let tunnelViewModel: TunnelViewModel
+
+ init(tunnelsManager tm: TunnelsManager, tunnelConfiguration: TunnelConfiguration) {
+ tunnelsManager = tm
+ tunnelViewModel = TunnelViewModel(tunnelConfiguration: tunnelConfiguration)
+ super.init(style: .grouped)
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ self.title = tunnelViewModel.interfaceData[.name]
+ self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(editTapped))
+
+ self.tableView.rowHeight = 44
+ self.tableView.register(TunnelDetailTableViewKeyValueCell.self, forCellReuseIdentifier: TunnelDetailTableViewKeyValueCell.id)
+ self.tableView.register(TunnelDetailTableViewButtonCell.self, forCellReuseIdentifier: TunnelDetailTableViewButtonCell.id)
+ }
+
+ @objc func editTapped() {
+ print("Edit")
+ }
+}
+
+// MARK: UITableViewDataSource
+
+extension TunnelDetailTableViewController {
+ override func numberOfSections(in tableView: UITableView) -> Int {
+ let numberOfInterfaceSections = interfaceFieldsBySection.count
+ let numberOfPeerSections = peerFieldsBySection.count
+ let numberOfPeers = tunnelViewModel.peersData.count
+
+ return numberOfInterfaceSections + (numberOfPeers * numberOfPeerSections) + 1
+ }
+
+ override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ let numberOfInterfaceSections = interfaceFieldsBySection.count
+ let numberOfPeerSections = peerFieldsBySection.count
+ let numberOfPeers = tunnelViewModel.peersData.count
+
+ if (section < numberOfInterfaceSections) {
+ // Interface
+ return interfaceFieldsBySection[section].count
+ } else if ((numberOfPeers > 0) && (section < (numberOfInterfaceSections + numberOfPeers * numberOfPeerSections))) {
+ // Peer
+ let fieldIndex = (section - numberOfInterfaceSections) % numberOfPeerSections
+ return peerFieldsBySection[fieldIndex].count
+ } else {
+ // Add peer
+ return 1
+ }
+ }
+
+ override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
+ let numberOfInterfaceSections = interfaceFieldsBySection.count
+ let numberOfPeerSections = peerFieldsBySection.count
+ let numberOfPeers = tunnelViewModel.peersData.count
+
+ if (section < numberOfInterfaceSections) {
+ // Interface
+ return (section == 0) ? "Interface" : nil
+ } else if ((numberOfPeers > 0) && (section < (numberOfInterfaceSections + numberOfPeers * numberOfPeerSections))) {
+ // Peer
+ let fieldIndex = (section - numberOfInterfaceSections) % numberOfPeerSections
+ return (fieldIndex == 0) ? "Peer" : nil
+ } else {
+ // Add peer
+ return nil
+ }
+ }
+
+ override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+ let numberOfInterfaceSections = interfaceFieldsBySection.count
+ let numberOfPeerSections = peerFieldsBySection.count
+ let numberOfPeers = tunnelViewModel.peersData.count
+
+ let section = indexPath.section
+ let row = indexPath.row
+
+ if (section < numberOfInterfaceSections) {
+ // Interface
+ let interfaceData = tunnelViewModel.interfaceData
+ let field = interfaceFieldsBySection[section][row]
+ if (field == .copyPublicKey) {
+ let cell = tableView.dequeueReusableCell(withIdentifier: TunnelDetailTableViewButtonCell.id, for: indexPath) as! TunnelDetailTableViewButtonCell
+ cell.buttonText = field.rawValue
+ cell.onTapped = {
+ print("Copying public key is unimplemented") // TODO
+ }
+ return cell
+ } else {
+ let cell = tableView.dequeueReusableCell(withIdentifier: TunnelDetailTableViewKeyValueCell.id, for: indexPath) as! TunnelDetailTableViewKeyValueCell
+ // Set key and value
+ cell.key = field.rawValue
+ cell.value = interfaceData[field]
+ if (field != .publicKey) {
+ cell.detailTextLabel?.allowsDefaultTighteningForTruncation = true
+ cell.detailTextLabel?.adjustsFontSizeToFitWidth = true
+ cell.detailTextLabel?.minimumScaleFactor = 0.85
+ }
+ return cell
+ }
+ } else if ((numberOfPeers > 0) && (section < (numberOfInterfaceSections + numberOfPeers * numberOfPeerSections))) {
+ // Peer
+ let peerIndex = Int((section - numberOfInterfaceSections) / numberOfPeerSections)
+ let peerSectionIndex = (section - numberOfInterfaceSections) % numberOfPeerSections
+ let peerData = tunnelViewModel.peersData[peerIndex]
+ let field = peerFieldsBySection[peerSectionIndex][row]
+ let cell = tableView.dequeueReusableCell(withIdentifier: TunnelDetailTableViewKeyValueCell.id, for: indexPath) as! TunnelDetailTableViewKeyValueCell
+ // Set key and value
+ cell.key = field.rawValue
+ cell.value = peerData[field]
+ if (field != .publicKey && field != .preSharedKey) {
+ cell.detailTextLabel?.allowsDefaultTighteningForTruncation = true
+ cell.detailTextLabel?.adjustsFontSizeToFitWidth = true
+ cell.detailTextLabel?.minimumScaleFactor = 0.85
+ }
+
+ return cell
+ } else {
+ assert(section == (numberOfInterfaceSections + numberOfPeers * numberOfPeerSections))
+ // Delete configuration
+ let cell = tableView.dequeueReusableCell(withIdentifier: TunnelDetailTableViewButtonCell.id, for: indexPath) as! TunnelDetailTableViewButtonCell
+ cell.buttonText = "Delete tunnel"
+ cell.onTapped = {
+ print("Delete peer unimplemented")
+ }
+ return cell
+ }
+ }
+}
+
+class TunnelDetailTableViewKeyValueCell: UITableViewCell {
+ static let id: String = "TunnelDetailTableViewKeyValueCell"
+ var key: String {
+ get { return textLabel?.text ?? "" }
+ set(value) { textLabel?.text = value }
+ }
+ var value: String {
+ get { return detailTextLabel?.text ?? "" }
+ set(value) { detailTextLabel?.text = value }
+ }
+
+ override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
+ super.init(style: .value1, reuseIdentifier: TunnelDetailTableViewKeyValueCell.id)
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ override func prepareForReuse() {
+ super.prepareForReuse()
+ key = ""
+ value = ""
+ }
+}
+
+class TunnelDetailTableViewButtonCell: UITableViewCell {
+ static let id: String = "TunnelsEditTableViewButtonCell"
+ var buttonText: String {
+ get { return button.title(for: .normal) ?? "" }
+ set(value) { button.setTitle(value, for: .normal) }
+ }
+ var onTapped: (() -> Void)? = nil
+
+ let button: UIButton
+
+ override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
+ button = UIButton(type: .system)
+ super.init(style: style, reuseIdentifier: reuseIdentifier)
+ contentView.addSubview(button)
+ button.translatesAutoresizingMaskIntoConstraints = false
+ NSLayoutConstraint.activate([
+ button.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
+ button.centerXAnchor.constraint(equalTo: contentView.centerXAnchor)
+ ])
+ button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
+ }
+
+ @objc func buttonTapped() {
+ onTapped?()
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+
+ override func prepareForReuse() {
+ buttonText = ""
+ onTapped = nil
+ }
+}
diff --git a/WireGuard/WireGuard/UI/iOS/TunnelsListTableViewController.swift b/WireGuard/WireGuard/UI/iOS/TunnelsListTableViewController.swift
index 2a57393..35e90b0 100644
--- a/WireGuard/WireGuard/UI/iOS/TunnelsListTableViewController.swift
+++ b/WireGuard/WireGuard/UI/iOS/TunnelsListTableViewController.swift
@@ -81,6 +81,18 @@ extension TunnelsListTableViewController {
}
}
+// MARK: UITableViewDelegate
+
+extension TunnelsListTableViewController {
+ override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+ guard let tunnelsManager = tunnelsManager else { return }
+ let tunnelConfiguration = tunnelsManager.tunnel(at: indexPath.row).tunnelProvider.tunnelConfiguration
+ let tunnelDetailVC = TunnelDetailTableViewController(tunnelsManager: tunnelsManager,
+ tunnelConfiguration: tunnelConfiguration)
+ showDetailViewController(tunnelDetailVC, sender: self) // Shall get propagated up to the split-vc
+ }
+}
+
// MARK: TunnelsManagerDelegate
extension TunnelsListTableViewController: TunnelsManagerDelegate {