Skip to content

Commit

Permalink
Merge pull request #461 from XcodesOrg/matt/redesign
Browse files Browse the repository at this point in the history
Redesign the main window to better suit more data
  • Loading branch information
MattKiazyk authored Dec 20, 2023
2 parents c85b3c2 + cd69ddc commit 3c5f860
Show file tree
Hide file tree
Showing 22 changed files with 519 additions and 222 deletions.
24 changes: 15 additions & 9 deletions Xcodes.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,9 @@
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 */; };
E84B7D0D2B296A8900DBDA2B /* NavigationSplitViewWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = E84B7D0C2B296A8900DBDA2B /* NavigationSplitViewWrapper.swift */; };
E84E4F522B323A5F003F3959 /* CornerRadiusModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = E84E4F512B323A5F003F3959 /* CornerRadiusModifier.swift */; };
E86671272B309D2F0048559A /* PlatformsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E86671262B309D2F0048559A /* PlatformsView.swift */; };
E87AB3C52939B65E00D72F43 /* Hardware.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87AB3C42939B65E00D72F43 /* Hardware.swift */; };
E87DD6EB25D053FA00D86808 /* Progress+.swift in Sources */ = {isa = PBXBuildFile; fileRef = E87DD6EA25D053FA00D86808 /* Progress+.swift */; };
E89342FA25EDCC17007CF557 /* NotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E89342F925EDCC17007CF557 /* NotificationManager.swift */; };
Expand Down Expand Up @@ -310,9 +311,10 @@
CAFFFEEE259CEAC400903F81 /* RingProgressViewStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RingProgressViewStyle.swift; sourceTree = "<group>"; };
E81D7E9F2805250100A205FC /* Collection+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+.swift"; sourceTree = "<group>"; };
E832EAF72B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuntimeInstallationStepDetailView.swift; sourceTree = "<group>"; };
E84CF8C02B0FEB8300ECA259 /* RuntimesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuntimesView.swift; sourceTree = "<group>"; };
E84B7D0C2B296A8900DBDA2B /* NavigationSplitViewWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationSplitViewWrapper.swift; sourceTree = "<group>"; };
E84E4F512B323A5F003F3959 /* CornerRadiusModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CornerRadiusModifier.swift; sourceTree = "<group>"; };
E856BB73291EDD3D00DC438B /* XcodesKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = XcodesKit; path = Xcodes/XcodesKit; sourceTree = "<group>"; };
E872EE4F2808D4F100D3DD8B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
E86671262B309D2F0048559A /* PlatformsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlatformsView.swift; sourceTree = "<group>"; };
E87AB3C42939B65E00D72F43 /* Hardware.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Hardware.swift; sourceTree = "<group>"; };
E87DD6EA25D053FA00D86808 /* Progress+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Progress+.swift"; sourceTree = "<group>"; };
E89342F925EDCC17007CF557 /* NotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManager.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -373,6 +375,7 @@
CA452BAF259FD9770072DFA4 /* ProgressIndicator.swift */,
536CFDD3263C9A8000026CE0 /* XcodesSheet.swift */,
53CBAB2B263DCC9100410495 /* XcodesAlert.swift */,
E84B7D0C2B296A8900DBDA2B /* NavigationSplitViewWrapper.swift */,
);
path = Common;
sourceTree = "<group>";
Expand Down Expand Up @@ -646,7 +649,8 @@
B0C6AD0A2AD9178E00E64698 /* IdenticalBuildView.swift */,
B0C6AD0C2AD91D7900E64698 /* IconView.swift */,
E832EAF72B0FBCF4001B570D /* RuntimeInstallationStepDetailView.swift */,
E84CF8C02B0FEB8300ECA259 /* RuntimesView.swift */,
E86671262B309D2F0048559A /* PlatformsView.swift */,
E84E4F512B323A5F003F3959 /* CornerRadiusModifier.swift */,
);
path = InfoPane;
sourceTree = "<group>";
Expand Down Expand Up @@ -868,7 +872,6 @@
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 */,
Expand Down Expand Up @@ -897,6 +900,7 @@
B0403CFC2AD9A6BF00137C09 /* InstalledStateButtons.swift in Sources */,
36741BFF291E50F500A85AAE /* FileError.swift in Sources */,
CA9FF8872595607900E47BAF /* InstalledXcode.swift in Sources */,
E84E4F522B323A5F003F3959 /* CornerRadiusModifier.swift in Sources */,
B0403CF22AD934B600137C09 /* CompatibilityView.swift in Sources */,
B0403CFE2ADA712C00137C09 /* InfoPaneControls.swift in Sources */,
53CBAB2C263DCC9100410495 /* XcodesAlert.swift in Sources */,
Expand All @@ -910,6 +914,7 @@
CABFA9C12592EEEA00380FEE /* Version+.swift in Sources */,
E8D655C0288DD04700A139C2 /* SelectedActionType.swift in Sources */,
36741BFD291E4FDB00A85AAE /* DownloadPreferencePane.swift in Sources */,
E86671272B309D2F0048559A /* PlatformsView.swift in Sources */,
CA9FF8522595080100E47BAF /* AcknowledgementsView.swift in Sources */,
CABFA9CE2592EEEA00380FEE /* Version+Xcode.swift in Sources */,
CAFBDB912598FE80003DCC5A /* SelectedXcode.swift in Sources */,
Expand All @@ -921,6 +926,7 @@
E8B20CBF2A2EDEC20057D816 /* SDKs+Xcode.swift in Sources */,
CA9FF877259528CC00E47BAF /* Version+XcodeReleases.swift in Sources */,
CABFAA2D2592FBFC00380FEE /* Configure.swift in Sources */,
E84B7D0D2B296A8900DBDA2B /* NavigationSplitViewWrapper.swift in Sources */,
CA73510D257BFCEF00EA9CF8 /* NSAttributedString+.swift in Sources */,
CAFBDB952598FE96003DCC5A /* FocusedValues.swift in Sources */,
B0403CF42AD9381D00137C09 /* SDKsView.swift in Sources */,
Expand Down Expand Up @@ -1040,7 +1046,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
Expand Down Expand Up @@ -1227,7 +1233,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
Expand Down Expand Up @@ -1285,7 +1291,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MACOSX_DEPLOYMENT_TARGET = 11.0;
MACOSX_DEPLOYMENT_TARGET = 12.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx;
Expand Down
1 change: 1 addition & 0 deletions Xcodes/Backend/AppState+Runtimes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ extension AppState {
Task {
do {
let runtimes = try await self.runtimeService.localInstalledRuntimes()

DispatchQueue.main.async {
self.installedRuntimes = runtimes
}
Expand Down
13 changes: 8 additions & 5 deletions Xcodes/Backend/AppState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ class AppState: ObservableObject {
checkIfHelperIsInstalled()
setupAutoInstallTimer()
setupDefaults()
updateInstalledRuntimes()
}

func setupDefaults() {
Expand Down Expand Up @@ -410,10 +409,7 @@ class AppState: ObservableObject {

// Check to see if users MacOS is supported
if let requiredMacOSVersion = availableXcode.requiredMacOSVersion {
let split = requiredMacOSVersion.components(separatedBy: ".").compactMap { Int($0) }
let xcodeMinimumMacOSVersion = OperatingSystemVersion(majorVersion: split[safe: 0] ?? 0, minorVersion: split[safe: 1] ?? 0, patchVersion: split[safe: 2] ?? 0)

if !ProcessInfo.processInfo.isOperatingSystemAtLeast(xcodeMinimumMacOSVersion) {
if hasMinSupportedOS(requiredMacOSVersion: requiredMacOSVersion) {
// prompt
self.presentedAlert = .checkMinSupportedVersion(xcode: availableXcode, macOS: ProcessInfo.processInfo.operatingSystemVersion.versionString())
return
Expand All @@ -428,6 +424,13 @@ class AppState: ObservableObject {
}
}

func hasMinSupportedOS(requiredMacOSVersion: String) -> Bool {
let split = requiredMacOSVersion.components(separatedBy: ".").compactMap { Int($0) }
let xcodeMinimumMacOSVersion = OperatingSystemVersion(majorVersion: split[safe: 0] ?? 0, minorVersion: split[safe: 1] ?? 0, patchVersion: split[safe: 2] ?? 0)

return !ProcessInfo.processInfo.isOperatingSystemAtLeast(xcodeMinimumMacOSVersion)
}

func install(id: Xcode.ID) {
guard let availableXcode = availableXcodes.first(where: { $0.version == id }) else { return }

Expand Down
23 changes: 23 additions & 0 deletions Xcodes/Backend/SDKs+Xcode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

import Foundation
import struct XCModel.SDKs
import XcodesKit
import SwiftUI

extension SDKs {
/// Loops through all SDK's and returns an array of buildNumbers (to be used to correlate runtimes)
Expand All @@ -33,3 +35,24 @@ extension SDKs {
return buildNumbers
}
}

extension DownloadableRuntime {
func icon() -> Image {
switch self.platform {
case .iOS:
return Image(systemName: "iphone")
case .macOS:
return Image(systemName: "macwindow")
case .watchOS:
return Image(systemName: "applewatch")
case .tvOS:
return Image(systemName: "appletv")
case .visionOS:
if #available(macOS 14, *) {
return Image(systemName: "visionpro")
} else {
return Image(systemName: "eyeglasses")
}
}
}
}
11 changes: 6 additions & 5 deletions Xcodes/Backend/XcodeCommands.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ struct CancelInstallButton: View {

var body: some View {
Button(action: cancelInstall) {
Text("Cancel")
.help(localizeString("StopInstallation"))
Image(systemName: "xmark.circle.fill")
}
.help(localizeString("StopInstallation"))
.buttonStyle(.plain)
}

private func cancelInstall() {
Expand All @@ -78,9 +79,9 @@ struct CancelRuntimeInstallButton: View {

var body: some View {
Button(action: cancelInstall) {
Text("Cancel")
.help(localizeString("StopInstallation"))
}
Image(systemName: "xmark.circle.fill")
}.help(localizeString("StopInstallation"))
.buttonStyle(.plain)
}

private func cancelInstall() {
Expand Down
46 changes: 46 additions & 0 deletions Xcodes/Frontend/Common/NavigationSplitViewWrapper.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// NavigationSplitViewWrapper.swift
// Xcodes
//
// Created by Matt Kiazyk on 2023-12-12.
//

import SwiftUI

struct NavigationSplitViewWrapper<Sidebar, Detail>: View where Sidebar: View, Detail: View {
private var sidebar: Sidebar
private var detail: Detail

init(
@ViewBuilder sidebar: () -> Sidebar,
@ViewBuilder detail: () -> Detail
) {
self.sidebar = sidebar()
self.detail = detail()
}

var body: some View {
if #available(iOS 16, macOS 13, tvOS 16, watchOS 9, visionOS 1, *) {
// Use the latest API available
NavigationSplitView {

if #available(macOS 14, *) {
sidebar
.toolbar(removing: .sidebarToggle)
} else {
sidebar
}
} detail: {
detail
}
} else {
// Alternative code for earlier versions of OS.
NavigationView {
// The first column is the sidebar.
sidebar
detail
}
.navigationViewStyle(.columns)
}
}
}
22 changes: 17 additions & 5 deletions Xcodes/Frontend/InfoPane/CompatibilityView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,27 @@
import SwiftUI

struct CompatibilityView: View {
@EnvironmentObject var appState: AppState

let requiredMacOSVersion: String?

var body: some View {
if let requiredMacOSVersion = requiredMacOSVersion {
VStack(alignment: .leading) {
Text("Compatibility")
.font(.headline)
Text(String(format: localizeString("MacOSRequirement"), requiredMacOSVersion))
.font(.subheadline)
HStack(alignment: .top){
VStack(alignment: .leading) {
Text("Compatibility")
.font(.headline)
Text(String(format: localizeString("MacOSRequirement"), requiredMacOSVersion))
.font(.subheadline)
.foregroundColor(appState.hasMinSupportedOS(requiredMacOSVersion: requiredMacOSVersion) ? .red : .primary)
}
Spacer()
if appState.hasMinSupportedOS(requiredMacOSVersion: requiredMacOSVersion) {
Image(systemName: "exclamationmark.triangle.fill")
.font(.largeTitle)
}
}
.xcodesBackground()
} else {
EmptyView()
}
Expand All @@ -28,4 +39,5 @@ struct CompatibilityView: View {
#Preview {
CompatibilityView(requiredMacOSVersion: "10.15.4")
.padding()
.environmentObject(AppState())
}
35 changes: 35 additions & 0 deletions Xcodes/Frontend/InfoPane/CornerRadiusModifier.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//
// CornerRadiusModifier.swift
// Xcodes
//
// Created by Matt Kiazyk on 2023-12-19.
//

import Foundation
import SwiftUI

struct CornerRadiusModifier: ViewModifier {
func body(content: Content) -> some View {
content
.frame(maxWidth: .infinity, alignment: .leading)
.padding()
.background(.background)
.clipShape(RoundedRectangle(cornerRadius: 5, style: .continuous))
}
}

extension View {
func xcodesBackground() -> some View {
self.modifier(
CornerRadiusModifier()
)
}
}

struct Previews_CornerRadius_Previews: PreviewProvider {
static var previews: some View {
HStack {
Text("XCODES RULES!")
}.xcodesBackground()
}
}
1 change: 1 addition & 0 deletions Xcodes/Frontend/InfoPane/IdenticalBuildView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ struct IdenticalBuildsView: View {
.font(.subheadline)
}
}
.xcodesBackground()
.accessibilityElement()
.accessibility(label: Text("IdenticalBuilds"))
.accessibility(value: Text(accessibilityDescription))
Expand Down
Loading

0 comments on commit 3c5f860

Please sign in to comment.