]> git.ipfire.org Git - thirdparty/wireguard-apple.git/commitdiff
macOS: Tunnels list: Show the confirmation alert till removal completes
authorRoopesh Chander <roop@roopc.net>
Fri, 5 Apr 2019 13:52:42 +0000 (19:22 +0530)
committerRoopesh Chander <roop@roopc.net>
Fri, 5 Apr 2019 18:38:45 +0000 (00:08 +0530)
Fix tunnel selection during deletion

Signed-off-by: Roopesh Chander <roop@roopc.net>
WireGuard/WireGuard/UI/macOS/ViewController/TunnelsListTableViewController.swift

index b694f3d9c66c5b0ba23f7229d4729042cf02b75f..8918f79acfb289ce58d68d51570e79f39ece9ca8 100644 (file)
@@ -12,6 +12,7 @@ class TunnelsListTableViewController: NSViewController {
 
     let tunnelsManager: TunnelsManager
     weak var delegate: TunnelsListTableViewControllerDelegate?
+    var isRemovingTunnels = false
 
     let tableView: NSTableView = {
         let tableView = NSTableView()
@@ -162,34 +163,53 @@ class TunnelsListTableViewController: NSViewController {
 
     @objc func handleRemoveTunnelAction() {
         guard let window = view.window else { return }
-        let selectedTunnelIndices = tableView.selectedRowIndexes.sorted()
-        let selectedTunnels = selectedTunnelIndices.compactMap { tunnelIndex in
-            tunnelIndex >= 0 && tunnelIndex < tunnelsManager.numberOfTunnels() ? tunnelsManager.tunnel(at: tunnelIndex) : nil
-        }
-        guard !selectedTunnels.isEmpty else { return }
+        let selectedTunnelIndices = tableView.selectedRowIndexes.sorted().filter { $0 >= 0 && $0 < tunnelsManager.numberOfTunnels() }
+        guard !selectedTunnelIndices.isEmpty else { return }
         let alert = NSAlert()
-        if selectedTunnels.count == 1 {
-            alert.messageText = tr(format: "macDeleteTunnelConfirmationAlertMessage (%@)", selectedTunnels.first!.name)
+        if selectedTunnelIndices.count == 1 {
+            let firstSelectedTunnel = tunnelsManager.tunnel(at: selectedTunnelIndices.first!)
+            alert.messageText = tr(format: "macDeleteTunnelConfirmationAlertMessage (%@)", firstSelectedTunnel.name)
         } else {
-            alert.messageText = tr(format: "macDeleteMultipleTunnelsConfirmationAlertMessage (%d)", selectedTunnels.count)
+            alert.messageText = tr(format: "macDeleteMultipleTunnelsConfirmationAlertMessage (%d)", selectedTunnelIndices.count)
         }
         alert.informativeText = tr("macDeleteTunnelConfirmationAlertInfo")
-        alert.addButton(withTitle: tr("macDeleteTunnelConfirmationAlertButtonTitleDelete"))
-        alert.addButton(withTitle: tr("macDeleteTunnelConfirmationAlertButtonTitleCancel"))
-        alert.beginSheetModal(for: window) { [weak self] response in
-            guard response == .alertFirstButtonReturn else { return }
-            self?.removeButton.isEnabled = false
-            self?.tunnelsManager.removeMultiple(tunnels: selectedTunnels) { [weak self] error in
-                guard let self = self else { return }
-                defer { self.removeButton.isEnabled = true }
-                if let error = error {
-                    ErrorPresenter.showErrorAlert(error: error, from: self)
-                    return
-                }
+        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
+            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
             }
         }
     }
 
+    @objc func removeTunnelAlertCancelClicked(_ sender: AnyObject) {
+        guard let alertWindow = (sender as? NSView)?.window, alertWindow.isSheet else { return }
+        view.window?.endSheet(alertWindow)
+    }
+
     @objc func handleViewLogAction() {
         let logVC = LogViewController()
         self.presentAsSheet(logVC)
@@ -276,15 +296,10 @@ extension TunnelsListTableViewController {
     }
 
     func tunnelRemoved(at index: Int) {
-        let selectedTunnelIndex = tableView.selectedRow
         tableView.removeRows(at: IndexSet(integer: index), withAnimation: .slideLeft)
         if tunnelsManager.numberOfTunnels() == 0 {
             delegate?.tunnelsListEmpty()
         }
-        let tunnelIndex = min(selectedTunnelIndex, self.tunnelsManager.numberOfTunnels() - 1)
-        if tunnelIndex >= 0 {
-            self.selectTunnel(at: tunnelIndex)
-        }
     }
 }