diff --git a/Xcodes.xcodeproj/project.pbxproj b/Xcodes.xcodeproj/project.pbxproj index 1198295..f0e0f6d 100644 --- a/Xcodes.xcodeproj/project.pbxproj +++ b/Xcodes.xcodeproj/project.pbxproj @@ -18,7 +18,8 @@ B0403CF42AD9381D00137C09 /* SDKsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0403CF32AD9381D00137C09 /* SDKsView.swift */; }; B0403CF62AD9849E00137C09 /* CompilersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0403CF52AD9849E00137C09 /* CompilersView.swift */; }; B0403CF82AD991F800137C09 /* UnselectedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0403CF72AD991F800137C09 /* UnselectedView.swift */; }; - B0403CFA2AD9942A00137C09 /* NotInstalledStateButtonsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0403CF92AD9942A00137C09 /* NotInstalledStateButtonsView.swift */; }; + B0403CFA2AD9942A00137C09 /* NotInstalledStateButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0403CF92AD9942A00137C09 /* NotInstalledStateButtons.swift */; }; + B0403CFC2AD9A6BF00137C09 /* InstalledStateButtons.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0403CFB2AD9A6BF00137C09 /* InstalledStateButtons.swift */; }; B0C6AD042AD6E65700E64698 /* ReleaseDateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0C6AD032AD6E65700E64698 /* ReleaseDateView.swift */; }; B0C6AD0B2AD9178E00E64698 /* IdenticalBuildView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0C6AD0A2AD9178E00E64698 /* IdenticalBuildView.swift */; }; B0C6AD0D2AD91D7900E64698 /* IconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0C6AD0C2AD91D7900E64698 /* IconView.swift */; }; @@ -206,7 +207,8 @@ B0403CF32AD9381D00137C09 /* SDKsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SDKsView.swift; sourceTree = ""; }; B0403CF52AD9849E00137C09 /* CompilersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompilersView.swift; sourceTree = ""; }; B0403CF72AD991F800137C09 /* UnselectedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnselectedView.swift; sourceTree = ""; }; - B0403CF92AD9942A00137C09 /* NotInstalledStateButtonsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotInstalledStateButtonsView.swift; sourceTree = ""; }; + B0403CF92AD9942A00137C09 /* NotInstalledStateButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotInstalledStateButtons.swift; sourceTree = ""; }; + B0403CFB2AD9A6BF00137C09 /* InstalledStateButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstalledStateButtons.swift; sourceTree = ""; }; B0C6AD032AD6E65700E64698 /* ReleaseDateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReleaseDateView.swift; sourceTree = ""; }; B0C6AD0A2AD9178E00E64698 /* IdenticalBuildView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdenticalBuildView.swift; sourceTree = ""; }; B0C6AD0C2AD91D7900E64698 /* IconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IconView.swift; sourceTree = ""; }; @@ -639,7 +641,8 @@ B0403CF12AD934B600137C09 /* CompatibilityView.swift */, CAFBDC67259A308B003DCC5A /* InfoPane.swift */, B0403CF72AD991F800137C09 /* UnselectedView.swift */, - B0403CF92AD9942A00137C09 /* NotInstalledStateButtonsView.swift */, + B0403CF92AD9942A00137C09 /* NotInstalledStateButtons.swift */, + B0403CFB2AD9A6BF00137C09 /* InstalledStateButtons.swift */, E8E98A9525D863D700EC89A0 /* InstallationStepDetailView.swift */, B0C6AD032AD6E65700E64698 /* ReleaseDateView.swift */, B0C6AD0A2AD9178E00E64698 /* IdenticalBuildView.swift */, @@ -888,6 +891,7 @@ CAA1CB45255A5B60003FD669 /* SignIn2FAView.swift in Sources */, CABFA9C52592EEEA00380FEE /* FileManager+.swift in Sources */, CABFA9CD2592EEEA00380FEE /* Foundation.swift in Sources */, + B0403CFC2AD9A6BF00137C09 /* InstalledStateButtons.swift in Sources */, 36741BFF291E50F500A85AAE /* FileError.swift in Sources */, CA9FF8872595607900E47BAF /* InstalledXcode.swift in Sources */, B0403CF22AD934B600137C09 /* CompatibilityView.swift in Sources */, @@ -928,7 +932,7 @@ CABFA9CF2592EEEA00380FEE /* Process.swift in Sources */, CAFFFED8259CDA5000903F81 /* XcodeListViewRow.swift in Sources */, CABFA9C72592EEEA00380FEE /* Entry+.swift in Sources */, - B0403CFA2AD9942A00137C09 /* NotInstalledStateButtonsView.swift in Sources */, + B0403CFA2AD9942A00137C09 /* NotInstalledStateButtons.swift in Sources */, CAE424B4259A764700B8B246 /* AppState+Install.swift in Sources */, CAE42487259A68A300B8B246 /* XcodeListCategory.swift in Sources */, CAA858C425A2BE4E00ACF8C0 /* Downloader.swift in Sources */, diff --git a/Xcodes/Backend/AppState.swift b/Xcodes/Backend/AppState.swift index 1c92951..168369f 100644 --- a/Xcodes/Backend/AppState.swift +++ b/Xcodes/Backend/AppState.swift @@ -541,10 +541,10 @@ class AppState: ObservableObject { ) } - func reveal(xcode: Xcode) { + func reveal(_ path: Path?) { // TODO: show error if not - guard let installedXcodePath = xcode.installedPath else { return } - NSWorkspace.shared.activateFileViewerSelecting([installedXcodePath.url]) + guard let path = path else { return } + NSWorkspace.shared.activateFileViewerSelecting([path.url]) } func reveal(path: String) { diff --git a/Xcodes/Backend/XcodeCommands.swift b/Xcodes/Backend/XcodeCommands.swift index 196e25d..6767afe 100644 --- a/Xcodes/Backend/XcodeCommands.swift +++ b/Xcodes/Backend/XcodeCommands.swift @@ -151,7 +151,7 @@ struct RevealButton: View { private func reveal() { guard let xcode = xcode else { return } - appState.reveal(xcode: xcode) + appState.reveal(xcode.installedPath) } } diff --git a/Xcodes/Frontend/InfoPane/InfoPane.swift b/Xcodes/Frontend/InfoPane/InfoPane.swift index 5125ab1..e242bcd 100644 --- a/Xcodes/Frontend/InfoPane/InfoPane.swift +++ b/Xcodes/Frontend/InfoPane/InfoPane.swift @@ -21,7 +21,7 @@ struct InfoPane: View { switch xcode.installState { case .notInstalled: - NotInstalledStateButtonsView( + NotInstalledStateButtons( downloadFileSizeString: xcode.downloadFileSizeString, id: xcode.id ) @@ -29,27 +29,8 @@ struct InfoPane: View { InstallationStepDetailView(installationStep: installationStep) .fixedSize(horizontal: false, vertical: true) CancelInstallButton(xcode: xcode) - case let .installed(path): - HStack { - Text(path.string) - Button(action: { appState.reveal(xcode: xcode) }) { - Image(systemName: "arrow.right.circle.fill") - } - .buttonStyle(PlainButtonStyle()) - .help("RevealInFinder") - } - - HStack { - SelectButton(xcode: xcode) - .disabled(xcode.selected) - .help("Selected") - - OpenButton(xcode: xcode) - .help("Open") - - Spacer() - UninstallButton(xcode: xcode) - } + case .installed: + InstalledStateButtons(xcode: xcode) } Divider() diff --git a/Xcodes/Frontend/InfoPane/InstalledStateButtons.swift b/Xcodes/Frontend/InfoPane/InstalledStateButtons.swift new file mode 100644 index 0000000..de1c73c --- /dev/null +++ b/Xcodes/Frontend/InfoPane/InstalledStateButtons.swift @@ -0,0 +1,80 @@ +// +// InstallingStateButtons.swift +// Xcodes +// +// Created by Duong Thai on 13/10/2023. +// Copyright © 2023 Robots and Pencils. All rights reserved. +// + +import SwiftUI +import Version +import XCModel +import Path + +struct InstalledStateButtons: View { + let xcode: Xcode + + @EnvironmentObject var appState: AppState + + var body: some View { + VStack(alignment: .leading) { + HStack { + Text(xcode.installedPath?.string ?? "") + Button(action: { appState.reveal(xcode.installedPath) }) { + Image(systemName: "arrow.right.circle.fill") + } + .buttonStyle(PlainButtonStyle()) + .help("RevealInFinder") + } + + HStack { + SelectButton(xcode: xcode) + .disabled(xcode.selected) + .help("Selected") + + OpenButton(xcode: xcode) + .help("Open") + + Spacer() + UninstallButton(xcode: xcode) + } + + } + } +} + +struct InstalledStateButtons_Preview: PreviewProvider { + static var previews: some View { + InstalledStateButtons(xcode: Self.xcode) + .environmentObject(configure(AppState()) { + $0.allXcodes = [Self.xcode] + }) + .padding() + .frame(width: 300) + } + + static private let xcode = Xcode( + version: Version(major: 12, minor: 3, patch: 0), + installState: .installed(Path("/Applications/Xcode-12.3.0.app")!), + selected: true, + icon: NSWorkspace.shared.icon(forFile: "/Applications/Xcode-12.3.0.app"), + requiredMacOSVersion: "10.15.4", + releaseNotesURL: URL(string: "https://developer.apple.com/documentation/xcode-release-notes/xcode-12_3-release-notes/")!, + releaseDate: Date(), + sdks: SDKs( + macOS: .init(number: "11.1"), + iOS: .init(number: "14.3"), + watchOS: .init(number: "7.3"), + tvOS: .init(number: "14.3") + ), + compilers: Compilers( + gcc: .init(number: "4"), + llvm_gcc: .init(number: "213"), + llvm: .init(number: "2.3"), + clang: .init(number: "7.3"), + swift: .init(number: "5.3.2") + ), + downloadFileSize: 242342424 + ) +} + diff --git a/Xcodes/Frontend/InfoPane/NotInstalledStateButtonsView.swift b/Xcodes/Frontend/InfoPane/NotInstalledStateButtons.swift similarity index 90% rename from Xcodes/Frontend/InfoPane/NotInstalledStateButtonsView.swift rename to Xcodes/Frontend/InfoPane/NotInstalledStateButtons.swift index 4935362..db81d9d 100644 --- a/Xcodes/Frontend/InfoPane/NotInstalledStateButtonsView.swift +++ b/Xcodes/Frontend/InfoPane/NotInstalledStateButtons.swift @@ -9,7 +9,7 @@ import SwiftUI import Version -struct NotInstalledStateButtonsView: View { +struct NotInstalledStateButtons: View { let downloadFileSizeString: String? let id: Version @@ -35,7 +35,7 @@ struct NotInstalledStateButtonsView: View { } } -struct NotInstalledStateButtonsView_Preview: PreviewProvider { +struct NotInstalledStateButtons_Preview: PreviewProvider { static var previews: some View { WrapperView() } @@ -52,7 +52,7 @@ private struct WrapperView: View { var body: some View { VStack { - NotInstalledStateButtonsView( + NotInstalledStateButtons( downloadFileSizeString: downloadFileSizeString, id: Version(major: 12, minor: 3, patch: 0) )