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)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 14.6;
MARKETING_VERSION = 0.1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.mikefreno.Gaze;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -453,6 +454,7 @@
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 14.6;
MARKETING_VERSION = 0.1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.mikefreno.Gaze;
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)
}
.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")
}
SettingsOnboardingView(
GeneralSetupView(
launchAtLogin: $launchAtLogin,
subtleReminderSize: $subtleReminderSize,
isAppStoreVersion: Binding(
@@ -111,7 +111,8 @@ struct OnboardingContainerView: View {
)
.foregroundColor(.primary)
}
.glassEffect(.regular.interactive(), in: .rect(cornerRadius: 10))
.glassEffectIfAvailable(
GlassStyle.regular.interactive(), in: .rect(cornerRadius: 10))
}
Button(action: {
@@ -133,8 +134,9 @@ struct OnboardingContainerView: View {
)
.foregroundColor(.white)
}
.glassEffect(
.regular.tint(currentPage == 5 ? .green : .accentColor).interactive(),
.glassEffectIfAvailable(
GlassStyle.regular.tint(currentPage == 5 ? .green : .accentColor)
.interactive(),
in: .rect(cornerRadius: 10))
}
.padding(.horizontal, 40)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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