general: minor cleanup

This commit is contained in:
Michael Freno
2026-01-11 08:47:48 -05:00
parent 405008f9fa
commit 3f762cf60e
14 changed files with 111 additions and 77 deletions

View File

@@ -419,6 +419,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 14.6;
MARKETING_VERSION = 0.1.0; MARKETING_VERSION = 0.1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.mikefreno.Gaze; PRODUCT_BUNDLE_IDENTIFIER = com.mikefreno.Gaze;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
@@ -453,6 +454,7 @@
"$(inherited)", "$(inherited)",
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 14.6;
MARKETING_VERSION = 0.1.0; MARKETING_VERSION = 0.1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.mikefreno.Gaze; PRODUCT_BUNDLE_IDENTIFIER = com.mikefreno.Gaze;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";

View File

@@ -1,24 +0,0 @@
//
// ContentView.swift
// Gaze
//
// Created by Mike Freno on 1/7/26.
//
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
}
#Preview("Content View") {
ContentView()
}

View File

@@ -0,0 +1,61 @@
//
// ViewExtensions.swift
// Gaze
//
// Created by Mike Freno on 1/11/26.
//
import SwiftUI
extension View {
/// Applies a glass effect on macOS 26.0+, with a fallback visual treatment for earlier versions
@ViewBuilder
func glassEffectIfAvailable<S: InsettableShape>(
_ style: GlassStyle,
in shape: S
) -> some View {
if #available(macOS 26.0, *) {
self.glassEffect(style.toGlass(), in: shape)
} else {
self.background {
shape
.fill(.ultraThinMaterial)
.shadow(color: .black.opacity(0.1), radius: 4, x: 0, y: 2)
}
}
}
}
// MARK: - GlassStyle Wrapper
/// Cross-version wrapper for glass effect styling
struct GlassStyle {
private let tintColor: Color?
private let isInteractive: Bool
static let regular = GlassStyle(tintColor: nil, isInteractive: false)
private init(tintColor: Color?, isInteractive: Bool) {
self.tintColor = tintColor
self.isInteractive = isInteractive
}
func tint(_ color: Color) -> GlassStyle {
GlassStyle(tintColor: color, isInteractive: isInteractive)
}
func interactive() -> GlassStyle {
GlassStyle(tintColor: tintColor, isInteractive: true)
}
@available(macOS 26.0, *)
func toGlass() -> Glass {
var glass = Glass.regular
if let tintColor = tintColor {
glass = glass.tint(tintColor)
}
if isInteractive {
glass = glass.interactive()
}
return glass
}
}

View File

@@ -33,7 +33,7 @@ struct InfoBox: View {
.foregroundColor(.white) .foregroundColor(.white)
} }
.padding() .padding()
.glassEffect(.regular.tint(.accentColor), in: .rect(cornerRadius: 8)) .glassEffectIfAvailable(GlassStyle.regular.tint(.accentColor), in: .rect(cornerRadius: 8))
} }
} }

View File

@@ -74,7 +74,7 @@ struct OnboardingContainerView: View {
Image(systemName: "figure.stand") Image(systemName: "figure.stand")
} }
SettingsOnboardingView( GeneralSetupView(
launchAtLogin: $launchAtLogin, launchAtLogin: $launchAtLogin,
subtleReminderSize: $subtleReminderSize, subtleReminderSize: $subtleReminderSize,
isAppStoreVersion: Binding( isAppStoreVersion: Binding(
@@ -111,7 +111,8 @@ struct OnboardingContainerView: View {
) )
.foregroundColor(.primary) .foregroundColor(.primary)
} }
.glassEffect(.regular.interactive(), in: .rect(cornerRadius: 10)) .glassEffectIfAvailable(
GlassStyle.regular.interactive(), in: .rect(cornerRadius: 10))
} }
Button(action: { Button(action: {
@@ -133,8 +134,9 @@ struct OnboardingContainerView: View {
) )
.foregroundColor(.white) .foregroundColor(.white)
} }
.glassEffect( .glassEffectIfAvailable(
.regular.tint(currentPage == 5 ? .green : .accentColor).interactive(), GlassStyle.regular.tint(currentPage == 5 ? .green : .accentColor)
.interactive(),
in: .rect(cornerRadius: 10)) in: .rect(cornerRadius: 10))
} }
.padding(.horizontal, 40) .padding(.horizontal, 40)

View File

