mirror of
https://github.com/XcodesOrg/XcodesApp.git
synced 2026-03-25 08:55:46 +00:00
fix: better handling of opening duplicate builds
This commit is contained in:
parent
c52f742556
commit
68838ecb4c
6 changed files with 45 additions and 29 deletions
|
|
@ -366,13 +366,13 @@ class AppState: ObservableObject {
|
|||
}
|
||||
|
||||
// MARK: - Uninstall
|
||||
func uninstall(id: Xcode.ID) {
|
||||
func uninstall(xcode: Xcode) {
|
||||
guard
|
||||
let installedXcode = Current.files.installedXcodes(Path.root/"Applications").first(where: { $0.version == id }),
|
||||
let installedXcode = xcode.installPath,
|
||||
uninstallPublisher == nil
|
||||
else { return }
|
||||
|
||||
uninstallPublisher = uninstallXcode(path: installedXcode.path)
|
||||
uninstallPublisher = uninstallXcode(path: installedXcode)
|
||||
.flatMap { [unowned self] _ in
|
||||
self.updateSelectedXcodePath()
|
||||
}
|
||||
|
|
@ -388,10 +388,10 @@ class AppState: ObservableObject {
|
|||
)
|
||||
}
|
||||
|
||||
func reveal(id: Xcode.ID) {
|
||||
func reveal(xcode: Xcode) {
|
||||
// TODO: show error if not
|
||||
guard let installedXcode = Current.files.installedXcodes(Path.root/"Applications").first(where: { $0.version == id }) else { return }
|
||||
NSWorkspace.shared.activateFileViewerSelecting([installedXcode.path.url])
|
||||
guard let installedXcode = xcode.installPath else { return }
|
||||
NSWorkspace.shared.activateFileViewerSelecting([installedXcode.url])
|
||||
}
|
||||
|
||||
/// Make an Xcode active, a.k.a select it, in the `xcode-select` sense.
|
||||
|
|
@ -404,26 +404,26 @@ class AppState: ObservableObject {
|
|||
/// If they consent to installing the helper then this method will be invoked again with `shouldPrepareUserForHelperInstallation` set to false.
|
||||
/// This will install the helper and make the Xcode active.
|
||||
///
|
||||
/// - Parameter id: The identifier of the Xcode to make active.
|
||||
/// - Parameter xcode: The Xcode to make active.
|
||||
/// - Parameter shouldPrepareUserForHelperInstallation: Whether the user should be presented with an alert preparing them for helper installation before making the Xcode version active.
|
||||
func select(id: Xcode.ID, shouldPrepareUserForHelperInstallation: Bool = true) {
|
||||
func select(xcode: Xcode, shouldPrepareUserForHelperInstallation: Bool = true) {
|
||||
guard helperInstallState == .installed || shouldPrepareUserForHelperInstallation == false else {
|
||||
isPreparingUserForActionRequiringHelper = { [unowned self] userConsented in
|
||||
guard userConsented else { return }
|
||||
self.select(id: id, shouldPrepareUserForHelperInstallation: false)
|
||||
self.select(xcode: xcode, shouldPrepareUserForHelperInstallation: false)
|
||||
}
|
||||
presentedAlert = .privilegedHelper
|
||||
return
|
||||
}
|
||||
|
||||
guard
|
||||
let installedXcode = Current.files.installedXcodes(Path.root/"Applications").first(where: { $0.version == id }),
|
||||
selectPublisher == nil
|
||||
guard
|
||||
let installedXcode = xcode.installPath,
|
||||
uninstallPublisher == nil
|
||||
else { return }
|
||||
|
||||
|
||||
selectPublisher = installHelperIfNecessary()
|
||||
.flatMap {
|
||||
Current.helper.switchXcodePath(installedXcode.path.string)
|
||||
Current.helper.switchXcodePath(installedXcode.string)
|
||||
}
|
||||
.flatMap { [unowned self] _ in
|
||||
self.updateSelectedXcodePath()
|
||||
|
|
@ -440,16 +440,22 @@ class AppState: ObservableObject {
|
|||
)
|
||||
}
|
||||
|
||||
func open(id: Xcode.ID) {
|
||||
guard let installedXcode = Current.files.installedXcodes(Path.root/"Applications").first(where: { $0.version == id }) else { return }
|
||||
NSWorkspace.shared.openApplication(at: installedXcode.path.url, configuration: .init())
|
||||
func open(xcode: Xcode) {
|
||||
switch xcode.installState {
|
||||
case let .installed(path):
|
||||
NSWorkspace.shared.openApplication(at: path.url, configuration: .init())
|
||||
default:
|
||||
Logger.appState.error("\(xcode.id) is not installed")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func copyPath(id: Xcode.ID) {
|
||||
guard let installedXcode = Current.files.installedXcodes(Path.root/"Applications").first(where: { $0.version == id }) else { return }
|
||||
func copyPath(xcode: Xcode) {
|
||||
guard let installedXcode = xcode.installPath else { return }
|
||||
|
||||
NSPasteboard.general.declareTypes([.URL, .string], owner: nil)
|
||||
NSPasteboard.general.writeObjects([installedXcode.path.url as NSURL])
|
||||
NSPasteboard.general.setString(installedXcode.path.string, forType: .string)
|
||||
NSPasteboard.general.writeObjects([installedXcode.url as NSURL])
|
||||
NSPasteboard.general.setString(installedXcode.string, forType: .string)
|
||||
}
|
||||
|
||||
func updateAllXcodes(availableXcodes: [AvailableXcode], installedXcodes: [InstalledXcode], selectedXcodePath: String?) {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import Foundation
|
|||
import Version
|
||||
import struct XCModel.SDKs
|
||||
import struct XCModel.Compilers
|
||||
import Path
|
||||
|
||||
struct Xcode: Identifiable, CustomStringConvertible {
|
||||
let version: Version
|
||||
|
|
@ -57,4 +58,13 @@ struct Xcode: Identifiable, CustomStringConvertible {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var installPath: Path? {
|
||||
switch installState {
|
||||
case .installed(let path):
|
||||
return path
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ struct SelectButton: View {
|
|||
|
||||
private func select() {
|
||||
guard let xcode = xcode else { return }
|
||||
appState.select(id: xcode.id)
|
||||
appState.select(xcode: xcode)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -100,7 +100,7 @@ struct OpenButton: View {
|
|||
|
||||
private func open() {
|
||||
guard let xcode = xcode else { return }
|
||||
appState.open(id: xcode.id)
|
||||
appState.open(xcode: xcode)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -132,7 +132,7 @@ struct RevealButton: View {
|
|||
|
||||
private func reveal() {
|
||||
guard let xcode = xcode else { return }
|
||||
appState.reveal(id: xcode.id)
|
||||
appState.reveal(xcode: xcode)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -149,7 +149,7 @@ struct CopyPathButton: View {
|
|||
|
||||
private func copyPath() {
|
||||
guard let xcode = xcode else { return }
|
||||
appState.copyPath(id: xcode.id)
|
||||
appState.copyPath(xcode: xcode)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ struct InfoPane: View {
|
|||
case let .installed(path):
|
||||
HStack {
|
||||
Text(path.string)
|
||||
Button(action: { appState.reveal(id: xcode.id) }) {
|
||||
Button(action: { appState.reveal(xcode: xcode) }) {
|
||||
Image(systemName: "arrow.right.circle.fill")
|
||||
}
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ struct MainWindow: View {
|
|||
.alert(item: $appState.xcodeBeingConfirmedForUninstallation) { xcode in
|
||||
Alert(title: Text("Uninstall Xcode \(xcode.description)?"),
|
||||
message: Text("It will be moved to the Trash, but won't be emptied."),
|
||||
primaryButton: .destructive(Text("Uninstall"), action: { self.appState.uninstall(id: xcode.id) }),
|
||||
primaryButton: .destructive(Text("Uninstall"), action: { self.appState.uninstall(xcode: xcode) }),
|
||||
secondaryButton: .cancel(Text("Cancel")))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ struct XcodeListViewRow: View {
|
|||
.foregroundColor(.green)
|
||||
.help("This is the active version")
|
||||
} else {
|
||||
Button(action: { appState.select(id: xcode.id) }) {
|
||||
Button(action: { appState.select(xcode: xcode) }) {
|
||||
Image(systemName: "checkmark.circle")
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
|
|
@ -101,7 +101,7 @@ struct XcodeListViewRow: View {
|
|||
private func installControl(for xcode: Xcode) -> some View {
|
||||
switch xcode.installState {
|
||||
case .installed:
|
||||
Button("OPEN") { appState.open(id: xcode.id) }
|
||||
Button("OPEN") { appState.open(xcode: xcode) }
|
||||
.buttonStyle(AppStoreButtonStyle(primary: true, highlighted: selected))
|
||||
.help("Open this version")
|
||||
case .notInstalled:
|
||||
|
|
|
|||
Loading…
Reference in a new issue