mirror of
https://github.com/passepartoutvpn/wireguard-apple.git
synced 2025-02-16 12:52:06 +00:00
Add switch to info view controller.
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
cc6c8e36e0
commit
dd02986a78
@ -617,12 +617,36 @@
|
|||||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="14" translatesAutoresizingMaskIntoConstraints="NO" id="LbD-1j-3B4">
|
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" spacing="14" translatesAutoresizingMaskIntoConstraints="NO" id="LbD-1j-3B4">
|
||||||
<rect key="frame" x="16" y="11" width="343" height="246"/>
|
<rect key="frame" x="16" y="11" width="343" height="246"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Interface" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Qcg-LJ-nRV">
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9Sa-Tj-Ueo">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="343" height="51"/>
|
<rect key="frame" x="0.0" y="0.0" width="343" height="51"/>
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<subviews>
|
||||||
<nil key="textColor"/>
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Interface" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Qcg-LJ-nRV">
|
||||||
<nil key="highlightedColor"/>
|
<rect key="frame" x="0.0" y="15.5" width="286" height="20.5"/>
|
||||||
</label>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<nil key="textColor"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="odM-GH-fla">
|
||||||
|
<rect key="frame" x="294" y="10" width="51" height="31"/>
|
||||||
|
<connections>
|
||||||
|
<action selector="tunnelSwitchChanged:" destination="4nk-ch-nYS" eventType="valueChanged" id="u0k-RB-DqP"/>
|
||||||
|
</connections>
|
||||||
|
</switch>
|
||||||
|
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="EcT-Wp-yDm">
|
||||||
|
<rect key="frame" x="308" y="15.5" width="20" height="20"/>
|
||||||
|
</activityIndicatorView>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="EcT-Wp-yDm" firstAttribute="centerY" secondItem="9Sa-Tj-Ueo" secondAttribute="centerY" id="DcF-AC-6ha"/>
|
||||||
|
<constraint firstItem="odM-GH-fla" firstAttribute="centerY" secondItem="9Sa-Tj-Ueo" secondAttribute="centerY" id="Y9x-NO-H4S"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="odM-GH-fla" secondAttribute="trailing" id="hMu-gM-CG1"/>
|
||||||
|
<constraint firstItem="odM-GH-fla" firstAttribute="leading" secondItem="Qcg-LJ-nRV" secondAttribute="trailing" constant="8" id="iDB-Jf-5Ad"/>
|
||||||
|
<constraint firstAttribute="trailing" secondItem="EcT-Wp-yDm" secondAttribute="trailing" constant="15" id="mDG-cy-oEG"/>
|
||||||
|
<constraint firstItem="Qcg-LJ-nRV" firstAttribute="centerY" secondItem="9Sa-Tj-Ueo" secondAttribute="centerY" id="piF-RV-qzI"/>
|
||||||
|
<constraint firstItem="Qcg-LJ-nRV" firstAttribute="leading" secondItem="9Sa-Tj-Ueo" secondAttribute="leading" id="vpU-wH-wQf"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="wJ9-cl-tZH">
|
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="wJ9-cl-tZH">
|
||||||
<rect key="frame" x="0.0" y="65" width="343" height="51"/>
|
<rect key="frame" x="0.0" y="65" width="343" height="51"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
@ -711,9 +735,11 @@
|
|||||||
</constraints>
|
</constraints>
|
||||||
</tableViewCellContentView>
|
</tableViewCellContentView>
|
||||||
<connections>
|
<connections>
|
||||||
|
<outlet property="activityIndicator" destination="EcT-Wp-yDm" id="0YQ-7s-ckk"/>
|
||||||
<outlet property="addressesField" destination="nxw-Kz-Bhj" id="e7Y-Z0-3Mk"/>
|
<outlet property="addressesField" destination="nxw-Kz-Bhj" id="e7Y-Z0-3Mk"/>
|
||||||
<outlet property="nameField" destination="t89-wK-B5h" id="6fz-z4-Gf5"/>
|
<outlet property="nameField" destination="t89-wK-B5h" id="6fz-z4-Gf5"/>
|
||||||
<outlet property="publicKeyField" destination="bCm-fp-MGf" id="O6Q-Tf-gKf"/>
|
<outlet property="publicKeyField" destination="bCm-fp-MGf" id="O6Q-Tf-gKf"/>
|
||||||
|
<outlet property="tunnelSwitch" destination="odM-GH-fla" id="m31-9W-GgE"/>
|
||||||
</connections>
|
</connections>
|
||||||
</tableViewCell>
|
</tableViewCell>
|
||||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="PeerInfoTableViewCell" rowHeight="268" id="E8O-dS-GmI" customClass="PeerInfoTableViewCell" customModule="WireGuard" customModuleProvider="target">
|
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="PeerInfoTableViewCell" rowHeight="268" id="E8O-dS-GmI" customClass="PeerInfoTableViewCell" customModule="WireGuard" customModuleProvider="target">
|
||||||
|
@ -3,8 +3,22 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import NetworkExtension
|
||||||
|
|
||||||
extension AppCoordinator: TunnelInfoTableViewControllerDelegate {
|
extension AppCoordinator: TunnelInfoTableViewControllerDelegate {
|
||||||
|
func connect(tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController) {
|
||||||
|
connect(tunnel: tunnel)
|
||||||
|
}
|
||||||
|
|
||||||
|
func disconnect(tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController) {
|
||||||
|
disconnect(tunnel: tunnel)
|
||||||
|
}
|
||||||
|
|
||||||
|
func status(for tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController) -> NEVPNStatus {
|
||||||
|
let session = self.providerManager(for: tunnel)?.connection as? NETunnelProviderSession
|
||||||
|
return session?.status ?? .invalid
|
||||||
|
}
|
||||||
|
|
||||||
func configure(tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController) {
|
func configure(tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController) {
|
||||||
print("configure tunnel \(tunnel)")
|
print("configure tunnel \(tunnel)")
|
||||||
let editContext = persistentContainer.newBackgroundContext()
|
let editContext = persistentContainer.newBackgroundContext()
|
||||||
|
@ -55,77 +55,11 @@ extension AppCoordinator: TunnelsTableViewControllerDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func connect(tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController) {
|
func connect(tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController) {
|
||||||
_ = refreshProviderManagers().then { () -> Promise<Void> in
|
connect(tunnel: tunnel)
|
||||||
let manager = self.providerManager(for: tunnel)!
|
|
||||||
let block = {
|
|
||||||
switch manager.connection.status {
|
|
||||||
case .invalid, .disconnected:
|
|
||||||
self.connect(tunnel: tunnel)
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if manager.connection.status == .invalid {
|
|
||||||
manager.loadFromPreferences { (_) in
|
|
||||||
block()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
block()
|
|
||||||
}
|
|
||||||
|
|
||||||
return Promise.value(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func disconnect(tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController) {
|
func disconnect(tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController) {
|
||||||
_ = refreshProviderManagers().then { () -> Promise<Void> in
|
disconnect(tunnel: tunnel)
|
||||||
let manager = self.providerManager(for: tunnel)!
|
|
||||||
let block = {
|
|
||||||
switch manager.connection.status {
|
|
||||||
case .connected, .connecting:
|
|
||||||
self.disconnect(tunnel: tunnel)
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if manager.connection.status == .invalid {
|
|
||||||
manager.loadFromPreferences { (_) in
|
|
||||||
block()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
block()
|
|
||||||
}
|
|
||||||
return Promise.value(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func connect(tunnel: Tunnel) {
|
|
||||||
os_log("connect tunnel: %{public}@", log: Log.general, type: .info, tunnel.description)
|
|
||||||
// Should the manager be enabled?
|
|
||||||
|
|
||||||
let manager = providerManager(for: tunnel)
|
|
||||||
manager?.isEnabled = true
|
|
||||||
manager?.saveToPreferences { (error) in
|
|
||||||
if let error = error {
|
|
||||||
os_log("error saving preferences: %{public}@", log: Log.general, type: .error, error.localizedDescription)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
os_log("saved preferences", log: Log.general, type: .info)
|
|
||||||
|
|
||||||
let session = manager?.connection as! NETunnelProviderSession //swiftlint:disable:this force_cast
|
|
||||||
do {
|
|
||||||
try session.startTunnel()
|
|
||||||
} catch let error {
|
|
||||||
os_log("error starting tunnel: %{public}@", log: Log.general, type: .error, error.localizedDescription)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func disconnect(tunnel: Tunnel) {
|
|
||||||
let manager = providerManager(for: tunnel)
|
|
||||||
manager?.connection.stopVPNTunnel()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func info(tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController) {
|
func info(tunnel: Tunnel, tunnelsTableViewController: TunnelsTableViewController) {
|
||||||
@ -154,18 +88,6 @@ extension AppCoordinator: TunnelsTableViewControllerDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func providerManager(for tunnel: Tunnel) -> NETunnelProviderManager? {
|
|
||||||
return self.providerManagers?.first {
|
|
||||||
guard let prot = $0.protocolConfiguration as? NETunnelProviderProtocol else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
guard let tunnelIdentifier = prot.providerConfiguration?[PCKeys.tunnelIdentifier.rawValue] as? String else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return tunnelIdentifier == tunnel.tunnelIdentifier
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func saveTunnel(_ tunnel: Tunnel) {
|
func saveTunnel(_ tunnel: Tunnel) {
|
||||||
let manager = providerManager(for: tunnel) ?? NETunnelProviderManager()
|
let manager = providerManager(for: tunnel) ?? NETunnelProviderManager()
|
||||||
manager.localizedDescription = tunnel.title
|
manager.localizedDescription = tunnel.title
|
||||||
|
@ -291,6 +291,73 @@ class AppCoordinator: RootViewCoordinator {
|
|||||||
showAlert(title: NSLocalizedString("Error", comment: "Error alert title"), message: error.localizedDescription)
|
showAlert(title: NSLocalizedString("Error", comment: "Error alert title"), message: error.localizedDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func connect(tunnel: Tunnel) {
|
||||||
|
_ = refreshProviderManagers().then { () -> Promise<Void> in
|
||||||
|
let manager = self.providerManager(for: tunnel)!
|
||||||
|
let block = {
|
||||||
|
switch manager.connection.status {
|
||||||
|
case .invalid, .disconnected:
|
||||||
|
os_log("connect tunnel: %{public}@", log: Log.general, type: .info, tunnel.description)
|
||||||
|
// Should the manager be enabled?
|
||||||
|
|
||||||
|
let manager = self.providerManager(for: tunnel)
|
||||||
|
manager?.isEnabled = true
|
||||||
|
manager?.saveToPreferences { (error) in
|
||||||
|
if let error = error {
|
||||||
|
os_log("error saving preferences: %{public}@", log: Log.general, type: .error, error.localizedDescription)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
os_log("saved preferences", log: Log.general, type: .info)
|
||||||
|
|
||||||
|
let session = manager?.connection as! NETunnelProviderSession //swiftlint:disable:this force_cast
|
||||||
|
do {
|
||||||
|
try session.startTunnel()
|
||||||
|
} catch let error {
|
||||||
|
os_log("error starting tunnel: %{public}@", log: Log.general, type: .error, error.localizedDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if manager.connection.status == .invalid {
|
||||||
|
manager.loadFromPreferences { (_) in
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.value(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func disconnect(tunnel: Tunnel) {
|
||||||
|
_ = refreshProviderManagers().then { () -> Promise<Void> in
|
||||||
|
let manager = self.providerManager(for: tunnel)!
|
||||||
|
let block = {
|
||||||
|
switch manager.connection.status {
|
||||||
|
case .connected, .connecting:
|
||||||
|
let manager = self.providerManager(for: tunnel)
|
||||||
|
manager?.connection.stopVPNTunnel()
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if manager.connection.status == .invalid {
|
||||||
|
manager.loadFromPreferences { (_) in
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
return Promise.value(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func showAlert(title: String, message: String) {
|
private func showAlert(title: String, message: String) {
|
||||||
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
|
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
|
||||||
alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "OK button"), style: .default))
|
alert.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "OK button"), style: .default))
|
||||||
@ -313,6 +380,18 @@ class AppCoordinator: RootViewCoordinator {
|
|||||||
return "Reasserting"
|
return "Reasserting"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func providerManager(for tunnel: Tunnel) -> NETunnelProviderManager? {
|
||||||
|
return self.providerManagers?.first {
|
||||||
|
guard let prot = $0.protocolConfiguration as? NETunnelProviderProtocol else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
guard let tunnelIdentifier = prot.providerConfiguration?[PCKeys.tunnelIdentifier.rawValue] as? String else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return tunnelIdentifier == tunnel.tunnelIdentifier
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppDocumentPickerDelegate: NSObject, UIDocumentPickerDelegate {
|
class AppDocumentPickerDelegate: NSObject, UIDocumentPickerDelegate {
|
||||||
|
@ -4,12 +4,17 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import CoreData
|
import CoreData
|
||||||
|
import NetworkExtension
|
||||||
|
|
||||||
import BNRCoreDataStack
|
import BNRCoreDataStack
|
||||||
import PromiseKit
|
import PromiseKit
|
||||||
|
|
||||||
protocol TunnelInfoTableViewControllerDelegate: class {
|
protocol TunnelInfoTableViewControllerDelegate: class {
|
||||||
|
func connect(tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController)
|
||||||
|
func disconnect(tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController)
|
||||||
func configure(tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController)
|
func configure(tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController)
|
||||||
func showSettings()
|
func showSettings()
|
||||||
|
func status(for tunnel: Tunnel, tunnelInfoTableViewController: TunnelInfoTableViewController) -> NEVPNStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
class TunnelInfoTableViewController: UITableViewController {
|
class TunnelInfoTableViewController: UITableViewController {
|
||||||
@ -31,6 +36,11 @@ class TunnelInfoTableViewController: UITableViewController {
|
|||||||
|
|
||||||
// Get rid of seperator lines in table.
|
// Get rid of seperator lines in table.
|
||||||
tableView.tableFooterView = UIView(frame: CGRect.zero)
|
tableView.tableFooterView = UIView(frame: CGRect.zero)
|
||||||
|
|
||||||
|
NotificationCenter.default.addObserver(self,
|
||||||
|
selector: #selector(VPNStatusDidChange(notification:)),
|
||||||
|
name: .NEVPNStatusDidChange,
|
||||||
|
object: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
@ -56,7 +66,8 @@ class TunnelInfoTableViewController: UITableViewController {
|
|||||||
switch indexPath.section {
|
switch indexPath.section {
|
||||||
case 0:
|
case 0:
|
||||||
let cell = tableView.dequeueReusableCell(type: InterfaceInfoTableViewCell.self, for: indexPath)
|
let cell = tableView.dequeueReusableCell(type: InterfaceInfoTableViewCell.self, for: indexPath)
|
||||||
cell.model = tunnel.interface
|
cell.delegate = self
|
||||||
|
cell.configure(model: tunnel.interface, status: delegate?.status(for: tunnel, tunnelInfoTableViewController: self) ?? .invalid)
|
||||||
return cell
|
return cell
|
||||||
default:
|
default:
|
||||||
let cell = tableView.dequeueReusableCell(type: PeerInfoTableViewCell.self, for: indexPath)
|
let cell = tableView.dequeueReusableCell(type: PeerInfoTableViewCell.self, for: indexPath)
|
||||||
@ -78,10 +89,46 @@ class TunnelInfoTableViewController: UITableViewController {
|
|||||||
@IBAction func editTunnelConfiguration(_ sender: Any) {
|
@IBAction func editTunnelConfiguration(_ sender: Any) {
|
||||||
delegate?.configure(tunnel: self.tunnel, tunnelInfoTableViewController: self)
|
delegate?.configure(tunnel: self.tunnel, tunnelInfoTableViewController: self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc private func VPNStatusDidChange(notification: NSNotification) {
|
||||||
|
guard let session = notification.object as? NETunnelProviderSession else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let prot = session.manager.protocolConfiguration as? NETunnelProviderProtocol else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let changedTunnelIdentifier = prot.providerConfiguration?[PCKeys.tunnelIdentifier.rawValue] as? String else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard tunnel.tunnelIdentifier == changedTunnelIdentifier else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.tableView.reloadRows(at: [IndexPath(row: 0, section: 0)], with: .none)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension TunnelInfoTableViewController: InterfaceInfoTableViewCellDelegate {
|
||||||
|
func connect(tunnelIdentifier: String) {
|
||||||
|
delegate?.connect(tunnel: tunnel, tunnelInfoTableViewController: self)
|
||||||
|
}
|
||||||
|
|
||||||
|
func disconnect(tunnelIdentifier: String) {
|
||||||
|
delegate?.disconnect(tunnel: tunnel, tunnelInfoTableViewController: self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol InterfaceInfoTableViewCellDelegate: class {
|
||||||
|
func connect(tunnelIdentifier: String)
|
||||||
|
func disconnect(tunnelIdentifier: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
class InterfaceInfoTableViewCell: UITableViewCell {
|
class InterfaceInfoTableViewCell: UITableViewCell {
|
||||||
var model: Interface! {
|
weak var delegate: InterfaceInfoTableViewCellDelegate?
|
||||||
|
private var model: Interface! {
|
||||||
didSet {
|
didSet {
|
||||||
nameField.text = model.tunnel?.title
|
nameField.text = model.tunnel?.title
|
||||||
addressesField.text = model.addresses
|
addressesField.text = model.addresses
|
||||||
@ -89,9 +136,41 @@ class InterfaceInfoTableViewCell: UITableViewCell {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func configure(model: Interface!, status: NEVPNStatus) {
|
||||||
|
self.model = model
|
||||||
|
|
||||||
|
if status == .connecting || status == .disconnecting || status == .reasserting {
|
||||||
|
activityIndicator.startAnimating()
|
||||||
|
tunnelSwitch.isHidden = true
|
||||||
|
} else {
|
||||||
|
activityIndicator.stopAnimating()
|
||||||
|
tunnelSwitch.isHidden = false
|
||||||
|
}
|
||||||
|
|
||||||
|
tunnelSwitch.isOn = status == .connected
|
||||||
|
tunnelSwitch.onTintColor = status == .invalid || status == .reasserting ? .gray : .green
|
||||||
|
tunnelSwitch.isEnabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
@IBAction func tunnelSwitchChanged(_ sender: Any) {
|
||||||
|
tunnelSwitch.isEnabled = false
|
||||||
|
|
||||||
|
guard let tunnelIdentifier = model.tunnel?.tunnelIdentifier else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if tunnelSwitch.isOn {
|
||||||
|
delegate?.connect(tunnelIdentifier: tunnelIdentifier)
|
||||||
|
} else {
|
||||||
|
delegate?.disconnect(tunnelIdentifier: tunnelIdentifier)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@IBOutlet weak var nameField: UILabel!
|
@IBOutlet weak var nameField: UILabel!
|
||||||
@IBOutlet weak var addressesField: UILabel!
|
@IBOutlet weak var addressesField: UILabel!
|
||||||
@IBOutlet weak var publicKeyField: UILabel!
|
@IBOutlet weak var publicKeyField: UILabel!
|
||||||
|
@IBOutlet weak var tunnelSwitch: UISwitch!
|
||||||
|
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
|
||||||
|
|
||||||
@IBAction func copyPublicKey(_ sender: Any) {
|
@IBAction func copyPublicKey(_ sender: Any) {
|
||||||
if let publicKey = model.publicKey {
|
if let publicKey = model.publicKey {
|
||||||
|
@ -44,7 +44,7 @@ class TunnelsTableViewController: UITableViewController {
|
|||||||
let tunnel = try Tunnel.findFirstInContext(self.viewContext, predicate: NSPredicate(format: "tunnelIdentifier == %@", tunnelIdentifier))
|
let tunnel = try Tunnel.findFirstInContext(self.viewContext, predicate: NSPredicate(format: "tunnelIdentifier == %@", tunnelIdentifier))
|
||||||
if let tunnel = tunnel {
|
if let tunnel = tunnel {
|
||||||
if let indexPath = self.fetchedResultsController.indexPathForObject(tunnel) {
|
if let indexPath = self.fetchedResultsController.indexPathForObject(tunnel) {
|
||||||
self.tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.none)
|
self.tableView.reloadRows(at: [indexPath], with: .none)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
Loading…
Reference in New Issue
Block a user