Skip to content

Commit c2f9492

Browse files
committed
Update UI for macOS 26
1 parent 75c3802 commit c2f9492

22 files changed

+156
-98
lines changed

SupportCompanion.xcodeproj/project.pbxproj

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
/* Begin PBXBuildFile section */
1010
F60FAB742CE8D40A00ECAC53 /* AlertToast in Frameworks */ = {isa = PBXBuildFile; productRef = F60FAB732CE8D40A00ECAC53 /* AlertToast */; };
1111
F60FAB872CEA108A00ECAC53 /* SidebarConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = F60FAB862CEA108A00ECAC53 /* SidebarConfig.swift */; };
12+
F627CBCB2E0AF1DF00164680 /* AppIcon.icon in Resources */ = {isa = PBXBuildFile; fileRef = F627CBCA2E0AF1DF00164680 /* AppIcon.icon */; };
1213
F64927372CF9EA8D00C34D90 /* com.github.macadmins.SupportCompanion.helper in CopyFiles */ = {isa = PBXBuildFile; fileRef = F6F8AE7D2CE345A8009B0A1F /* com.github.macadmins.SupportCompanion.helper */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
1314
F6575A992D117108007DBC83 /* ExecutionService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6F8AE9C2CE34E54009B0A1F /* ExecutionService.swift */; };
1415
F6575A9A2D117114007DBC83 /* HelperRemoteProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6F8AE9E2CE34E72009B0A1F /* HelperRemoteProvider.swift */; };
@@ -74,6 +75,7 @@
7475

7576
/* Begin PBXFileReference section */
7677
F60FAB862CEA108A00ECAC53 /* SidebarConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarConfig.swift; sourceTree = "<group>"; };
78+
F627CBCA2E0AF1DF00164680 /* AppIcon.icon */ = {isa = PBXFileReference; lastKnownFileType = folder.iconcomposer.icon; path = AppIcon.icon; sourceTree = "<group>"; };
7779
F649273D2CF9FFD600C34D90 /* CHANGELOG.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = "<group>"; };
7880
F64928192CFA02AD00C34D90 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
7981
F6890EE22CFF308F00244985 /* SupportCompanionCLI */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SupportCompanionCLI; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -166,6 +168,7 @@
166168
F68910C62D009DB500244985 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
167169
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
168170
membershipExceptions = (
171+
AppIcon.icns,
169172
MenuIcon.png,
170173
);
171174
target = F6F3BEB82CE1E7BA0036ADB9 /* SupportCompanion */;
@@ -288,6 +291,7 @@
288291
F60ED7952CEB278400960264 /* Frameworks */,
289292
F6F3BEBA2CE1E7BA0036ADB9 /* Products */,
290293
F69455982CF6076100B887F8 /* build.zsh */,
294+
F627CBCA2E0AF1DF00164680 /* AppIcon.icon */,
291295
);
292296
sourceTree = "<group>";
293297
};
@@ -491,6 +495,7 @@
491495
files = (
492496
F6F3BEC12CE1E7BB0036ADB9 /* Assets.xcassets in Resources */,
493497
F6A4E0FA2CEC9FFB002B4D74 /* Localizable.xcstrings in Resources */,
498+
F627CBCB2E0AF1DF00164680 /* AppIcon.icon in Resources */,
494499
);
495500
runOnlyForDeploymentPostprocessing = 0;
496501
};
@@ -626,7 +631,7 @@
626631
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
627632
MTL_FAST_MATH = YES;
628633
ONLY_ACTIVE_ARCH = YES;
629-
SDKROOT = macosx;
634+
SDKROOT = macosx26.0;
630635
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
631636
SWIFT_EMIT_LOC_STRINGS = YES;
632637
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@@ -685,7 +690,7 @@
685690
MTL_ENABLE_DEBUG_INFO = NO;
686691
MTL_FAST_MATH = YES;
687692
ONLY_ACTIVE_ARCH = NO;
688-
SDKROOT = macosx;
693+
SDKROOT = macosx26.0;
689694
SWIFT_COMPILATION_MODE = wholemodule;
690695
SWIFT_EMIT_LOC_STRINGS = YES;
691696
};
@@ -722,6 +727,7 @@
722727
PRODUCT_BUNDLE_IDENTIFIER = com.github.macadmins.SupportCompanion;
723728
PRODUCT_NAME = "$(TARGET_NAME)";
724729
PROVISIONING_PROFILE_SPECIFIER = "";
730+
SDKROOT = macosx;
725731
SWIFT_EMIT_LOC_STRINGS = YES;
726732
SWIFT_VERSION = 5.0;
727733
TEAM_ID = H92SB6Z7S4;
@@ -759,6 +765,7 @@
759765
PRODUCT_BUNDLE_IDENTIFIER = com.github.macadmins.SupportCompanion;
760766
PRODUCT_NAME = "$(TARGET_NAME)";
761767
PROVISIONING_PROFILE_SPECIFIER = "";
768+
SDKROOT = macosx;
762769
SWIFT_EMIT_LOC_STRINGS = YES;
763770
SWIFT_VERSION = 5.0;
764771
TEAM_ID = T4SK8ZXCXG;