@@ -79,7 +79,7 @@ struct SettingsWindowView: View {
Label("User Timers", systemImage: "plus.circle") Label("User Timers", systemImage: "plus.circle")
} }
SettingsOnboardingView( GeneralSetupView(
launchAtLogin: $launchAtLogin, launchAtLogin: $launchAtLogin,
subtleReminderSize: $subtleReminderSize, subtleReminderSize: $subtleReminderSize,
isAppStoreVersion: Binding( isAppStoreVersion: Binding(

View File

@@ -29,8 +29,8 @@ struct MenuBarHoverButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View { func makeBody(configuration: Configuration) -> some View {
configuration.label configuration.label
.glassEffect( .glassEffectIfAvailable(
isHovered ? .regular.tint(.accentColor.opacity(0.5)).interactive() : .regular, isHovered ? GlassStyle.regular.tint(.accentColor.opacity(0.5)).interactive() : GlassStyle.regular,
in: .rect(cornerRadius: 6) in: .rect(cornerRadius: 6)
) )
.contentShape(Rectangle()) .contentShape(Rectangle())
@@ -316,8 +316,8 @@ struct TimerStatusRow: View {
.padding(6) .padding(6)
} }
.buttonStyle(.plain) .buttonStyle(.plain)
.glassEffect( .glassEffectIfAvailable(
isHoveredDevTrigger ? .regular.tint(.yellow.opacity(0.5)) : .regular, isHoveredDevTrigger ? GlassStyle.regular.tint(.yellow.opacity(0.5)) : GlassStyle.regular,
in: .circle in: .circle
) )
.help("Trigger \(type.displayName) reminder now (dev)") .help("Trigger \(type.displayName) reminder now (dev)")
@@ -334,8 +334,8 @@ struct TimerStatusRow: View {
.padding(6) .padding(6)
} }
.buttonStyle(.plain) .buttonStyle(.plain)
.glassEffect( .glassEffectIfAvailable(
isHoveredSkip ? .regular.tint(.accentColor.opacity(0.5)) : .regular, isHoveredSkip ? GlassStyle.regular.tint(.accentColor.opacity(0.5)) : GlassStyle.regular,
in: .circle in: .circle
) )
.help("Skip to next \(type.displayName) reminder") .help("Skip to next \(type.displayName) reminder")
@@ -345,8 +345,8 @@ struct TimerStatusRow: View {
} }
.padding(.horizontal, 8) .padding(.horizontal, 8)
.padding(.vertical, 6) .padding(.vertical, 6)
.glassEffect( .glassEffectIfAvailable(
isHoveredBody ? .regular.tint(.accentColor.opacity(0.5)) : .regular, isHoveredBody ? GlassStyle.regular.tint(.accentColor.opacity(0.5)) : GlassStyle.regular,
in: .rect(cornerRadius: 6) in: .rect(cornerRadius: 6)
) )
.padding(.horizontal, 8) .padding(.horizontal, 8)
@@ -415,8 +415,8 @@ struct InactiveTimerRow: View {
.padding(.vertical, 6) .padding(.vertical, 6)
} }
.buttonStyle(.plain) .buttonStyle(.plain)
.glassEffect( .glassEffectIfAvailable(
isHovered ? .regular.tint(.accentColor.opacity(0.5)) : .regular, isHovered ? GlassStyle.regular.tint(.accentColor.opacity(0.5)) : GlassStyle.regular,
in: .rect(cornerRadius: 6) in: .rect(cornerRadius: 6)
) )
.padding(.horizontal, 8) .padding(.horizontal, 8)
@@ -473,8 +473,8 @@ struct UserTimerStatusRow: View {
.padding(.vertical, 6) .padding(.vertical, 6)
} }
.buttonStyle(.plain) .buttonStyle(.plain)
.glassEffect( .glassEffectIfAvailable(
isHovered ? .regular.tint(timer.color.opacity(0.3)) : .regular, isHovered ? GlassStyle.regular.tint(timer.color.opacity(0.3)) : GlassStyle.regular,
in: .rect(cornerRadius: 6) in: .rect(cornerRadius: 6)
) )
.padding(.horizontal, 8) .padding(.horizontal, 8)

View File

@@ -54,7 +54,7 @@ struct BlinkSetupView: View {
.foregroundColor(.white) .foregroundColor(.white)
} }
.padding() .padding()
.glassEffect(.regular.tint(.accentColor), in: .rect(cornerRadius: 8)) .glassEffectIfAvailable(GlassStyle.regular.tint(.accentColor), in: .rect(cornerRadius: 8))
VStack(alignment: .leading, spacing: 20) { VStack(alignment: .leading, spacing: 20) {
Toggle("Enable Blink Reminders", isOn: $enabled) Toggle("Enable Blink Reminders", isOn: $enabled)
@@ -81,7 +81,7 @@ struct BlinkSetupView: View {
} }
} }
.padding() .padding()
.glassEffect(.regular, in: .rect(cornerRadius: 12)) .glassEffectIfAvailable(GlassStyle.regular, in: .rect(cornerRadius: 12))
if enabled { if enabled {
Text( Text(
@@ -111,7 +111,7 @@ struct BlinkSetupView: View {
.padding(.horizontal, 16) .padding(.horizontal, 16)
.padding(.vertical, 10) .padding(.vertical, 10)
} }
.glassEffect(.regular.tint(.accentColor).interactive(), in: .rect(cornerRadius: 10)) .glassEffectIfAvailable(GlassStyle.regular.tint(.accentColor).interactive(), in: .rect(cornerRadius: 10))
} }
Spacer() Spacer()

View File

@@ -67,7 +67,7 @@ struct CompletionView: View {
.padding(.horizontal) .padding(.horizontal)
} }
.padding() .padding()
.glassEffect(.regular, in: .rect(cornerRadius: 12)) .glassEffectIfAvailable(GlassStyle.regular, in: .rect(cornerRadius: 12))
Spacer() Spacer()
} }

