From 4a33d010a80dfba5cd13651e2a69fc79c6830b47 Mon Sep 17 00:00:00 2001 From: Brandon Evans Date: Thu, 7 Jan 2021 19:36:54 -0700 Subject: [PATCH] Confirm before cancelling installation --- Xcodes/Backend/AppState.swift | 1 + Xcodes/Backend/Xcode.swift | 6 ++++++ Xcodes/Backend/XcodeCommands.swift | 15 ++++++++++----- Xcodes/Frontend/MainWindow.swift | 9 +++++++++ .../Frontend/XcodeList/InstallationStepView.swift | 2 +- Xcodes/Frontend/XcodeList/XcodeListViewRow.swift | 6 +++++- 6 files changed, 32 insertions(+), 7 deletions(-) diff --git a/Xcodes/Backend/AppState.swift b/Xcodes/Backend/AppState.swift index 7087a52..f581fb4 100644 --- a/Xcodes/Backend/AppState.swift +++ b/Xcodes/Backend/AppState.swift @@ -30,6 +30,7 @@ class AppState: ObservableObject { @Published var isProcessingAuthRequest = false @Published var secondFactorData: SecondFactorData? @Published var xcodeBeingConfirmedForUninstallation: Xcode? + @Published var xcodeBeingConfirmedForInstallCancellation: Xcode? @Published var helperInstallState: HelperInstallState = .notInstalled // MARK: - Errors diff --git a/Xcodes/Backend/Xcode.swift b/Xcodes/Backend/Xcode.swift index 0d5baf8..87cddcb 100644 --- a/Xcodes/Backend/Xcode.swift +++ b/Xcodes/Backend/Xcode.swift @@ -39,6 +39,12 @@ struct Xcode: Identifiable, CustomStringConvertible { var id: Version { version } var installed: Bool { installState == .installed } + var installing: Bool { + switch installState { + case .installing: return true + default: return false + } + } var description: String { version.xcodeDescription diff --git a/Xcodes/Backend/XcodeCommands.swift b/Xcodes/Backend/XcodeCommands.swift index efa45a0..b4a2a8c 100644 --- a/Xcodes/Backend/XcodeCommands.swift +++ b/Xcodes/Backend/XcodeCommands.swift @@ -55,13 +55,13 @@ struct CancelInstallButton: View { var body: some View { Button(action: cancelInstall) { Text("Cancel") - .help("Cancel installation") + .help("Stop installation") } } private func cancelInstall() { guard let xcode = xcode else { return } - appState.cancelInstall(id: xcode.id) + appState.xcodeBeingConfirmedForInstallCancellation = xcode } } @@ -160,9 +160,14 @@ struct InstallCommand: View { @FocusedValue(\.selectedXcode) private var selectedXcode: SelectedXcode? var body: some View { - InstallButton(xcode: selectedXcode.unwrapped) - .keyboardShortcut("i", modifiers: [.command, .option]) - .disabled(selectedXcode.unwrapped?.installed == true) + if selectedXcode.unwrapped?.installing == true { + CancelInstallButton(xcode: selectedXcode.unwrapped) + .keyboardShortcut(".", modifiers: [.command]) + } else { + InstallButton(xcode: selectedXcode.unwrapped) + .keyboardShortcut("i", modifiers: [.command, .option]) + .disabled(selectedXcode.unwrapped?.installState != .notInstalled) + } } } diff --git a/Xcodes/Frontend/MainWindow.swift b/Xcodes/Frontend/MainWindow.swift index 4e1faf8..4170a2b 100644 --- a/Xcodes/Frontend/MainWindow.swift +++ b/Xcodes/Frontend/MainWindow.swift @@ -24,6 +24,15 @@ struct MainWindow: View { .frame(minWidth: 300, maxWidth: .infinity) .frame(width: isShowingInfoPane ? nil : 0) .isHidden(!isShowingInfoPane) + // This alert isn't intentionally placed here, + // just trying to put it in a unique part of the hierarchy + // since you can't have more than one in the same spot. + .alert(item: $appState.xcodeBeingConfirmedForInstallCancellation) { xcode in + Alert(title: Text("Are you sure you want to stop the installation of Xcode \(xcode.description)?"), + message: Text("Any progress will be discarded."), + primaryButton: .destructive(Text("Stop Installation"), action: { self.appState.cancelInstall(id: xcode.id) }), + secondaryButton: .cancel(Text("Cancel"))) + } } .mainToolbar( category: $category, diff --git a/Xcodes/Frontend/XcodeList/InstallationStepView.swift b/Xcodes/Frontend/XcodeList/InstallationStepView.swift index 38cf61b..42d3f25 100644 --- a/Xcodes/Frontend/XcodeList/InstallationStepView.swift +++ b/Xcodes/Frontend/XcodeList/InstallationStepView.swift @@ -31,7 +31,7 @@ struct InstallationStepView: View { } .buttonStyle(PlainButtonStyle()) .foregroundColor(highlighted ? .white : .secondary) - .help("Cancel installation") + .help("Stop installation") } .frame(minWidth: 80) } diff --git a/Xcodes/Frontend/XcodeList/XcodeListViewRow.swift b/Xcodes/Frontend/XcodeList/XcodeListViewRow.swift index 3c06c40..be213e5 100644 --- a/Xcodes/Frontend/XcodeList/XcodeListViewRow.swift +++ b/Xcodes/Frontend/XcodeList/XcodeListViewRow.swift @@ -85,7 +85,11 @@ struct XcodeListViewRow: View { .buttonStyle(AppStoreButtonStyle(primary: false, highlighted: selected)) .help("Install this version") case let .installing(installationStep): - InstallationStepView(installationStep: installationStep, highlighted: selected, cancel: { appState.cancelInstall(id: xcode.id) }) + InstallationStepView( + installationStep: installationStep, + highlighted: selected, + cancel: { appState.xcodeBeingConfirmedForInstallCancellation = xcode } + ) } } }