From 97cbfebb9f1d0385d6d1163cf8eeaf6845a579ae Mon Sep 17 00:00:00 2001 From: Michael Freno Date: Fri, 9 Jan 2026 23:25:13 -0500 Subject: [PATCH] general: continued refinements --- Gaze/Views/Onboarding/LookAwaySetupView.swift | 6 +- .../Onboarding/OnboardingContainerView.swift | 2 +- .../Onboarding/SettingsOnboardingView.swift | 46 ++++++++++-- Gaze/Views/Onboarding/UserTimersView.swift | 71 +++++++++++-------- Gaze/Views/SettingsWindowView.swift | 2 +- 5 files changed, 86 insertions(+), 41 deletions(-) diff --git a/Gaze/Views/Onboarding/LookAwaySetupView.swift b/Gaze/Views/Onboarding/LookAwaySetupView.swift index ce284d0..35a4f43 100644 --- a/Gaze/Views/Onboarding/LookAwaySetupView.swift +++ b/Gaze/Views/Onboarding/LookAwaySetupView.swift @@ -34,7 +34,7 @@ struct LookAwaySetupView: View { // Vertically centered content Spacer() - + VStack(spacing: 30) { // InfoBox with link functionality HStack(spacing: 12) { @@ -74,7 +74,7 @@ struct LookAwaySetupView: View { value: Binding( get: { Double(intervalMinutes) }, set: { intervalMinutes = Int($0) } - ), in: 5...60, step: 5) + ), in: 5...90, step: 5) Text("\(intervalMinutes) min") .frame(width: 60, alignment: .trailing) @@ -117,7 +117,7 @@ struct LookAwaySetupView: View { .foregroundColor(.secondary) } } - + Spacer() } .frame(maxWidth: .infinity, maxHeight: .infinity) diff --git a/Gaze/Views/Onboarding/OnboardingContainerView.swift b/Gaze/Views/Onboarding/OnboardingContainerView.swift index 92e8688..56600c3 100644 --- a/Gaze/Views/Onboarding/OnboardingContainerView.swift +++ b/Gaze/Views/Onboarding/OnboardingContainerView.swift @@ -138,7 +138,7 @@ struct OnboardingContainerView: View { } } } - .frame(minWidth: 1000, minHeight: 750) + .frame(minWidth: 1000, minHeight: 800) .opacity(isAnimatingOut ? 0 : 1) .scaleEffect(isAnimatingOut ? 0.3 : 1.0) } diff --git a/Gaze/Views/Onboarding/SettingsOnboardingView.swift b/Gaze/Views/Onboarding/SettingsOnboardingView.swift index 863f505..fc6f1f3 100644 --- a/Gaze/Views/Onboarding/SettingsOnboardingView.swift +++ b/Gaze/Views/Onboarding/SettingsOnboardingView.swift @@ -25,7 +25,6 @@ struct SettingsOnboardingView: View { .padding(.top, 20) .padding(.bottom, 30) - // Vertically centered content Spacer() VStack(spacing: 30) { Text("Configure app preferences and support the project") @@ -34,7 +33,6 @@ struct SettingsOnboardingView: View { .multilineTextAlignment(.center) VStack(spacing: 20) { - // Launch at Login Toggle HStack { VStack(alignment: .leading, spacing: 4) { Text("Launch at Login") @@ -62,13 +60,41 @@ struct SettingsOnboardingView: View { .font(.caption) .foregroundColor(.secondary) - Picker("Size", selection: $subtleReminderSize) { + HStack(spacing: 12) { ForEach(ReminderSize.allCases, id: \.self) { size in - Text(size.displayName).tag(size) + Button(action: { + subtleReminderSize = size + }) { + VStack(spacing: 8) { + Circle() + .fill( + subtleReminderSize == size + ? Color.accentColor + : Color.secondary.opacity(0.3) + ) + .frame( + width: iconSize(for: size), + height: iconSize(for: size)) + + Text(size.displayName) + .font(.caption) + .fontWeight( + subtleReminderSize == size ? .semibold : .regular + ) + .foregroundColor( + subtleReminderSize == size ? .primary : .secondary) + } + .frame(maxWidth: .infinity, minHeight: 60) + .padding(.vertical, 12) + } + .glassEffect( + subtleReminderSize == size + ? .regular.tint(.accentColor.opacity(0.3)) + : .regular, + in: .rect(cornerRadius: 10) + ) } } - .pickerStyle(.segmented) - .labelsHidden() } .padding() .glassEffect(.regular, in: .rect(cornerRadius: 12)) @@ -158,6 +184,14 @@ struct SettingsOnboardingView: View { print("Failed to set launch at login: \(error)") } } + + private func iconSize(for size: ReminderSize) -> CGFloat { + switch size { + case .small: return 20 + case .medium: return 32 + case .large: return 48 + } + } } #Preview("Settings Onboarding - Launch Disabled") { diff --git a/Gaze/Views/Onboarding/UserTimersView.swift b/Gaze/Views/Onboarding/UserTimersView.swift index 697e0a4..f4dc6a7 100644 --- a/Gaze/Views/Onboarding/UserTimersView.swift +++ b/Gaze/Views/Onboarding/UserTimersView.swift @@ -74,7 +74,8 @@ struct UserTimersView: View { } else { ScrollView { VStack(spacing: 8) { - ForEach(Array(userTimers.enumerated()), id: \.element.id) { index, timer in + ForEach(Array(userTimers.enumerated()), id: \.element.id) { + index, timer in UserTimerRow( timer: $userTimers[index], onEdit: { @@ -144,7 +145,7 @@ struct UserTimerRow: View { Circle() .fill(timer.color) .frame(width: 12, height: 12) - + Image(systemName: timer.type == .subtle ? "eye.circle" : "rectangle.on.rectangle") .foregroundColor(timer.color) .frame(width: 24) @@ -166,7 +167,7 @@ struct UserTimerRow: View { .labelsHidden() .toggleStyle(.switch) .controlSize(.small) - + Button(action: onEdit) { Image(systemName: "pencil.circle.fill") .font(.title3) @@ -216,11 +217,14 @@ struct UserTimerEditSheet: View { self.onSave = onSave self.onCancel = onCancel - _title = State(initialValue: timer?.title ?? UserTimer.generateTitle(for: existingTimersCount)) + _title = State( + initialValue: timer?.title ?? UserTimer.generateTitle(for: existingTimersCount)) _message = State(initialValue: timer?.message ?? "") _type = State(initialValue: timer?.type ?? .subtle) _timeOnScreen = State(initialValue: timer?.timeOnScreenSeconds ?? 30) - _selectedColorHex = State(initialValue: timer?.colorHex ?? UserTimer.defaultColors[existingTimersCount % UserTimer.defaultColors.count]) + _selectedColorHex = State( + initialValue: timer?.colorHex + ?? UserTimer.defaultColors[existingTimersCount % UserTimer.defaultColors.count]) } var body: some View { @@ -239,12 +243,15 @@ struct UserTimerEditSheet: View { .font(.caption) .foregroundColor(.secondary) } - + VStack(alignment: .leading, spacing: 8) { Text("Color") .font(.headline) - - LazyVGrid(columns: Array(repeating: GridItem(.flexible(), spacing: 12), count: 8), spacing: 12) { + + LazyVGrid( + columns: Array(repeating: GridItem(.flexible(), spacing: 12), count: 8), + spacing: 12 + ) { ForEach(UserTimer.defaultColors, id: \.self) { colorHex in Button(action: { selectedColorHex = colorHex @@ -254,9 +261,13 @@ struct UserTimerEditSheet: View { .frame(width: 32, height: 32) .overlay( Circle() - .strokeBorder(Color.white, lineWidth: selectedColorHex == colorHex ? 3 : 0) + .strokeBorder( + Color.white, + lineWidth: selectedColorHex == colorHex ? 3 : 0) ) - .shadow(color: selectedColorHex == colorHex ? .accentColor : .clear, radius: 4) + .shadow( + color: selectedColorHex == colorHex ? .accentColor : .clear, + radius: 4) } .buttonStyle(.plain) } @@ -264,9 +275,6 @@ struct UserTimerEditSheet: View { } VStack(alignment: .leading, spacing: 8) { - Text("Display Type") - .font(.headline) - Picker("Display Type", selection: $type) { ForEach(UserTimerType.allCases) { timerType in Text(timerType.displayName).tag(timerType) @@ -276,28 +284,30 @@ struct UserTimerEditSheet: View { Text( type == .subtle - ? "Small reminder in corner of screen" + ? "Small reminder at top of screen" : "Full screen reminder with animation" ) .font(.caption) .foregroundColor(.secondary) } - VStack(alignment: .leading, spacing: 8) { - Text("Duration on Screen") - .font(.headline) - HStack { - Slider( - value: Binding( - get: { Double(timeOnScreen) }, - set: { timeOnScreen = Int($0) } - ), - in: 5...120, - step: 5 - ) - Text("\(timeOnScreen)s") - .frame(width: 50, alignment: .trailing) - .monospacedDigit() + if type == .overlay { + VStack(alignment: .leading, spacing: 8) { + Text("Duration on Screen") + .font(.headline) + HStack { + Slider( + value: Binding( + get: { Double(timeOnScreen) }, + set: { timeOnScreen = Int($0) } + ), + in: 5...30, + step: 1 + ) + Text("\(timeOnScreen)s") + .frame(width: 50, alignment: .trailing) + .monospacedDigit() + } } } @@ -347,7 +357,8 @@ struct UserTimerEditSheet: View { UserTimersView( userTimers: .constant([ UserTimer( - id: "1", title: "User Reminder 1", type: .subtle, timeOnScreenSeconds: 30, message: "Take a break", colorHex: "9B59B6"), + id: "1", title: "User Reminder 1", type: .subtle, timeOnScreenSeconds: 30, + message: "Take a break", colorHex: "9B59B6"), UserTimer( id: "2", title: "User Reminder 2", type: .overlay, timeOnScreenSeconds: 60, message: "Stretch your legs", colorHex: "3498DB"), diff --git a/Gaze/Views/SettingsWindowView.swift b/Gaze/Views/SettingsWindowView.swift index 44a13d8..9c89790 100644 --- a/Gaze/Views/SettingsWindowView.swift +++ b/Gaze/Views/SettingsWindowView.swift @@ -109,7 +109,7 @@ struct SettingsWindowView: View { } .padding() } - .frame(minWidth: 700, minHeight: 750) + .frame(minWidth: 750, minHeight: 800) .onReceive( NotificationCenter.default.publisher(for: Notification.Name("SwitchToSettingsTab")) ) { notification in