Copy public key through context menu.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jeroen Leenarts 2018-10-02 19:39:03 +02:00
parent cd86ba92ec
commit 7f6a7481c8
5 changed files with 84 additions and 82 deletions

View File

@ -14,6 +14,7 @@
4A4351592124956200261999 /* Validators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4351582124956200261999 /* Validators.swift */; };
4A43515A2124956200261999 /* Validators.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4351582124956200261999 /* Validators.swift */; };
4A43515C21249E5700261999 /* ValidatorsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A43515B21249E5700261999 /* ValidatorsTests.swift */; };
4A4B1B932163D24E00DDA3BB /* CopyableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4B1B922163D24E00DDA3BB /* CopyableLabel.swift */; };
4A4BA6D820B73CBA00223AB8 /* TunnelConfigurationTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BA6D720B73CBA00223AB8 /* TunnelConfigurationTableViewController.swift */; };
4A4BACE620B5F1BF00F12B28 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BACE520B5F1BF00F12B28 /* AppDelegate.swift */; };
4A4BACE820B5F1BF00F12B28 /* TunnelsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A4BACE720B5F1BF00F12B28 /* TunnelsTableViewController.swift */; };
@ -109,6 +110,7 @@
4A430E832139DCFB0078172C /* icon_60pt@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "icon_60pt@3x.png"; path = "WireGuard/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png"; sourceTree = SOURCE_ROOT; };
4A4351582124956200261999 /* Validators.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Validators.swift; sourceTree = "<group>"; };
4A43515B21249E5700261999 /* ValidatorsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValidatorsTests.swift; sourceTree = "<group>"; };
4A4B1B922163D24E00DDA3BB /* CopyableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyableLabel.swift; sourceTree = "<group>"; };
4A4BA6D720B73CBA00223AB8 /* TunnelConfigurationTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelConfigurationTableViewController.swift; sourceTree = "<group>"; };
4A4BACE220B5F1BF00F12B28 /* WireGuard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WireGuard.app; sourceTree = BUILT_PRODUCTS_DIR; };
4A4BACE520B5F1BF00F12B28 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
@ -196,6 +198,14 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
4A4B1B912163D23C00DDA3BB /* CustomViews */ = {
isa = PBXGroup;
children = (
4A4B1B922163D24E00DDA3BB /* CopyableLabel.swift */,
);
path = CustomViews;
sourceTree = "<group>";
};
4A4BACD920B5F1BF00F12B28 = {
isa = PBXGroup;
children = (
@ -224,6 +234,7 @@
4A4BACE420B5F1BF00F12B28 /* WireGuard */ = {
isa = PBXGroup;
children = (
4A4B1B912163D23C00DDA3BB /* CustomViews */,
4ABFFEA1212D39CA00107136 /* Crypto */,
4A61D83320D98D07006C7A76 /* WireGuard.entitlements */,
4A4BAD1420B5F8C000F12B28 /* Models */,
@ -635,6 +646,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4A4B1B932163D24E00DDA3BB /* CopyableLabel.swift in Sources */,
4A8A229A215B782E00736141 /* AppCoordinator+TunnelConfigurationTableViewControllerDelegate.swift in Sources */,
4A8A22A0215B821A00736141 /* ExtensionMessage.swift in Sources */,
4A4BAD0C20B5F6AA00F12B28 /* AppCoordinator.swift in Sources */,

View File

@ -223,25 +223,14 @@
<rect key="frame" x="0.0" y="0.0" width="343" height="15.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Public key" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="jrM-B3-YSD">
<rect key="frame" x="0.0" y="0.0" width="243" height="15.5"/>
<rect key="frame" x="0.0" y="0.0" width="343" height="15.5"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.60784313729999995" green="0.60784313729999995" blue="0.60784313729999995" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Oxw-Sl-4if">
<rect key="frame" x="243" y="0.0" width="100" height="15.5"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="cMG-GD-Qad"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<state key="normal" title="Copy"/>
<connections>
<action selector="copyPublicKey:" destination="06N-KU-LSv" eventType="touchUpInside" id="bkX-yC-E6w"/>
</connections>
</button>
</subviews>
</stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Qks-JK-qzc">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Qks-JK-qzc" customClass="CopyableLabel" customModule="WireGuard" customModuleProvider="target">
<rect key="frame" x="0.0" y="15.5" width="343" height="33.5"/>
<constraints>
<constraint firstAttribute="height" constant="33.5" id="YP4-TS-hbj"/>
@ -428,22 +417,11 @@
<rect key="frame" x="0.0" y="0.0" width="343" height="16"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Public key" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="s9R-Af-RNn">
<rect key="frame" x="0.0" y="0.0" width="243" height="16"/>
<rect key="frame" x="0.0" y="0.0" width="343" height="16"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.60784313729999995" green="0.60784313729999995" blue="0.60784313729999995" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="k1n-bm-do3">
<rect key="frame" x="243" y="0.0" width="100" height="16"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="qqO-dK-9SJ"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<state key="normal" title="Copy"/>
<connections>
<action selector="copyPublicKey:" destination="gzz-88-0IG" eventType="touchUpInside" id="ozU-nW-UXP"/>
</connections>
</button>
</subviews>
</stackView>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="RLw-0o-akQ">
@ -481,6 +459,9 @@
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="vxg-u7-VjZ">
<rect key="frame" x="0.0" y="180" width="343" height="46"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="SJS-V6-FwE">
<rect key="frame" x="0.0" y="0.0" width="343" height="16"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Allowed IPs" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hDL-EX-UqG">
<rect key="frame" x="0.0" y="0.0" width="343" height="16"/>
@ -488,7 +469,9 @@
<color key="textColor" red="0.60784313729999995" green="0.60784313729999995" blue="0.60784313729999995" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" placeholder="(generated)" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="iiY-Tl-UcH">
</subviews>
</stackView>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" borderStyle="roundedRect" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="iiY-Tl-UcH">
<rect key="frame" x="0.0" y="16" width="343" height="30"/>
<nil key="textColor"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/>
@ -674,25 +657,14 @@
<rect key="frame" x="0.0" y="0.0" width="343" height="17.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Public key" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="vWC-ql-O8v">
<rect key="frame" x="0.0" y="0.0" width="243" height="17.5"/>
<rect key="frame" x="0.0" y="0.0" width="343" height="17.5"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.60784313729999995" green="0.60784313729999995" blue="0.60784313729999995" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="QuI-0b-Odb">
<rect key="frame" x="243" y="0.0" width="100" height="17.5"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="Cwg-HP-HvQ"/>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<state key="normal" title="Copy"/>
<connections>
<action selector="copyPublicKey:" destination="4nk-ch-nYS" eventType="touchUpInside" id="4i8-TJ-9Ix"/>
</connections>
</button>
</subviews>
</stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bCm-fp-MGf">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bCm-fp-MGf" customClass="CopyableLabel" customModule="WireGuard" customModuleProvider="target">
<rect key="frame" x="0.0" y="17.5" width="343" height="33.5"/>
<gestureRecognizers/>
<constraints>
@ -765,25 +737,20 @@
<rect key="frame" x="0.0" y="0.0" width="343" height="17.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Public key" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="quD-G5-mlN">
<rect key="frame" x="0.0" y="0.0" width="243" height="17.5"/>
<rect key="frame" x="0.0" y="0.0" width="343" height="17.5"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" red="0.60784313729999995" green="0.60784313729999995" blue="0.60784313729999995" alpha="1" colorSpace="calibratedRGB"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="pfR-7r-TKm">
<rect key="frame" x="243" y="0.0" width="100" height="17.5"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="fQD-S2-KoL"/>
</constraints>
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Copied" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zGI-77-A75">
<rect key="frame" x="0.0" y="0.0" width="0.0" height="17.5"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<state key="normal" title="Copy"/>
<connections>
<action selector="copyPublicKey:" destination="E8O-dS-GmI" eventType="touchUpInside" id="fe2-gy-StL"/>
</connections>
</button>
<color key="textColor" red="0.52156862749999999" green="0.21176470589999999" blue="0.1764705882" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QB9-fz-eN5">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QB9-fz-eN5" customClass="CopyableLabel" customModule="WireGuard" customModuleProvider="target">
<rect key="frame" x="0.0" y="17.5" width="343" height="33.5"/>
<constraints>
<constraint firstAttribute="height" constant="33.5" id="T62-rA-BQP"/>
@ -846,6 +813,7 @@
</tableViewCellContentView>
<connections>
<outlet property="allowedIpsField" destination="h84-DM-thL" id="CR8-i3-y2q"/>
<outlet property="copiedStatusLabel" destination="zGI-77-A75" id="zev-Na-P2u"/>
<outlet property="endpointField" destination="pju-S6-5Ls" id="y3c-20-rkp"/>
<outlet property="publicKeyField" destination="QB9-fz-eN5" id="hfg-EO-IRw"/>
</connections>

View File

@ -0,0 +1,44 @@
//
// CopyableLabel.swift
// WireGuard
//
// Created by Jeroen Leenarts on 02/10/2018.
// Copyright © 2018 WireGuard LLC. All rights reserved.
//
import UIKit
@IBDesignable
class CopyableLabel: UILabel {
override func awakeFromNib() {
super.awakeFromNib()
let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(_:)))
self.addGestureRecognizer(gestureRecognizer)
self.isUserInteractionEnabled = true
}
// MARK: - UIGestureRecognizer
@objc func handleTapGesture(_ recognizer: UIGestureRecognizer) {
guard recognizer.state == .recognized else { return }
if let recognizerView = recognizer.view,
let recognizerSuperView = recognizerView.superview, recognizerView.becomeFirstResponder() {
let menuController = UIMenuController.shared
menuController.setTargetRect(recognizerView.frame, in: recognizerSuperView)
menuController.setMenuVisible(true, animated: true)
}
}
override var canBecomeFirstResponder: Bool {
return true
}
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return (action == #selector(UIResponderStandardEditActions.copy(_:)))
}
override func copy(_ sender: Any?) {
UIPasteboard.general.string = text
}
}

View File

@ -180,18 +180,12 @@ class InterfaceTableViewCell: UITableViewCell {
}
}
@IBAction func copyPublicKey(_ sender: Any) {
if let publicKey = model.publicKey {
UIPasteboard.general.string = publicKey
}
}
weak var delegate: InterfaceTableViewCellDelegate?
@IBOutlet weak var nameField: UITextField!
@IBOutlet weak var addressesField: UITextField!
@IBOutlet weak var privateKeyField: UITextField!
@IBOutlet weak var publicKeyField: UILabel!
@IBOutlet weak var publicKeyField: CopyableLabel!
@IBOutlet weak var listenPortField: UITextField!
@IBOutlet weak var dnsField: UITextField!
@IBOutlet weak var mtuField: UITextField!
@ -254,12 +248,6 @@ class PeerTableViewCell: UITableViewCell {
@IBOutlet weak var endpointField: UITextField!
@IBOutlet weak var persistentKeepaliveField: UITextField!
@IBAction func copyPublicKey(_ sender: Any) {
if let publicKey = peer.publicKey {
UIPasteboard.general.string = publicKey
}
}
@IBAction func deletePeer(_ sender: Any) {
delegate?.delete(peer: peer)
}

View File

@ -168,15 +168,9 @@ class InterfaceInfoTableViewCell: UITableViewCell {
@IBOutlet weak var nameField: UILabel!
@IBOutlet weak var addressesField: UILabel!
@IBOutlet weak var publicKeyField: UILabel!
@IBOutlet weak var publicKeyField: CopyableLabel!
@IBOutlet weak var tunnelSwitch: UISwitch!
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
@IBAction func copyPublicKey(_ sender: Any) {
if let publicKey = model.publicKey {
UIPasteboard.general.string = publicKey
}
}
}
class PeerInfoTableViewCell: UITableViewCell {
@ -188,15 +182,11 @@ class PeerInfoTableViewCell: UITableViewCell {
}
}
@IBOutlet weak var publicKeyField: UILabel!
@IBOutlet weak var publicKeyField: CopyableLabel!
@IBOutlet weak var allowedIpsField: UILabel!
@IBOutlet weak var endpointField: UILabel!
@IBOutlet weak var copiedStatusLabel: UILabel!
@IBAction func copyPublicKey(_ sender: Any) {
if let publicKey = peer.publicKey {
UIPasteboard.general.string = publicKey
}
}
}
extension TunnelInfoTableViewController: Identifyable {}