View File

@@ -1,5 +1,5 @@
// //
// SettingsOnboardingView.swift // GeneralSetupView.swift
// Gaze // Gaze
// //
// Created by Mike Freno on 1/8/26. // Created by Mike Freno on 1/8/26.
@@ -7,7 +7,7 @@
import SwiftUI import SwiftUI
struct SettingsOnboardingView: View { struct GeneralSetupView: View {
@Binding var launchAtLogin: Bool @Binding var launchAtLogin: Bool
@Binding var subtleReminderSize: ReminderSize @Binding var subtleReminderSize: ReminderSize
@Binding var isAppStoreVersion: Bool @Binding var isAppStoreVersion: Bool
@@ -50,7 +50,7 @@ struct SettingsOnboardingView: View {
} }
} }
.padding() .padding()
.glassEffect(.regular, in: .rect(cornerRadius: 12)) .glassEffectIfAvailable(GlassStyle.regular, in: .rect(cornerRadius: 12))
VStack(alignment: .leading, spacing: 12) { VStack(alignment: .leading, spacing: 12) {
Text("Subtle Reminder Size") Text("Subtle Reminder Size")
@@ -87,17 +87,17 @@ struct SettingsOnboardingView: View {
.frame(maxWidth: .infinity, minHeight: 60) .frame(maxWidth: .infinity, minHeight: 60)
.padding(.vertical, 12) .padding(.vertical, 12)
} }
.glassEffect( .glassEffectIfAvailable(
subtleReminderSize == size subtleReminderSize == size
? .regular.tint(.accentColor.opacity(0.3)) ? GlassStyle.regular.tint(.accentColor.opacity(0.3))
: .regular, : GlassStyle.regular,
in: .rect(cornerRadius: 10) in: .rect(cornerRadius: 10)
) )
} }
} }
} }
.padding() .padding()
.glassEffect(.regular, in: .rect(cornerRadius: 12)) .glassEffectIfAvailable(GlassStyle.regular, in: .rect(cornerRadius: 12))
// Links Section // Links Section
VStack(spacing: 12) { VStack(spacing: 12) {
@@ -130,7 +130,8 @@ struct SettingsOnboardingView: View {
.frame(maxWidth: .infinity) .frame(maxWidth: .infinity)
} }
.buttonStyle(.plain) .buttonStyle(.plain)
.glassEffect(.regular.interactive(), in: .rect(cornerRadius: 10)) .glassEffectIfAvailable(
GlassStyle.regular.interactive(), in: .rect(cornerRadius: 10))
if !isAppStoreVersion { if !isAppStoreVersion {
Button(action: { Button(action: {
@@ -160,8 +161,9 @@ struct SettingsOnboardingView: View {
.cornerRadius(10) .cornerRadius(10)
} }
.buttonStyle(.plain) .buttonStyle(.plain)
.glassEffect( .glassEffectIfAvailable(
.regular.tint(.orange).interactive(), in: .rect(cornerRadius: 10)) GlassStyle.regular.tint(.orange).interactive(),
in: .rect(cornerRadius: 10))
} }
} }
.padding() .padding()
@@ -195,20 +197,11 @@ struct SettingsOnboardingView: View {
} }
} }
#Preview("Settings Onboarding - Launch Disabled") { #Preview("Settings Onboarding") {
SettingsOnboardingView( GeneralSetupView(
launchAtLogin: .constant(false), launchAtLogin: .constant(false),
subtleReminderSize: .constant(.medium), subtleReminderSize: .constant(.medium),
isAppStoreVersion: .constant(false), isAppStoreVersion: .constant(false),
isOnboarding: true isOnboarding: true
) )
} }
#Preview("Settings Onboarding - Launch Enabled") {
SettingsOnboardingView(
launchAtLogin: .constant(true),
subtleReminderSize: .constant(.medium),
isAppStoreVersion: .constant(false),
isOnboarding: true
)
}