SupportCompanion/ContentView.swift

Lines changed: 52 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ struct ContentView: View {
2222

2323
var body: some View {
2424
let sidebarItems = generateSidebarItems(preferences: appState.preferences, stateManager: webViewStateManager)
25-
25+
2626
NavigationSplitView {
2727
VStack(spacing: 10) {
2828
Spacer() // Push content to the center dynamically
@@ -77,52 +77,36 @@ struct ContentView: View {
7777
}
7878
}
7979
.background(Color.clear)
80-
81-
if !appState.preferences.supportEmail.isEmpty && !appState.preferences.supportPhone.isEmpty {
82-
HStack {
83-
Spacer()
84-
Button(action: {
85-
isShowingPopup = true // Show popup
86-
}) {
87-
Text("Support Information")
88-
.padding()
89-
.foregroundColor(
90-
modalButtonHovered
91-
? Color(NSColor(hex: appState.preferences.accentColor ?? "") ?? NSColor.controlAccentColor)
92-
: .primary
93-
)
94-
.cornerRadius(8)
95-
}
96-
.buttonStyle(PlainButtonStyle())
97-
.onHover { hovering in
98-
modalButtonHovered = hovering
99-
}
100-
Spacer()
101-
}
102-
}
103-
104-
HStack {
105-
Spacer()
106-
DarkLightModeToggle()
107-
Spacer()
108-
}
109-
.padding()
110-
.frame(maxWidth: .infinity)
11180
}
11281
.navigationSplitViewColumnWidth(
11382
min: 280, ideal: 280, max: 320)
11483
.frame(maxHeight: .infinity, alignment: .top)
11584
.background(Color.clear)
11685
} detail: {
117-
if let selectedItem = selectedItem {
118-
selectedItem.destination
119-
.id(selectedItem.id)
120-
.ignoresSafeArea(edges: .all)
121-
} else {
122-
Text("Select an option") // Placeholder if nothing is selected
123-
.frame(maxWidth: .infinity, maxHeight: .infinity)
124-
.background(Color.gray.opacity(0.2))
125-
}
86+
Group{
87+
if let selectedItem = selectedItem {
88+
selectedItem.destination
89+
.id(selectedItem.id)
90+
//.ignoresSafeArea(edges: .all)
91+
} else {
92+
Text("Select an option") // Placeholder if nothing is selected
93+
.frame(maxWidth: .infinity, maxHeight: .infinity)
94+
.background(Color.gray.opacity(0.1))
95+
}
96+
}
97+
.toolbar {
98+
ToolbarItem(placement: .automatic) {
99+
ToolbarSupportButton(isShowingPopup: $isShowingPopup)
100+
}
101+
102+
if #available(macOS 26.0, *) {
103+
ToolbarSpacer(.fixed)
104+
}
105+
106+
ToolbarItem(placement: .automatic) {
107+
ToolbarDarkModeToggleView()
108+
}
109+
}
126110
}
127111
.sheet(isPresented: $isShowingPopup) {
128112
// The popup content
@@ -165,6 +149,30 @@ struct ContentView: View {
165149
}
166150
}
167151

