guh
This commit is contained in:
@@ -10,8 +10,6 @@ import SwiftUI
|
||||
struct BlinkSetupView: View {
|
||||
@Binding var enabled: Bool
|
||||
@Binding var intervalMinutes: Int
|
||||
var onContinue: () -> Void
|
||||
var onBack: (() -> Void)?
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 30) {
|
||||
@@ -55,34 +53,8 @@ struct BlinkSetupView: View {
|
||||
InfoBox(text: "We blink much less when focusing on screens. Regular blink reminders help prevent dry eyes")
|
||||
|
||||
Spacer()
|
||||
|
||||
HStack(spacing: 12) {
|
||||
if let onBack = onBack {
|
||||
Button(action: onBack) {
|
||||
HStack {
|
||||
Image(systemName: "chevron.left")
|
||||
Text("Back")
|
||||
}
|
||||
.font(.headline)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding()
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.glassEffect(.regular.interactive())
|
||||
}
|
||||
|
||||
Button(action: onContinue) {
|
||||
Text("Continue")
|
||||
.font(.headline)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding()
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.glassEffect(.regular.tint(.blue).interactive())
|
||||
}
|
||||
.padding(.horizontal, 40)
|
||||
}
|
||||
.frame(width: 600, height: 500)
|
||||
.frame(width: 600, height: 450)
|
||||
.padding()
|
||||
.background(.clear)
|
||||
}
|
||||
@@ -91,8 +63,6 @@ struct BlinkSetupView: View {
|
||||
#Preview {
|
||||
BlinkSetupView(
|
||||
enabled: .constant(true),
|
||||
intervalMinutes: .constant(5),
|
||||
onContinue: {},
|
||||
onBack: {}
|
||||
intervalMinutes: .constant(5)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import SwiftUI
|
||||
|
||||
struct CompletionView: View {
|
||||
var onComplete: () -> Void
|
||||
var onBack: (() -> Void)?
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 30) {
|
||||
@@ -64,39 +63,13 @@ struct CompletionView: View {
|
||||
.glassEffect(in: .rect(cornerRadius: 12))
|
||||
|
||||
Spacer()
|
||||
|
||||
HStack(spacing: 12) {
|
||||
if let onBack = onBack {
|
||||
Button(action: onBack) {
|
||||
HStack {
|
||||
Image(systemName: "chevron.left")
|
||||
Text("Back")
|
||||
}
|
||||
.font(.headline)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding()
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.glassEffect(.regular.interactive())
|
||||
}
|
||||
|
||||
Button(action: onComplete) {
|
||||
Text("Get Started")
|
||||
.font(.headline)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding()
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.glassEffect(.regular.tint(.green).interactive())
|
||||
}
|
||||
.padding(.horizontal, 40)
|
||||
}
|
||||
.frame(width: 600, height: 500)
|
||||
.frame(width: 600, height: 450)
|
||||
.padding()
|
||||
.background(.clear)
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
CompletionView(onComplete: {}, onBack: {})
|
||||
CompletionView(onComplete: {})
|
||||
}
|
||||
|
||||
@@ -11,8 +11,6 @@ struct LookAwaySetupView: View {
|
||||
@Binding var enabled: Bool
|
||||
@Binding var intervalMinutes: Int
|
||||
@Binding var countdownSeconds: Int
|
||||
var onContinue: () -> Void
|
||||
var onBack: (() -> Void)?
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 30) {
|
||||
@@ -71,34 +69,8 @@ struct LookAwaySetupView: View {
|
||||
InfoBox(text: "Every \(intervalMinutes) minutes, look in the distance for \(countdownSeconds) seconds to reduce eye strain")
|
||||
|
||||
Spacer()
|
||||
|
||||
HStack(spacing: 12) {
|
||||
if let onBack = onBack {
|
||||
Button(action: onBack) {
|
||||
HStack {
|
||||
Image(systemName: "chevron.left")
|
||||
Text("Back")
|
||||
}
|
||||
.font(.headline)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding()
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.glassEffect(.regular.interactive())
|
||||
}
|
||||
|
||||
Button(action: onContinue) {
|
||||
Text("Continue")
|
||||
.font(.headline)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding()
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.glassEffect(.regular.tint(.blue).interactive())
|
||||
}
|
||||
.padding(.horizontal, 40)
|
||||
}
|
||||
.frame(width: 600, height: 500)
|
||||
.frame(width: 600, height: 450)
|
||||
.padding()
|
||||
.background(.clear)
|
||||
}
|
||||
@@ -124,8 +96,6 @@ struct InfoBox: View {
|
||||
LookAwaySetupView(
|
||||
enabled: .constant(true),
|
||||
intervalMinutes: .constant(20),
|
||||
countdownSeconds: .constant(20),
|
||||
onContinue: {},
|
||||
onBack: {}
|
||||
countdownSeconds: .constant(20)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
//
|
||||
// OnboardingContainerView.swift
|
||||
// Gaze
|
||||
//
|
||||
// Created by Mike Freno on 1/7/26.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import AppKit
|
||||
import SwiftUI
|
||||
|
||||
// NSVisualEffectView wrapper for SwiftUI
|
||||
struct VisualEffectView: NSViewRepresentable {
|
||||
let material: NSVisualEffectView.Material
|
||||
let blendingMode: NSVisualEffectView.BlendingMode
|
||||
@@ -43,10 +35,8 @@ struct OnboardingContainerView: View {
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
// Semi-transparent background with blur
|
||||
VisualEffectView(material: .hudWindow, blendingMode: .behindWindow)
|
||||
.ignoresSafeArea()
|
||||
|
||||
VStack(spacing: 0) {
|
||||
TabView(selection: $currentPage) {
|
||||
WelcomeView(
|
||||
@@ -60,9 +50,7 @@ struct OnboardingContainerView: View {
|
||||
LookAwaySetupView(
|
||||
enabled: $lookAwayEnabled,
|
||||
intervalMinutes: $lookAwayIntervalMinutes,
|
||||
countdownSeconds: $lookAwayCountdownSeconds,
|
||||
onContinue: { currentPage = 2 },
|
||||
onBack: { currentPage = 0 }
|
||||
countdownSeconds: $lookAwayCountdownSeconds
|
||||
)
|
||||
.tag(1)
|
||||
.tabItem {
|
||||
@@ -71,9 +59,7 @@ struct OnboardingContainerView: View {
|
||||
|
||||
BlinkSetupView(
|
||||
enabled: $blinkEnabled,
|
||||
intervalMinutes: $blinkIntervalMinutes,
|
||||
onContinue: { currentPage = 3 },
|
||||
onBack: { currentPage = 1 }
|
||||
intervalMinutes: $blinkIntervalMinutes
|
||||
)
|
||||
.tag(2)
|
||||
.tabItem {
|
||||
@@ -82,9 +68,7 @@ struct OnboardingContainerView: View {
|
||||
|
||||
PostureSetupView(
|
||||
enabled: $postureEnabled,
|
||||
intervalMinutes: $postureIntervalMinutes,
|
||||
onContinue: { currentPage = 4 },
|
||||
onBack: { currentPage = 2 }
|
||||
intervalMinutes: $postureIntervalMinutes
|
||||
)
|
||||
.tag(3)
|
||||
.tabItem {
|
||||
@@ -92,9 +76,7 @@ struct OnboardingContainerView: View {
|
||||
}
|
||||
|
||||
SettingsOnboardingView(
|
||||
launchAtLogin: $launchAtLogin,
|
||||
onContinue: { currentPage = 5 },
|
||||
onBack: { currentPage = 3 }
|
||||
launchAtLogin: $launchAtLogin
|
||||
)
|
||||
.tag(4)
|
||||
.tabItem {
|
||||
@@ -104,8 +86,7 @@ struct OnboardingContainerView: View {
|
||||
CompletionView(
|
||||
onComplete: {
|
||||
completeOnboarding()
|
||||
},
|
||||
onBack: { currentPage = 4 }
|
||||
}
|
||||
)
|
||||
.tag(5)
|
||||
.tabItem {
|
||||
@@ -113,6 +94,39 @@ struct OnboardingContainerView: View {
|
||||
}
|
||||
}
|
||||
.tabViewStyle(.automatic)
|
||||
|
||||
if currentPage >= 1 {
|
||||
HStack(spacing: 12) {
|
||||
Button(action: { currentPage -= 1 }) {
|
||||
HStack {
|
||||
Image(systemName: "chevron.left")
|
||||
Text("Back")
|
||||
}
|
||||
.font(.headline)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding()
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.glassEffect(.regular.interactive())
|
||||
|
||||
Button(action: {
|
||||
if currentPage == 5 {
|
||||
completeOnboarding()
|
||||
} else {
|
||||
currentPage += 1
|
||||
}
|
||||
}) {
|
||||
Text(currentPage == 5 ? "Get Started" : "Continue")
|
||||
.font(.headline)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding()
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.glassEffect(.regular.tint(currentPage == 5 ? .green : .blue).interactive())
|
||||
}
|
||||
.padding(.horizontal, 40)
|
||||
.padding(.bottom, 20)
|
||||
}
|
||||
}
|
||||
}
|
||||
.opacity(isAnimatingOut ? 0 : 1)
|
||||
@@ -157,7 +171,11 @@ struct OnboardingContainerView: View {
|
||||
|
||||
private func performVacuumAnimation() {
|
||||
// Get the NSWindow reference
|
||||
guard let window = NSApplication.shared.windows.first(where: { $0.isVisible && $0.contentView != nil }) else {
|
||||
guard
|
||||
let window = NSApplication.shared.windows.first(where: {
|
||||
$0.isVisible && $0.contentView != nil
|
||||
})
|
||||
else {
|
||||
// Fallback: just dismiss without animation
|
||||
dismiss()
|
||||
return
|
||||
@@ -194,19 +212,17 @@ struct OnboardingContainerView: View {
|
||||
}
|
||||
|
||||
// Animate window frame using AppKit
|
||||
NSAnimationContext.runAnimationGroup({ context in
|
||||
context.duration = 0.7
|
||||
context.timingFunction = CAMediaTimingFunction(name: .easeIn)
|
||||
window.animator().setFrame(targetRect, display: true)
|
||||
window.animator().alphaValue = 0
|
||||
}, completionHandler: {
|
||||
// Close window after animation completes
|
||||
self.dismiss()
|
||||
window.close()
|
||||
})
|
||||
NSAnimationContext.runAnimationGroup(
|
||||
{ context in
|
||||
context.duration = 0.7
|
||||
context.timingFunction = CAMediaTimingFunction(name: .easeIn)
|
||||
window.animator().setFrame(targetRect, display: true)
|
||||
window.animator().alphaValue = 0
|
||||
},
|
||||
completionHandler: {
|
||||
// Close window after animation completes
|
||||
self.dismiss()
|
||||
window.close()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
OnboardingContainerView(settingsManager: SettingsManager.shared)
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@ import SwiftUI
|
||||
struct PostureSetupView: View {
|
||||
@Binding var enabled: Bool
|
||||
@Binding var intervalMinutes: Int
|
||||
var onContinue: () -> Void
|
||||
var onBack: (() -> Void)?
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 30) {
|
||||
@@ -55,34 +53,8 @@ struct PostureSetupView: View {
|
||||
InfoBox(text: "Regular posture checks help prevent back and neck pain from prolonged sitting")
|
||||
|
||||
Spacer()
|
||||
|
||||
HStack(spacing: 12) {
|
||||
if let onBack = onBack {
|
||||
Button(action: onBack) {
|
||||
HStack {
|
||||
Image(systemName: "chevron.left")
|
||||
Text("Back")
|
||||
}
|
||||
.font(.headline)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding()
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.glassEffect(.regular.interactive())
|
||||
}
|
||||
|
||||
Button(action: onContinue) {
|
||||
Text("Continue")
|
||||
.font(.headline)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding()
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.glassEffect(.regular.tint(.blue).interactive())
|
||||
}
|
||||
.padding(.horizontal, 40)
|
||||
}
|
||||
.frame(width: 600, height: 500)
|
||||
.frame(width: 600, height: 450)
|
||||
.padding()
|
||||
.background(.clear)
|
||||
}
|
||||
@@ -91,8 +63,6 @@ struct PostureSetupView: View {
|
||||
#Preview {
|
||||
PostureSetupView(
|
||||
enabled: .constant(true),
|
||||
intervalMinutes: .constant(30),
|
||||
onContinue: {},
|
||||
onBack: {}
|
||||
intervalMinutes: .constant(30)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -9,8 +9,6 @@ import SwiftUI
|
||||
|
||||
struct SettingsOnboardingView: View {
|
||||
@Binding var launchAtLogin: Bool
|
||||
var onContinue: () -> Void
|
||||
var onBack: (() -> Void)?
|
||||
|
||||
var body: some View {
|
||||
VStack(spacing: 30) {
|
||||
@@ -116,34 +114,8 @@ struct SettingsOnboardingView: View {
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
HStack(spacing: 12) {
|
||||
if let onBack = onBack {
|
||||
Button(action: onBack) {
|
||||
HStack {
|
||||
Image(systemName: "chevron.left")
|
||||
Text("Back")
|
||||
}
|
||||
.font(.headline)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding()
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.glassEffect(.regular.interactive())
|
||||
}
|
||||
|
||||
Button(action: onContinue) {
|
||||
Text("Continue")
|
||||
.font(.headline)
|
||||
.frame(maxWidth: .infinity)
|
||||
.padding()
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
.glassEffect(.regular.tint(.blue).interactive())
|
||||
}
|
||||
.padding(.horizontal, 40)
|
||||
}
|
||||
.frame(width: 600, height: 500)
|
||||
.frame(width: 600, height: 450)
|
||||
.padding()
|
||||
.background(.clear)
|
||||
}
|
||||
@@ -163,8 +135,6 @@ struct SettingsOnboardingView: View {
|
||||
|
||||
#Preview {
|
||||
SettingsOnboardingView(
|
||||
launchAtLogin: .constant(false),
|
||||
onContinue: {},
|
||||
onBack: {}
|
||||
launchAtLogin: .constant(false)
|
||||
)
|
||||
}
|
||||
|
||||
21
run
21
run
@@ -4,7 +4,7 @@
|
||||
# Usage: ./run [build|test|run]
|
||||
|
||||
# Default action is build and run
|
||||
ACTION=${1:-build}
|
||||
ACTION=${1:-run}
|
||||
VERBOSE=false
|
||||
OUTPUT_FILE=""
|
||||
|
||||
@@ -71,19 +71,16 @@ elif [ "$ACTION" = "test" ]; then
|
||||
fi
|
||||
|
||||
elif [ "$ACTION" = "run" ]; then
|
||||
echo "Running Gaze application..."
|
||||
# First ensure we have a built app
|
||||
if [ -d "build/Debug/Gaze.app" ]; then
|
||||
echo "Building and running Gaze application..."
|
||||
# Always build first, then run
|
||||
run_with_output "xcodebuild -project Gaze.xcodeproj -scheme Gaze -configuration Debug build"
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ Build succeeded!"
|
||||
run_with_output "open -a \"Gaze\""
|
||||
else
|
||||
echo "⚠️ No built app found. Building first..."
|
||||
run_with_output "xcodebuild -project Gaze.xcodeproj -scheme Gaze -configuration Debug build"
|
||||
if [ $? -eq 0 ]; then
|
||||
run_with_output "open -a \"Gaze\""
|
||||
else
|
||||
echo "❌ Build failed during run attempt!"
|
||||
exit 1
|
||||
fi
|
||||
echo "❌ Build failed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user