macOS: Tunnels list: Show the confirmation alert till removal completes

Fix tunnel selection during deletion

Signed-off-by: Roopesh Chander <roop@roopc.net>
This commit is contained in:
Roopesh Chander 2019-04-05 19:22:42 +05:30
parent 4c1b2e1258
commit 9ce42d152d
1 changed files with 40 additions and 25 deletions

View File

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