152+
struct ToolbarSupportButton: View {
153+
@EnvironmentObject var appState: AppStateManager
154+
@Binding var isShowingPopup: Bool
155+
156+
var body: some View {
157+
if !appState.preferences.supportEmail.isEmpty && !appState.preferences.supportPhone.isEmpty {
158+
Button {
159+
isShowingPopup = true
160+
} label: {
161+
Label("Support Information", systemImage: "phone")
162+
}
163+
}
164+
}
165+
}
166+
167+
struct ToolbarDarkModeToggleView: View {
168+
var body: some View {
169+
DarkLightModeToggle()
170+
.padding(.trailing, 5)
171+
.padding(.leading, 5)
172+
}
173+
}
174+
175+
168176
@ViewBuilder
169177
private func sidebarItem(for item: SidebarItem) -> some View {
170178
HStack {
@@ -179,11 +187,11 @@ struct ContentView: View {
179187
.background(
180188
Group {
181189
if selectedItem == item {
182-
RoundedRectangle(cornerRadius: 8)
190+
Capsule()
183191
.fill(Color(NSColor(hex: appState.preferences.accentColor ?? "") ?? NSColor.controlAccentColor))
184192
.matchedGeometryEffect(id: "sidebar-highlight", in: animationNamespace)
185193
} else {
186-
RoundedRectangle(cornerRadius: 8)
194+
Capsule()
187195
.fill(Color.clear)
188196
}
189197
}
@@ -236,7 +244,7 @@ struct HoverEffectModifier: ViewModifier {
236244
func body(content: Content) -> some View {
237245
content
238246
.background(
239-
RoundedRectangle(cornerRadius: 8)
247+
Capsule()
240248
.fill(isHovered ? Color.black.opacity(0.2) : Color.clear)
241249
)
242250
.onHover { hovering in

SupportCompanion/Extensions/Extensions.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,18 @@ extension Theme {
194194
.relativeLineSpacing(.em(0.25))
195195
}
196196
}
197+
198+
extension View {
199+
@ViewBuilder
200+
func isGlass() -> some View {
201+
if #available(macOS 26, *) {
202+
self.glassEffect(in: .rect(cornerRadius: 12))
203+
}
204+
else {
205+
self.background(
206+
RoundedRectangle(cornerRadius: 12)
207+
.fill(.ultraThinMaterial)
208+
)
209+
}
210+
}
211+
}

SupportCompanion/Views/Applications.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ struct Applications: View {
5656
}
5757
}
5858
}
59-
.padding(20)
59+
.padding(.horizontal, 20)
60+
.padding(.bottom, 20)
6061
.onAppear {
6162
isLoading = true
6263
let appInfoManager = ApplicationsInfoManager(appState: appState) // Local instance

SupportCompanion/Views/CardGrid.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ struct CardGrid: View {
5353
}
5454
}
5555
.padding(.horizontal, 20)
56-
.padding(.top, 20)
56+
//.padding(.top, 20)
5757

5858
LazyVGrid(columns: columns) {
5959
if appState.JsonCards.count > 0 && appState.preferences.customCardsMenuLabel.isEmpty {

SupportCompanion/Views/Cards/BatteryEvergreenStack.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,15 @@ struct BatteryEvergreenStack: View {
2020
ScCard(title: "\(Constants.CardTitle.battery)", titleImageName: "battery.100percent.bolt", imageSize: (25,25), content: {
2121
VStack(alignment: .leading) {
2222
CardData(info: appState.batteryInfoManager.batteryInfo.toKeyValuePairs())
23+
Spacer()
2324
}
24-
.frame(height: 110)
25+
//.frame(height: 110)
26+
.frame(maxHeight: .infinity, alignment: .top)
27+
.frame(minHeight: 110)
2528
.padding(.horizontal)
2629
}
2730
)
28-
.fixedSize(horizontal: false, vertical: true)
31+
.fixedSize(horizontal: false, vertical: false)
2932
}
3033

3134
if viewModel.isCardVisible(Constants.Cards.evergreen) && appState.preferences.mode == Constants.modes.munki {
@@ -42,11 +45,14 @@ struct BatteryEvergreenStack: View {
4245
.font(.system(size: 14))
4346
}
4447
}
48+
Spacer()
4549
}
46-
.frame(height: 116)
50+
//.frame(height: 116)
51+
.frame(maxHeight: .infinity, alignment: .top)
52+
.frame(minHeight: 110)
4753
.padding(.horizontal)
4854
})
49-
.fixedSize(horizontal: false, vertical: true)
55+
.fixedSize(horizontal: false, vertical: false)
5056
}
5157
}
5258
}

