diff --git a/Xcodes.xcodeproj/project.pbxproj b/Xcodes.xcodeproj/project.pbxproj index b73e456..22bf2c6 100644 --- a/Xcodes.xcodeproj/project.pbxproj +++ b/Xcodes.xcodeproj/project.pbxproj @@ -9,7 +9,7 @@ /* Begin PBXBuildFile section */ 36741BFD291E4FDB00A85AAE /* DownloadPreferencePane.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36741BFC291E4FDB00A85AAE /* DownloadPreferencePane.swift */; }; 36741BFF291E50F500A85AAE /* FileError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36741BFE291E50F500A85AAE /* FileError.swift */; }; - 536CFDD2263C94DE00026CE0 /* SignedInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536CFDD1263C94DE00026CE0 /* SignedInView.swift */; }; + 536CFDD2263C94DE00026CE0 /* SignedInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536CFDD1263C94DE00026CE0 /* SignedInView.swift */; }; 536CFDD4263C9A8000026CE0 /* XcodesSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536CFDD3263C9A8000026CE0 /* XcodesSheet.swift */; }; 53CBAB2C263DCC9100410495 /* XcodesAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53CBAB2B263DCC9100410495 /* XcodesAlert.swift */; }; 63EAA4EB259944450046AB8F /* ProgressButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63EAA4EA259944450046AB8F /* ProgressButton.swift */; }; @@ -113,6 +113,7 @@ E689540325BE8C64000EBCEA /* DockProgress in Frameworks */ = {isa = PBXBuildFile; productRef = E689540225BE8C64000EBCEA /* DockProgress */; }; E81D7EA02805250100A205FC /* Collection+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E81D7E9F2805250100A205FC /* Collection+.swift */; }; E832EAF82B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E832EAF72B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift */; }; + E84CF8C12B0FEB8300ECA259 /* RuntimesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E84CF8C02B0FEB8300ECA259 /* RuntimesView.swift */; }; E872EE4E2808D4F100D3DD8B /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E872EE502808D4F100D3DD8B /* Localizable.strings */; }; E87AB3C52939B65E00D72F43 /* Hardware.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87AB3C42939B65E00D72F43 /* Hardware.swift */; }; E87DD6EB25D053FA00D86808 /* Progress+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87DD6EA25D053FA00D86808 /* Progress+.swift */; }; @@ -324,6 +325,7 @@ E2AFDCCA28F024D000864ADD /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; }; E81D7E9F2805250100A205FC /* Collection+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+.swift"; sourceTree = ""; }; E832EAF72B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuntimeInstallationStepDetailView.swift; sourceTree = ""; }; + E84CF8C02B0FEB8300ECA259 /* RuntimesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuntimesView.swift; sourceTree = ""; }; E856BB73291EDD3D00DC438B /* XcodesKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = XcodesKit; path = Xcodes/XcodesKit; sourceTree = ""; }; E872EE4F2808D4F100D3DD8B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; E87AB3C42939B65E00D72F43 /* Hardware.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Hardware.swift; sourceTree = ""; }; @@ -659,6 +661,7 @@ B0C6AD0A2AD9178E00E64698 /* IdenticalBuildView.swift */, B0C6AD0C2AD91D7900E64698 /* IconView.swift */, E832EAF72B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift */, + E84CF8C02B0FEB8300ECA259 /* RuntimesView.swift */, ); path = InfoPane; sourceTree = ""; @@ -880,6 +883,7 @@ CA9FF8CF25959A9700E47BAF /* HelperXPCShared.swift in Sources */, CA735109257BF96D00EA9CF8 /* AttributedText.swift in Sources */, CAFBDC4E2599B33D003DCC5A /* MainToolbar.swift in Sources */, + E84CF8C12B0FEB8300ECA259 /* RuntimesView.swift in Sources */, CA11E7BA2598476C00D2EE1C /* XcodeCommands.swift in Sources */, CAA8589B25A2B83000ACF8C0 /* Aria2CError.swift in Sources */, 536CFDD2263C94DE00026CE0 /* SignedInView.swift in Sources */, diff --git a/Xcodes/Backend/AppState+Runtimes.swift b/Xcodes/Backend/AppState+Runtimes.swift index 4c19820..be8e088 100644 --- a/Xcodes/Backend/AppState+Runtimes.swift +++ b/Xcodes/Backend/AppState+Runtimes.swift @@ -54,6 +54,8 @@ extension AppState { guard let index = self.downloadableRuntimes.firstIndex(where: { $0.identifier == runtime.identifier }) else { return } self.downloadableRuntimes[index].installState = .installed } + + updateInstalledRuntimes() } catch { Logger.appState.error("Error downloading runtime: \(error.localizedDescription)") diff --git a/Xcodes/Backend/AppState.swift b/Xcodes/Backend/AppState.swift index cd6b4ef..9db4dbe 100644 --- a/Xcodes/Backend/AppState.swift +++ b/Xcodes/Backend/AppState.swift @@ -824,7 +824,7 @@ class AppState: ObservableObject { // MARK: Runtimes func runtimeInstallPath(xcode: Xcode, runtime: DownloadableRuntime) -> Path? { - if let coreSimulatorInfo = installedRuntimes.filter({ $0.runtimeInfo.build == runtime.sdkBuildUpdate }).first { + if let coreSimulatorInfo = installedRuntimes.filter({ $0.runtimeInfo.build == runtime.simulatorVersion.buildUpdate }).first { let urlString = coreSimulatorInfo.path["relative"]! // app was not allowed to open up file:// url's so remove let fileRemovedString = urlString.replacingOccurrences(of: "file://", with: "") diff --git a/Xcodes/Frontend/InfoPane/InfoPane.swift b/Xcodes/Frontend/InfoPane/InfoPane.swift index 3fcde23..d39648a 100644 --- a/Xcodes/Frontend/InfoPane/InfoPane.swift +++ b/Xcodes/Frontend/InfoPane/InfoPane.swift @@ -22,8 +22,9 @@ struct InfoPane: View { Divider() Group { - ReleaseNotesView(url: xcode.releaseNotesURL) + RuntimesView(xcode: xcode) ReleaseDateView(date: xcode.releaseDate) + ReleaseNotesView(url: xcode.releaseNotesURL) IdenticalBuildsView(builds: xcode.identicalBuilds) CompatibilityView(requiredMacOSVersion: xcode.requiredMacOSVersion) SDKsView(sdks: xcode.sdks) @@ -44,8 +45,13 @@ struct InfoPane: View { private func makePreviewContent(for index: Int) -> some View { let name = PreviewName.allCases[index] - - }) + return InfoPane(xcode: xcodeDict[name]!) + .environmentObject(configure(AppState()) { + $0.allXcodes = [xcodeDict[name]!] + }) + .frame(width: 300, height: 400) + .padding() +} enum PreviewName: String, CaseIterable, Identifiable { case Populated_Installed_Selected diff --git a/Xcodes/Frontend/InfoPane/RuntimesView.swift b/Xcodes/Frontend/InfoPane/RuntimesView.swift new file mode 100644 index 0000000..9d9251e --- /dev/null +++ b/Xcodes/Frontend/InfoPane/RuntimesView.swift @@ -0,0 +1,66 @@ +// +// RuntimesView.swift +// Xcodes +// +// Created by Matt Kiazyk on 2023-11-23. +// Copyright © 2023 Robots and Pencils. All rights reserved. +// + +import SwiftUI + +struct RuntimesView: View { + @EnvironmentObject var appState: AppState + let xcode: Xcode + + var body: some View { + VStack(alignment: .leading) { + Text("Platforms") + .font(.headline) + .frame(maxWidth: .infinity, alignment: .leading) + + let builds = xcode.sdks?.allBuilds() + let runtimes = builds?.flatMap { sdkBuild in + appState.downloadableRuntimes.filter { + $0.sdkBuildUpdate == sdkBuild + } + } + // let runtimes = appState.getRunTimes(xcode: xcode) + + ForEach(runtimes ?? [], id: \.simulatorVersion.buildUpdate) { runtime in + VStack { + HStack { + Text("\(runtime.visibleIdentifier)") + .font(.subheadline) + Spacer() + Text(runtime.downloadFileSizeString) + .font(.subheadline) + + // it's installed if we have a path + if let path = appState.runtimeInstallPath(xcode: xcode, runtime: runtime) { + Button(action: { appState.reveal(path: path.string) }) { + Image(systemName: "arrow.right.circle.fill") + } + .buttonStyle(PlainButtonStyle()) + .help("RevealInFinder") + } else { + DownloadRuntimeButton(runtime: runtime) + } + } + switch runtime.installState { + + case .installing(let installationStep): + RuntimeInstallationStepDetailView(installationStep: installationStep) + .fixedSize(horizontal: false, vertical: true) + default: + EmptyView() + } + } + + } + } + } +} + +//#Preview { +// RuntimesView() +//}