View File

@@ -58,7 +58,7 @@ struct LookAwaySetupView: View {
.foregroundColor(.white) .foregroundColor(.white)
} }
.padding() .padding()
.glassEffect(.regular.tint(.accentColor), in: .rect(cornerRadius: 8)) .glassEffectIfAvailable(GlassStyle.regular.tint(.accentColor), in: .rect(cornerRadius: 8))
VStack(alignment: .leading, spacing: 20) { VStack(alignment: .leading, spacing: 20) {
Toggle("Enable Look Away Reminders", isOn: $enabled) Toggle("Enable Look Away Reminders", isOn: $enabled)
@@ -101,7 +101,7 @@ struct LookAwaySetupView: View {
} }
} }
.padding() .padding()
.glassEffect(.regular, in: .rect(cornerRadius: 12)) .glassEffectIfAvailable(GlassStyle.regular, in: .rect(cornerRadius: 12))
if enabled { if enabled {
Text( Text(
@@ -132,7 +132,7 @@ struct LookAwaySetupView: View {
.padding(.horizontal, 16) .padding(.horizontal, 16)
.padding(.vertical, 10) .padding(.vertical, 10)
} }
.glassEffect(.regular.tint(.accentColor).interactive(), in: .rect(cornerRadius: 10)) .glassEffectIfAvailable(GlassStyle.regular.tint(.accentColor).interactive(), in: .rect(cornerRadius: 10))
} }
Spacer() Spacer()

View File

@@ -56,7 +56,7 @@ struct PostureSetupView: View {
.foregroundColor(.white) .foregroundColor(.white)
} }
.padding() .padding()
.glassEffect(.regular.tint(.accentColor), in: .rect(cornerRadius: 8)) .glassEffectIfAvailable(GlassStyle.regular.tint(.accentColor), in: .rect(cornerRadius: 8))
VStack(alignment: .leading, spacing: 20) { VStack(alignment: .leading, spacing: 20) {
Toggle("Enable Posture Reminders", isOn: $enabled) Toggle("Enable Posture Reminders", isOn: $enabled)
@@ -83,7 +83,7 @@ struct PostureSetupView: View {
} }
} }
.padding() .padding()
.glassEffect(.regular, in: .rect(cornerRadius: 12)) .glassEffectIfAvailable(GlassStyle.regular, in: .rect(cornerRadius: 12))
if enabled { if enabled {
Text( Text(
@@ -113,7 +113,7 @@ struct PostureSetupView: View {
.padding(.horizontal, 16) .padding(.horizontal, 16)
.padding(.vertical, 10) .padding(.vertical, 10)
} }
.glassEffect(.regular.tint(.accentColor).interactive(), in: .rect(cornerRadius: 10)) .glassEffectIfAvailable(GlassStyle.regular.tint(.accentColor).interactive(), in: .rect(cornerRadius: 10))
} }
Spacer() Spacer()

View File

@@ -40,7 +40,7 @@ struct UserTimersView: View {
.foregroundColor(.white) .foregroundColor(.white)
} }
.padding() .padding()
.glassEffect(.regular.tint(.purple), in: .rect(cornerRadius: 8)) .glassEffectIfAvailable(GlassStyle.regular.tint(.purple), in: .rect(cornerRadius: 8))
VStack(alignment: .leading, spacing: 12) { VStack(alignment: .leading, spacing: 12) {
HStack { HStack {
@@ -96,7 +96,7 @@ struct UserTimersView: View {
} }
} }
.padding() .padding()
.glassEffect(.regular, in: .rect(cornerRadius: 12)) .glassEffectIfAvailable(GlassStyle.regular, in: .rect(cornerRadius: 12))
} }
Spacer() Spacer()
} }
@@ -354,7 +354,7 @@ struct UserTimerEditSheet: View {
} }
} }
.padding() .padding()
.glassEffect(.regular, in: .rect(cornerRadius: 12)) .glassEffectIfAvailable(GlassStyle.regular, in: .rect(cornerRadius: 12))
HStack(spacing: 12) { HStack(spacing: 12) {
Button("Cancel", action: onCancel) Button("Cancel", action: onCancel)

View File

@@ -38,7 +38,7 @@ struct WelcomeView: View {
description: "Create your own timers for specific needs") description: "Create your own timers for specific needs")
} }
.padding() .padding()
.glassEffect(.regular, in: .rect(cornerRadius: 12)) .glassEffectIfAvailable(GlassStyle.regular, in: .rect(cornerRadius: 12))
Spacer() Spacer()
} }