Tunnel detail: Start off with the tunnel detail view
Signed-off-by: Roopesh Chander <roop@roopc.net>
This commit is contained in:
parent
88c7657eb7
commit
c14d816b87
|
@ -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 */,
|
||||
);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue