general: minor cleanup
This commit is contained in:
@@ -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)";
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
61
Gaze/Extensions/ViewExtensions.swift
Normal file
61
Gaze/Extensions/ViewExtensions.swift
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -79,7 +79,7 @@ struct SettingsWindowView: View {
|
||||
Label("User Timers", systemImage: "plus.circle")
|
||||
}
|
||||
|
||||
SettingsOnboardingView(
|
||||
GeneralSetupView(
|
||||
launchAtLogin: $launchAtLogin,
|
||||
subtleReminderSize: $subtleReminderSize,
|
||||
isAppStoreVersion: Binding(
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
@@ -67,7 +67,7 @@ struct CompletionView: View {
|
||||
.padding(.horizontal)
|
||||
}
|
||||
.padding()
|
||||
.glassEffect(.regular, in: .rect(cornerRadius: 12))
|
||||
.glassEffectIfAvailable(GlassStyle.regular, in: .rect(cornerRadius: 12))
|
||||
|
||||
Spacer()
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
@@ -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()
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
@@ -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()
|
||||
}
|
||||
Reference in New Issue
Block a user