SupportCompanion/Views/Cards/DeviceInformationCard.swift

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,16 @@ struct DeviceInfoSection: View {
7575

7676
VStack(alignment: .leading, spacing: 5) {
7777
ForEach(group.1, id: \.key) { item in
78-
if item.key == Constants.DeviceInfo.Keys.lastRestart {
79-
LastRestartRow(
80-
label: item.display,
81-
value: item.value.rawValue as? Int ?? 0,
82-
colorScheme: colorScheme // Pass colorScheme explicitly
83-
)
84-
} else {
85-
DeviceInfoRow(label: item.display, value: item.value.displayValue)
78+
if item.key != "lastRestartDays" {
79+
if item.key == Constants.DeviceInfo.Keys.lastRestart {
80+
LastRestartRow(
81+
label: item.display,
82+
value: item.value.rawValue as? Int ?? 0,
83+
colorScheme: colorScheme // Pass colorScheme explicitly
84+
)
85+
} else {
86+
DeviceInfoRow(label: item.display, value: item.value.displayValue)
87+
}
8688
}
8789
}
8890
}

SupportCompanion/Views/Cards/StorageDeviceManagementStack.swift

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,26 +47,33 @@ struct StorageDeviceManagementStack: View {
4747
return AnyView(EmptyView())
4848
}
4949
)
50+
Spacer()
5051
}
5152
.padding(.horizontal)
52-
.frame(height: 116)
53+
//.frame(height: 116)
54+
.frame(maxHeight: .infinity, alignment: .top)
55+
.frame(minHeight: 110)
5356
})
54-
.fixedSize(horizontal: false, vertical: true)
57+
.fixedSize(horizontal: false, vertical: false)
5558
}
5659

5760
// Device Management Card
5861
if viewModel.isCardVisible(Constants.Cards.deviceManagement) {
5962
ScCard(title: "\(Constants.CardTitle.deviceManagement)", titleImageName: "lock.shield", content: {
6063
VStack(alignment: .leading, spacing: 5) {
6164
CardData(info: appState.mdmInfoManager.mdmInfo.toKeyValuePairs())
65+
Spacer()
6266
}
6367
.padding(.horizontal)
64-
.frame(height: 116)
68+
//.frame(height: 116)
69+
.frame(maxHeight: .infinity, alignment: .top)
70+
.frame(minHeight: 110)
6571
})
66-
.fixedSize(horizontal: false, vertical: true)
72+
.fixedSize(horizontal: false, vertical: false)
6773
}
6874
}
6975
.frame(maxWidth: .infinity)
76+
.frame(maxHeight: .infinity)
7077
}
7178
}
7279
}

SupportCompanion/Views/CountdownModal.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ struct CountdownModal: View {
6464
.frame(maxWidth: 250)
6565
.background(Color.red)
6666
.foregroundColor(.white)
67-
.cornerRadius(12)
67+
.cornerRadius(14)
6868
}
6969
.buttonStyle(PlainButtonStyle())
7070

SupportCompanion/Views/CustomMarkdown.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct CustomMarkdown: View {
2525
.padding(20)
2626
}
2727
}
28-
.padding(20)
28+
.padding(.horizontal, 20)
2929
.background(Color.clear)
3030
}
3131
}

0 commit comments

Comments
 (0)