aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoopesh Chander <roop@roopc.net>2019-04-06 15:22:05 +0530
committerRoopesh Chander <roop@roopc.net>2019-04-06 17:53:41 +0530
commitf361b8a6746b3129988db27f442a42c998519643 (patch)
treedfd2f6e1738daff46fc0de56ed8cf5dd27734199
parentTunnelsManager: When setting a config, also set isAvailable cache (diff)
downloadwireguard-apple-f361b8a6746b3129988db27f442a42c998519643.tar.xz
wireguard-apple-f361b8a6746b3129988db27f442a42c998519643.zip
macOS: Tunnels list: Suppress alert buttons when removing tunnels is in progress
Also refactor the deletion alert into a separate helper class
-rw-r--r--WireGuard/WireGuard.xcodeproj/project.pbxproj4
-rw-r--r--WireGuard/WireGuard/Base.lproj/Localizable.strings1
-rw-r--r--WireGuard/WireGuard/UI/macOS/View/DeleteTunnelsConfirmationAlert.swift36
-rw-r--r--WireGuard/WireGuard/UI/macOS/ViewController/TunnelsListTableViewController.swift53
4 files changed, 60 insertions, 34 deletions
diff --git a/WireGuard/WireGuard.xcodeproj/project.pbxproj b/WireGuard/WireGuard.xcodeproj/project.pbxproj
index a7ceac9..98a18d2 100644
--- a/WireGuard/WireGuard.xcodeproj/project.pbxproj
+++ b/WireGuard/WireGuard.xcodeproj/project.pbxproj
@@ -50,6 +50,7 @@
6BD5C97E220D1AE200784E08 /* key.c in Sources */ = {isa = PBXBuildFile; fileRef = 6BD5C979220D1AE100784E08 /* key.c */; };
6F0F44C9222D55BB00B0FF04 /* TextCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F0F44C8222D55BB00B0FF04 /* TextCell.swift */; };
6F0F44CB222D55FD00B0FF04 /* EditableTextCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F0F44CA222D55FD00B0FF04 /* EditableTextCell.swift */; };
+ 6F1075642258AE9800D78929 /* DeleteTunnelsConfirmationAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F1075632258AE9800D78929 /* DeleteTunnelsConfirmationAlert.swift */; };
6F19D30422402B8700A126F2 /* ConfirmationAlertPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F19D30322402B8700A126F2 /* ConfirmationAlertPresenter.swift */; };
6F4DD16B21DA558800690EAE /* TunnelListRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F4DD16A21DA558800690EAE /* TunnelListRow.swift */; };
6F4DD16C21DA558F00690EAE /* NSTableView+Reuse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F4DD16721DA552B00690EAE /* NSTableView+Reuse.swift */; };
@@ -295,6 +296,7 @@
6BD5C97A220D1AE200784E08 /* key.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = key.h; sourceTree = "<group>"; };
6F0F44C8222D55BB00B0FF04 /* TextCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextCell.swift; sourceTree = "<group>"; };
6F0F44CA222D55FD00B0FF04 /* EditableTextCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditableTextCell.swift; sourceTree = "<group>"; };
+ 6F1075632258AE9800D78929 /* DeleteTunnelsConfirmationAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteTunnelsConfirmationAlert.swift; sourceTree = "<group>"; };
6F19D30322402B8700A126F2 /* ConfirmationAlertPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmationAlertPresenter.swift; sourceTree = "<group>"; };
6F4DD16721DA552B00690EAE /* NSTableView+Reuse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSTableView+Reuse.swift"; sourceTree = "<group>"; };
6F4DD16A21DA558800690EAE /* TunnelListRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelListRow.swift; sourceTree = "<group>"; };
@@ -483,6 +485,7 @@
6F5EA59A223E58A8002B380A /* ButtonRow.swift */,
6FB17945222FD5960018AE71 /* OnDemandWiFiControls.swift */,
6FDB6D14224CB2CE00EE4BC3 /* LogViewCell.swift */,
+ 6F1075632258AE9800D78929 /* DeleteTunnelsConfirmationAlert.swift */,
);
path = View;
sourceTree = "<group>";
@@ -1287,6 +1290,7 @@
6FADE96C2254B8C300B838A4 /* UnusableTunnelDetailViewController.swift in Sources */,
6FFACD2021E4D8D500E9A2A5 /* ParseError+WireGuardAppError.swift in Sources */,
6FB1BDC021D50F0200A991BF /* NETunnelProviderProtocol+Extension.swift in Sources */,
+ 6F1075642258AE9800D78929 /* DeleteTunnelsConfirmationAlert.swift in Sources */,
6FBA101821D656000051C35F /* StatusMenu.swift in Sources */,
6F613D9B21DE33B8004B217A /* KeyValueRow.swift in Sources */,
6FB1BDC121D50F0200A991BF /* String+ArrayConversion.swift in Sources */,
diff --git a/WireGuard/WireGuard/Base.lproj/Localizable.strings b/WireGuard/WireGuard/Base.lproj/Localizable.strings
index 5e9b6d5..cd11045 100644
--- a/WireGuard/WireGuard/Base.lproj/Localizable.strings
+++ b/WireGuard/WireGuard/Base.lproj/Localizable.strings
@@ -314,6 +314,7 @@
"macDeleteTunnelConfirmationAlertInfo" = "You cannot undo this action.";
"macDeleteTunnelConfirmationAlertButtonTitleDelete" = "Delete";
"macDeleteTunnelConfirmationAlertButtonTitleCancel" = "Cancel";
+"macDeleteTunnelConfirmationAlertButtonTitleDeleting" = "Deleting…";
"macButtonImportTunnels" = "Import tunnel(s) from file";
"macSheetButtonImport" = "Import";
diff --git a/WireGuard/WireGuard/UI/macOS/View/DeleteTunnelsConfirmationAlert.swift b/WireGuard/WireGuard/UI/macOS/View/DeleteTunnelsConfirmationAlert.swift
new file mode 100644
index 0000000..e52ed89
--- /dev/null
+++ b/WireGuard/WireGuard/UI/macOS/View/DeleteTunnelsConfirmationAlert.swift
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: MIT
+// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.
+
+import Cocoa
+
+class DeleteTunnelsConfirmationAlert: NSAlert {
+ var alertDeleteButton: NSButton?
+ var alertCancelButton: NSButton?
+
+ var onDeleteClicked: ((_ completionHandler: @escaping () -> Void) -> Void)?
+
+ override init() {
+ super.init()
+ let alertDeleteButton = addButton(withTitle: tr("macDeleteTunnelConfirmationAlertButtonTitleDelete"))
+ alertDeleteButton.target = self
+ alertDeleteButton.action = #selector(removeTunnelAlertDeleteClicked)
+ self.alertDeleteButton = alertDeleteButton
+ self.alertCancelButton = addButton(withTitle: tr("macDeleteTunnelConfirmationAlertButtonTitleCancel"))
+ }
+
+ @objc func removeTunnelAlertDeleteClicked() {
+ alertDeleteButton?.title = tr("macDeleteTunnelConfirmationAlertButtonTitleDeleting")
+ alertDeleteButton?.isEnabled = false
+ alertCancelButton?.isEnabled = false
+ if let onDeleteClicked = onDeleteClicked {
+ onDeleteClicked { [weak self] in
+ guard let self = self else { return }
+ self.window.sheetParent?.endSheet(self.window)
+ }
+ }
+ }
+
+ func beginSheetModal(for sheetWindow: NSWindow) {
+ beginSheetModal(for: sheetWindow) { _ in }
+ }
+}
diff --git a/WireGuard/WireGuard/UI/macOS/ViewController/TunnelsListTableViewController.swift b/WireGuard/WireGuard/UI/macOS/ViewController/TunnelsListTableViewController.swift
index 8918f79..40a2b9e 100644
--- a/WireGuard/WireGuard/UI/macOS/ViewController/TunnelsListTableViewController.swift
+++ b/WireGuard/WireGuard/UI/macOS/ViewController/TunnelsListTableViewController.swift
@@ -163,9 +163,15 @@ class TunnelsListTableViewController: NSViewController {
@objc func handleRemoveTunnelAction() {
guard let window = view.window else { return }
+
let selectedTunnelIndices = tableView.selectedRowIndexes.sorted().filter { $0 >= 0 && $0 < tunnelsManager.numberOfTunnels() }
guard !selectedTunnelIndices.isEmpty else { return }
- let alert = NSAlert()
+ var nextSelection = selectedTunnelIndices.last! + 1
+ if nextSelection >= tunnelsManager.numberOfTunnels() {
+ nextSelection = max(selectedTunnelIndices.first! - 1, 0)
+ }
+
+ let alert = DeleteTunnelsConfirmationAlert()
if selectedTunnelIndices.count == 1 {
let firstSelectedTunnel = tunnelsManager.tunnel(at: selectedTunnelIndices.first!)
alert.messageText = tr(format: "macDeleteTunnelConfirmationAlertMessage (%@)", firstSelectedTunnel.name)
@@ -173,41 +179,20 @@ class TunnelsListTableViewController: NSViewController {
alert.messageText = tr(format: "macDeleteMultipleTunnelsConfirmationAlertMessage (%d)", selectedTunnelIndices.count)
}
alert.informativeText = tr("macDeleteTunnelConfirmationAlertInfo")
- let alertDeleteButton = alert.addButton(withTitle: tr("macDeleteTunnelConfirmationAlertButtonTitleDelete"))
- alertDeleteButton.target = self
- alertDeleteButton.action = #selector(removeTunnelAlertDeleteClicked)
- let alertCancelButton = alert.addButton(withTitle: tr("macDeleteTunnelConfirmationAlertButtonTitleCancel"))
- alertCancelButton.target = self
- alertCancelButton.action = #selector(removeTunnelAlertCancelClicked)
- alert.beginSheetModal(for: window) { _ in }
- }
-
- @objc func removeTunnelAlertDeleteClicked(_ sender: AnyObject) {
- guard let alertWindow = (sender as? NSView)?.window, alertWindow.isSheet else { return }
- let selectedTunnelIndices = tableView.selectedRowIndexes.sorted().filter { $0 >= 0 && $0 < tunnelsManager.numberOfTunnels() }
- precondition(!selectedTunnelIndices.isEmpty)
- var nextSelection = selectedTunnelIndices.last! + 1
- if nextSelection >= tunnelsManager.numberOfTunnels() {
- nextSelection = max(selectedTunnelIndices.first! - 1, 0)
- }
- let selectedTunnels = selectedTunnelIndices.map { tunnelsManager.tunnel(at: $0) }
- alertWindow.ignoresMouseEvents = true
- self.selectTunnel(at: nextSelection)
- isRemovingTunnels = true
- tunnelsManager.removeMultiple(tunnels: selectedTunnels) { [weak self] error in
+ alert.onDeleteClicked = { [weak self] completion in
guard let self = self else { return }
- self.view.window?.endSheet(alertWindow)
- self.isRemovingTunnels = false
- if let error = error {
- ErrorPresenter.showErrorAlert(error: error, from: self)
- return
- }
+ self.selectTunnel(at: nextSelection)
+ let selectedTunnels = selectedTunnelIndices.map { self.tunnelsManager.tunnel(at: $0) }
+ self.tunnelsManager.removeMultiple(tunnels: selectedTunnels) { [weak self] error in
+ guard let self = self else { return }
+ defer { completion() }
+ if let error = error {
+ ErrorPresenter.showErrorAlert(error: error, from: self)
+ return
+ }
+ }
}
- }
-
- @objc func removeTunnelAlertCancelClicked(_ sender: AnyObject) {
- guard let alertWindow = (sender as? NSView)?.window, alertWindow.isSheet else { return }
- view.window?.endSheet(alertWindow)
+ alert.beginSheetModal(for: window)
}
@objc func handleViewLogAction() {