general: foregroundColor -> foregroundStyle (will change in future)

This commit is contained in:
Michael Freno
2026-01-16 18:16:04 -05:00
parent c825ce16e2
commit 44445f2fd5
20 changed files with 449 additions and 367 deletions

View File

@@ -34,20 +34,22 @@ struct EyeTrackingCalibrationView: View {
VStack(spacing: 30) {
Image(systemName: "eye.circle.fill")
.font(.system(size: 80))
.foregroundColor(.blue)
.foregroundStyle(.blue)
Text("Eye Tracking Calibration")
.font(.largeTitle)
.foregroundStyle(.white)
.fontWeight(.bold)
Text("This calibration will help improve eye tracking accuracy.")
.font(.title3)
.multilineTextAlignment(.center)
.foregroundColor(.secondary)
.foregroundStyle(.gray)
VStack(alignment: .leading, spacing: 15) {
InstructionRow(icon: "1.circle.fill", text: "Look at each target on the screen")
InstructionRow(icon: "2.circle.fill", text: "Keep your head still, only move your eyes")
InstructionRow(
icon: "2.circle.fill", text: "Keep your head still, only move your eyes")
InstructionRow(icon: "3.circle.fill", text: "Follow the countdown at each position")
InstructionRow(icon: "4.circle.fill", text: "Takes about 30-45 seconds")
}
@@ -57,11 +59,11 @@ struct EyeTrackingCalibrationView: View {
VStack(spacing: 10) {
Text("Last calibration:")
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.gray)
Text(calibrationManager.getCalibrationSummary())
.font(.caption)
.multilineTextAlignment(.center)
.foregroundColor(.secondary)
.foregroundStyle(.gray)
}
.padding(.vertical)
}
@@ -70,6 +72,8 @@ struct EyeTrackingCalibrationView: View {
Button("Cancel") {
dismiss()
}
.foregroundStyle(.white)
.buttonStyle(.plain)
.keyboardShortcut(.escape, modifiers: [])
Button("Start Calibration") {
@@ -113,10 +117,10 @@ struct EyeTrackingCalibrationView: View {
VStack(spacing: 10) {
HStack {
Text("Calibrating...")
.foregroundColor(.white)
.foregroundStyle(.white)
Spacer()
Text(calibrationManager.progressText)
.foregroundColor(.white.opacity(0.7))
.foregroundStyle(.white.opacity(0.7))
}
ProgressView(value: calibrationManager.progress)
@@ -141,7 +145,9 @@ struct EyeTrackingCalibrationView: View {
.stroke(Color.blue.opacity(0.3), lineWidth: 3)
.frame(width: 100, height: 100)
.scaleEffect(isCountingDown ? 1.2 : 1.0)
.animation(.easeInOut(duration: 0.6).repeatForever(autoreverses: true), value: isCountingDown)
.animation(
.easeInOut(duration: 0.6).repeatForever(autoreverses: true),
value: isCountingDown)
// Inner circle
Circle()
@@ -152,18 +158,18 @@ struct EyeTrackingCalibrationView: View {
if isCountingDown && countdownValue > 0 {
Text("\(countdownValue)")
.font(.system(size: 36, weight: .bold))
.foregroundColor(.white)
.foregroundStyle(.white)
} else if calibrationManager.samplesCollected > 0 {
Image(systemName: "checkmark")
.font(.system(size: 30, weight: .bold))
.foregroundColor(.white)
.foregroundStyle(.white)
}
}
// Instruction text
Text(step.instructionText)
.font(.title2)
.foregroundColor(.white)
.foregroundStyle(.white)
.padding(.horizontal, 40)
.padding(.vertical, 15)
.background(Color.black.opacity(0.7))
@@ -182,7 +188,7 @@ struct EyeTrackingCalibrationView: View {
calibrationManager.skipStep()
} label: {
Text("Skip this position")
.foregroundColor(.white)
.foregroundStyle(.white)
.padding(.horizontal, 20)
.padding(.vertical, 10)
.background(Color.white.opacity(0.2))
@@ -258,10 +264,11 @@ struct InstructionRow: View {
HStack(spacing: 15) {
Image(systemName: icon)
.font(.title2)
.foregroundColor(.blue)
.foregroundStyle(.blue)
.frame(width: 30)
Text(text)
.foregroundStyle(.white)
.font(.body)
}
}

View File

@@ -28,7 +28,7 @@ struct GazeOverlayView: View {
Text(eyeTrackingService.isInFrame ? "In Frame" : "No Face")
.font(.caption2)
.fontWeight(.semibold)
.foregroundColor(.white)
.foregroundStyle(.white)
}
.padding(.horizontal, 10)
.padding(.vertical, 6)
@@ -46,7 +46,9 @@ struct GazeOverlayView: View {
ForEach(0..<3, id: \.self) { row in
HStack(spacing: 2) {
ForEach(0..<3, id: \.self) { col in
let isActive = currentPos.x == col && currentPos.y == row && eyeTrackingService.isInFrame
let isActive =
currentPos.x == col && currentPos.y == row
&& eyeTrackingService.isInFrame
gridCell(row: row, col: col, isActive: isActive)
}
}
@@ -68,7 +70,7 @@ struct GazeOverlayView: View {
Text(direction.rawValue)
.font(.system(size: 14, weight: .bold))
.foregroundColor(isActive ? .white : .white.opacity(0.6))
.foregroundStyle(isActive ? .white : .white.opacity(0.6))
}
.frame(width: 28, height: 28)
}
@@ -95,12 +97,12 @@ struct GazeOverlayView: View {
if let leftH = eyeTrackingService.debugLeftPupilRatio {
Text("L.H: \(String(format: "%.2f", leftH))")
.font(.system(size: 9, weight: .medium, design: .monospaced))
.foregroundColor(.white)
.foregroundStyle(.white)
}
if let rightH = eyeTrackingService.debugRightPupilRatio {
Text("R.H: \(String(format: "%.2f", rightH))")
.font(.system(size: 9, weight: .medium, design: .monospaced))
.foregroundColor(.white)
.foregroundStyle(.white)
}
}
@@ -108,12 +110,12 @@ struct GazeOverlayView: View {
if let leftV = eyeTrackingService.debugLeftVerticalRatio {
Text("L.V: \(String(format: "%.2f", leftV))")
.font(.system(size: 9, weight: .medium, design: .monospaced))
.foregroundColor(.white)
.foregroundStyle(.white)
}
if let rightV = eyeTrackingService.debugRightVerticalRatio {
Text("R.V: \(String(format: "%.2f", rightV))")
.font(.system(size: 9, weight: .medium, design: .monospaced))
.foregroundColor(.white)
.foregroundStyle(.white)
}
}
@@ -121,12 +123,13 @@ struct GazeOverlayView: View {
if let leftH = eyeTrackingService.debugLeftPupilRatio,
let rightH = eyeTrackingService.debugRightPupilRatio,
let leftV = eyeTrackingService.debugLeftVerticalRatio,
let rightV = eyeTrackingService.debugRightVerticalRatio {
let rightV = eyeTrackingService.debugRightVerticalRatio
{
let avgH = (leftH + rightH) / 2.0
let avgV = (leftV + rightV) / 2.0
Text("Avg H:\(String(format: "%.2f", avgH)) V:\(String(format: "%.2f", avgV))")
.font(.system(size: 9, weight: .bold, design: .monospaced))
.foregroundColor(.yellow)
.foregroundStyle(.yellow)
}
}
.padding(.horizontal, 8)
@@ -143,7 +146,7 @@ struct GazeOverlayView: View {
VStack(spacing: 4) {
Text("Left")
.font(.system(size: 8, weight: .bold))
.foregroundColor(.white)
.foregroundStyle(.white)
HStack(spacing: 4) {
eyeImageView(
@@ -165,7 +168,7 @@ struct GazeOverlayView: View {
VStack(spacing: 4) {
Text("Right")
.font(.system(size: 8, weight: .bold))
.foregroundColor(.white)
.foregroundStyle(.white)
HStack(spacing: 4) {
eyeImageView(
@@ -190,7 +193,9 @@ struct GazeOverlayView: View {
)
}
private func eyeImageView(image: NSImage?, pupilPosition: PupilPosition?, eyeSize: CGSize?, label: String) -> some View {
private func eyeImageView(
image: NSImage?, pupilPosition: PupilPosition?, eyeSize: CGSize?, label: String
) -> some View {
let displaySize: CGFloat = 50
return VStack(spacing: 2) {
@@ -203,7 +208,9 @@ struct GazeOverlayView: View {
.frame(width: displaySize, height: displaySize)
// Draw pupil position marker
if let pupil = pupilPosition, let size = eyeSize, size.width > 0, size.height > 0 {
if let pupil = pupilPosition, let size = eyeSize, size.width > 0,
size.height > 0
{
let scaleX = displaySize / size.width
let scaleY = displaySize / size.height
let scale = min(scaleX, scaleY)
@@ -224,7 +231,7 @@ struct GazeOverlayView: View {
.frame(width: displaySize, height: displaySize)
Text("--")
.font(.system(size: 10))
.foregroundColor(.white.opacity(0.5))
.foregroundStyle(.white.opacity(0.5))
}
}
.frame(width: displaySize, height: displaySize)
@@ -232,7 +239,7 @@ struct GazeOverlayView: View {
Text(label)
.font(.system(size: 7))
.foregroundColor(.white.opacity(0.7))
.foregroundStyle(.white.opacity(0.7))
}
}
}

View File

@@ -22,15 +22,15 @@ struct InfoBox: View {
#endif
}) {
Image(systemName: "info.circle")
.foregroundColor(.white)
.foregroundStyle(.white)
}.buttonStyle(.plain)
} else {
Image(systemName: "info.circle")
.foregroundColor(.white)
.foregroundStyle(.white)
}
Text(text)
.font(.headline)
.foregroundColor(.white)
.foregroundStyle(.white)
}
.padding()
.glassEffectIfAvailable(GlassStyle.regular.tint(.accentColor), in: .rect(cornerRadius: 8))
@@ -38,6 +38,10 @@ struct InfoBox: View {
}
#Preview {
InfoBox(text: "This is an informational message that provides helpful context to the user.", url: "https://www.healthline.com/health/eye-health/20-20-20-rule")
InfoBox(
text: "This is an informational message that provides helpful context to the user.",
url: "https://www.healthline.com/health/eye-health/20-20-20-rule"
)
.padding()
}

View File

@@ -20,7 +20,8 @@ struct PupilOverlayView: View {
// Left eye
if let leftRegion = eyeTrackingService.debugLeftEyeRegion,
let leftPupil = eyeTrackingService.debugLeftPupilPosition,
let imageSize = eyeTrackingService.debugImageSize {
let imageSize = eyeTrackingService.debugImageSize
{
EyeOverlayShape(
eyeRegion: leftRegion,
pupilPosition: leftPupil,
@@ -34,7 +35,8 @@ struct PupilOverlayView: View {
// Right eye
if let rightRegion = eyeTrackingService.debugRightEyeRegion,
let rightPupil = eyeTrackingService.debugRightPupilPosition,
let imageSize = eyeTrackingService.debugImageSize {
let imageSize = eyeTrackingService.debugImageSize
{
EyeOverlayShape(
eyeRegion: rightRegion,
pupilPosition: rightPupil,
@@ -160,14 +162,14 @@ private struct EyeOverlayShape: View {
// Label
Text(label)
.font(.system(size: 10, weight: .bold))
.foregroundColor(color)
.foregroundStyle(color)
.position(x: eyeRect.minX + 8, y: eyeRect.minY - 8)
// Debug: Show raw coordinates
Text("\(label): (\(Int(pupilPosition.x)), \(Int(pupilPosition.y)))")
.font(.system(size: 8, design: .monospaced))
.foregroundColor(.white)
.background(Color.black.opacity(0.7))
.foregroundStyle(.white)
.background(.black.opacity(0.7))
.position(x: eyeRect.midX, y: eyeRect.maxY + 10)
}
}

View File

@@ -16,7 +16,7 @@ struct SetupHeader: View {
VStack(spacing: 16) {
Image(systemName: icon)
.font(.system(size: 60))
.foregroundColor(color)
.foregroundStyle(color)
Text(title)
.font(.system(size: 28, weight: .bold))
}

View File

@@ -42,7 +42,7 @@ struct SliderSection: View {
VStack(alignment: .leading, spacing: 12) {
Text("Remind me every:")
.font(.subheadline)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
HStack {
Slider(
value: Binding(
@@ -62,7 +62,7 @@ struct SliderSection: View {
if let range = countdownSettings.range {
Text("Look away for:")
.font(.subheadline)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
HStack {
Slider(
value: Binding(
@@ -89,14 +89,14 @@ struct SliderSection: View {
reminderText
)
.font(.subheadline)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
.multilineTextAlignment(.center)
} else {
Text(
"\(type) reminders are currently disabled."
)
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
Button(action: {
@@ -104,10 +104,10 @@ struct SliderSection: View {
}) {
HStack(spacing: 8) {
Image(systemName: "eye")
.foregroundColor(.white)
.foregroundStyle(.white)
Text("Preview Reminder")
.font(.headline)
.foregroundColor(.white)
.foregroundStyle(.white)
}
.padding(.horizontal, 16)
.padding(.vertical, 10)

View File

@@ -90,7 +90,8 @@ final class OnboardingWindowPresenter {
self?.windowController = nil
self?.removeCloseObserver()
}
NotificationCenter.default.post(name: Notification.Name("OnboardingWindowDidClose"), object: nil)
NotificationCenter.default.post(
name: Notification.Name("OnboardingWindowDidClose"), object: nil)
}
}
@@ -159,11 +160,12 @@ struct OnboardingContainerView: View {
}
.font(.headline)
.frame(minWidth: 100, maxWidth: .infinity, minHeight: 44, maxHeight: 44)
.foregroundColor(.primary)
.foregroundStyle(.primary)
.contentShape(RoundedRectangle(cornerRadius: 10))
}
.buttonStyle(.plain)
.glassEffectIfAvailable(GlassStyle.regular.interactive(), in: .rect(cornerRadius: 10))
.glassEffectIfAvailable(
GlassStyle.regular.interactive(), in: .rect(cornerRadius: 10))
}
Button(action: {
@@ -173,10 +175,13 @@ struct OnboardingContainerView: View {
currentPage += 1
}
}) {
Text(currentPage == 0 ? "Let's Get Started" : currentPage == 5 ? "Get Started" : "Continue")
Text(
currentPage == 0
? "Let's Get Started" : currentPage == 5 ? "Get Started" : "Continue"
)
.font(.headline)
.frame(minWidth: 100, maxWidth: .infinity, minHeight: 44, maxHeight: 44)
.foregroundColor(.white)
.foregroundStyle(.white)
.contentShape(RoundedRectangle(cornerRadius: 10))
}
.buttonStyle(.plain)

View File

@@ -50,7 +50,7 @@ struct MenuBarHoverButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.foregroundColor(isHovered ? .white : .primary)
.foregroundStyle(isHovered ? .white : .primary)
.glassEffectIfAvailable(
isHovered
? GlassStyle.regular.tint(.accentColor).interactive()
@@ -83,7 +83,7 @@ struct MenuBarContentView: View {
VStack(alignment: .leading, spacing: 12) {
Text("Active Timers")
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
.padding(.horizontal)
.padding(.top, 8)
@@ -176,7 +176,7 @@ struct MenuBarContentView: View {
}) {
HStack {
Image(systemName: "checkmark.circle.fill")
.foregroundColor(.accentColor)
.foregroundStyle(Color.accentColor)
Text("Complete Onboarding")
Spacer()
}
@@ -193,7 +193,7 @@ struct MenuBarContentView: View {
Button(action: onQuit) {
HStack {
Image(systemName: "power")
.foregroundColor(.red)
.foregroundStyle(.red)
Text("Quit Gaze")
Spacer()
}
@@ -207,7 +207,7 @@ struct MenuBarContentView: View {
"v\(Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "0.0.0")"
)
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
.padding(.horizontal, 8)
.padding(.vertical, 4)
@@ -335,20 +335,20 @@ struct TimerStatusRowWithIndividualControls: View {
}
Image(systemName: iconName)
.foregroundColor(isHoveredBody ? .white : color)
.foregroundStyle(isHoveredBody ? .white : color)
.frame(width: 20)
VStack(alignment: .leading, spacing: 2) {
Text(displayName)
.font(.subheadline)
.fontWeight(.medium)
.foregroundColor(isHoveredBody ? .white : .primary)
.foregroundStyle(isHoveredBody ? .white : .primary)
.lineLimit(1)
if let state = state {
Text(state.remainingSeconds.asTimerDuration)
.font(.caption)
.foregroundColor(isHoveredBody ? .white.opacity(0.8) : .secondary)
.foregroundStyle(isHoveredBody ? .white.opacity(0.8) : .secondary)
.monospacedDigit()
}
}
@@ -365,7 +365,7 @@ struct TimerStatusRowWithIndividualControls: View {
Button(action: onDevTrigger) {
Image(systemName: "bolt.fill")
.font(.caption)
.foregroundColor(isHoveredDevTrigger ? .white : .yellow)
.foregroundStyle(isHoveredDevTrigger ? .white : .yellow)
.padding(6)
.contentShape(Circle())
}
@@ -394,7 +394,7 @@ struct TimerStatusRowWithIndividualControls: View {
systemName: isPaused ? "play.circle" : "pause.circle"
)
.font(.caption)
.foregroundColor(isHoveredPauseButton ? .white : .accentColor)
.foregroundStyle(isHoveredPauseButton ? .white : .accentColor)
.padding(6)
.contentShape(Circle())
}
@@ -416,7 +416,7 @@ struct TimerStatusRowWithIndividualControls: View {
Button(action: onSkip) {
Image(systemName: "forward.fill")
.font(.caption)
.foregroundColor(isHoveredSkip ? .white : .accentColor)
.foregroundStyle(isHoveredSkip ? .white : .accentColor)
.padding(6)
.contentShape(Circle())
}

View File

@@ -33,11 +33,11 @@ struct LookAwayReminderView: View {
VStack(spacing: 40) {
Text("Look Away")
.font(.system(size: 64, weight: .bold))
.foregroundColor(.white)
.foregroundStyle(.white)
Text("Look at something 20 feet away")
.font(.system(size: 28))
.foregroundColor(.white.opacity(0.9))
.foregroundStyle(.white.opacity(0.9))
GazeLottieView(
animationName: AnimationAsset.lookAway.fileName,
@@ -62,14 +62,14 @@ struct LookAwayReminderView: View {
Text("\(remainingSeconds)")
.font(.system(size: 48, weight: .bold))
.foregroundColor(.white)
.foregroundStyle(.white)
.monospacedDigit()
.accessibilityIdentifier(AccessibilityIdentifiers.Reminders.countdownLabel)
}
Text("Press ESC or Space to skip")
.font(.subheadline)
.foregroundColor(.white.opacity(0.6))
.foregroundStyle(.white.opacity(0.6))
}
// Skip button in corner
@@ -79,7 +79,7 @@ struct LookAwayReminderView: View {
Button(action: dismiss) {
Image(systemName: "xmark.circle.fill")
.font(.system(size: 32))
.foregroundColor(.white.opacity(0.7))
.foregroundStyle(.white.opacity(0.7))
}
.buttonStyle(.plain)
.accessibilityIdentifier(AccessibilityIdentifiers.Reminders.dismissButton)

View File

@@ -22,7 +22,7 @@ struct PostureReminderView: View {
VStack {
Image(systemName: "arrow.up.circle.fill")
.font(.system(size: scale))
.foregroundColor(.accentColor)
.foregroundStyle(Color.accentColor)
}
.opacity(opacity)
.offset(y: yOffset)

View File

@@ -32,19 +32,19 @@ struct UserTimerOverlayReminderView: View {
VStack(spacing: 40) {
Text(timer.title)
.font(.system(size: 64, weight: .bold))
.foregroundColor(.white)
.foregroundStyle(.white)
if let message = timer.message, !message.isEmpty {
Text(message)
.font(.system(size: 28))
.foregroundColor(.white.opacity(0.9))
.foregroundStyle(.white.opacity(0.9))
.multilineTextAlignment(.center)
.padding(.horizontal, 40)
}
Image(systemName: "clock.fill")
.font(.system(size: 120))
.foregroundColor(timer.color)
.foregroundStyle(timer.color)
.padding(.vertical, 30)
// Countdown display
@@ -62,13 +62,13 @@ struct UserTimerOverlayReminderView: View {
Text("\(remainingSeconds)")
.font(.system(size: 48, weight: .bold))
.foregroundColor(.white)
.foregroundStyle(.white)
.monospacedDigit()
}
Text("Press ESC or Space to dismiss")
.font(.subheadline)
.foregroundColor(.white.opacity(0.6))
.foregroundStyle(.white.opacity(0.6))
}
// Dismiss button in corner
@@ -78,7 +78,7 @@ struct UserTimerOverlayReminderView: View {
Button(action: dismiss) {
Image(systemName: "xmark.circle.fill")
.font(.system(size: 32))
.foregroundColor(.white.opacity(0.7))
.foregroundStyle(.white.opacity(0.7))
}
.buttonStyle(.plain)
.padding(30)

View File

@@ -27,12 +27,12 @@ struct UserTimerReminderView: View {
VStack(spacing: 12) {
Image(systemName: "clock.fill")
.font(.system(size: baseSize * 0.4))
.foregroundColor(timer.color)
.foregroundStyle(timer.color)
if let message = timer.message, !message.isEmpty {
Text(message)
.font(.system(size: baseSize * 0.24))
.foregroundColor(.primary)
.foregroundStyle(.primary)
.multilineTextAlignment(.center)
.lineLimit(2)
}

View File

@@ -21,43 +21,60 @@ struct BlinkSetupView: View {
VStack(spacing: 30) {
HStack(spacing: 12) {
Button(action: {
if let url = URL(string: "https://www.aao.org/eye-health/tips-prevention/computer-usage#:~:text=Humans normally blink about 15 times in one minute. However, studies show that we only blink about 5 to 7 times in a minute while using computers and other digital screen devices.") {
if let url = URL(
string:
"https://www.aao.org/eye-health/tips-prevention/computer-usage#:~:text=Humans normally blink about 15 times in one minute. However, studies show that we only blink about 5 to 7 times in a minute while using computers and other digital screen devices."
) {
NSWorkspace.shared.open(url)
}
}) {
Image(systemName: "info.circle")
.foregroundColor(.white)
.foregroundStyle(.white)
}
.buttonStyle(.plain)
Text("We blink much less when focusing on screens. Regular blink reminders help prevent dry eyes.")
Text(
"We blink much less when focusing on screens. Regular blink reminders help prevent dry eyes."
)
.font(.headline)
.foregroundColor(.white)
.foregroundStyle(.white)
}
.padding()
.glassEffectIfAvailable(GlassStyle.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: $settingsManager.settings.blinkTimer.enabled)
Toggle(
"Enable Blink Reminders", isOn: $settingsManager.settings.blinkTimer.enabled
)
.font(.headline)
if settingsManager.settings.blinkTimer.enabled {
VStack(alignment: .leading, spacing: 12) {
Text("Remind me every:")
.font(.subheadline)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
HStack {
Slider(
value: Binding(
get: { Double(settingsManager.settings.blinkTimer.intervalSeconds / 60) },
set: { settingsManager.settings.blinkTimer.intervalSeconds = Int($0) * 60 }
get: {
Double(
settingsManager.settings.blinkTimer.intervalSeconds
/ 60)
},
set: {
settingsManager.settings.blinkTimer.intervalSeconds =
Int($0) * 60
}
),
in: 1...20,
step: 1
)
Text("\(settingsManager.settings.blinkTimer.intervalSeconds / 60) min")
Text(
"\(settingsManager.settings.blinkTimer.intervalSeconds / 60) min"
)
.frame(width: 60, alignment: .trailing)
.monospacedDigit()
}
@@ -68,29 +85,33 @@ struct BlinkSetupView: View {
.glassEffectIfAvailable(GlassStyle.regular, in: .rect(cornerRadius: 12))
if settingsManager.settings.blinkTimer.enabled {
Text("You will be subtly reminded every \(settingsManager.settings.blinkTimer.intervalSeconds / 60) minutes to blink")
Text(
"You will be subtly reminded every \(settingsManager.settings.blinkTimer.intervalSeconds / 60) minutes to blink"
)
.font(.subheadline)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
} else {
Text("Blink reminders are currently disabled.")
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
Button(action: showPreviewWindow) {
HStack(spacing: 8) {
Image(systemName: "eye")
.foregroundColor(.white)
.foregroundStyle(.white)
Text("Preview Reminder")
.font(.headline)
.foregroundColor(.white)
.foregroundStyle(.white)
}
.padding(.horizontal, 16)
.padding(.vertical, 10)
.contentShape(RoundedRectangle(cornerRadius: 10))
}
.buttonStyle(.plain)
.glassEffectIfAvailable(GlassStyle.regular.tint(.accentColor).interactive(), in: .rect(cornerRadius: 10))
.glassEffectIfAvailable(
GlassStyle.regular.tint(.accentColor).interactive(), in: .rect(cornerRadius: 10)
)
}
Spacer()
@@ -104,7 +125,9 @@ struct BlinkSetupView: View {
guard let screen = NSScreen.main else { return }
previewWindowController = PreviewWindowHelper.showPreview(
on: screen,
content: BlinkReminderView(sizePercentage: settingsManager.settings.subtleReminderSize.percentage) { [weak previewWindowController] in
content: BlinkReminderView(
sizePercentage: settingsManager.settings.subtleReminderSize.percentage
) { [weak previewWindowController] in
previewWindowController?.window?.close()
}
)

View File

@@ -14,14 +14,14 @@ struct CompletionView: View {
Image(systemName: "checkmark.circle.fill")
.font(.system(size: 80))
.foregroundColor(.green)
.foregroundStyle(.green)
Text("You're All Set!")
.font(.system(size: 36, weight: .bold))
Text("Gaze will now help you take care of your eyes and posture")
.font(.title3)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
.multilineTextAlignment(.center)
.padding(.horizontal, 40)
@@ -32,7 +32,7 @@ struct CompletionView: View {
HStack(spacing: 16) {
Image(systemName: "menubar.rectangle")
.foregroundColor(.accentColor)
.foregroundStyle(Color.accentColor)
.frame(width: 30)
Text("Gaze will appear in your menu bar")
.font(.subheadline)
@@ -41,7 +41,7 @@ struct CompletionView: View {
HStack(spacing: 16) {
Image(systemName: "clock")
.foregroundColor(.accentColor)
.foregroundStyle(Color.accentColor)
.frame(width: 30)
Text("Timers will start automatically")
.font(.subheadline)
@@ -50,7 +50,7 @@ struct CompletionView: View {
HStack(spacing: 16) {
Image(systemName: "gearshape")
.foregroundColor(.accentColor)
.foregroundStyle(Color.accentColor)
.frame(width: 30)
Text("Adjust settings anytime from the menu bar")
.font(.subheadline)
@@ -59,7 +59,7 @@ struct CompletionView: View {
HStack(spacing: 16) {
Image(systemName: "plus.circle")
.foregroundColor(.accentColor)
.foregroundStyle(Color.accentColor)
.frame(width: 30)
Text("Create custom timers in Settings for additional reminders")
.font(.subheadline)

View File

@@ -6,8 +6,8 @@
//
import AVFoundation
import SwiftUI
import Foundation
import SwiftUI
struct EnforceModeSetupView: View {
@Bindable var settingsManager: SettingsManager
@@ -33,7 +33,7 @@ struct EnforceModeSetupView: View {
VStack(spacing: 30) {
Text("Use your camera to ensure you take breaks")
.font(.title3)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
.multilineTextAlignment(.center)
VStack(spacing: 20) {
@@ -43,7 +43,7 @@ struct EnforceModeSetupView: View {
.font(.headline)
Text("Camera activates 3 seconds before lookaway reminders")
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
Spacer()
Toggle(
@@ -149,7 +149,7 @@ struct EnforceModeSetupView: View {
HStack {
Image(systemName: "target")
.font(.title3)
.foregroundColor(.blue)
.foregroundStyle(.blue)
Text("Eye Tracking Calibration")
.font(.headline)
}
@@ -158,7 +158,7 @@ struct EnforceModeSetupView: View {
VStack(alignment: .leading, spacing: 8) {
Text(calibrationManager.getCalibrationSummary())
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
if calibrationManager.needsRecalibration() {
Label(
@@ -166,17 +166,17 @@ struct EnforceModeSetupView: View {
systemImage: "exclamationmark.triangle.fill"
)
.font(.caption)
.foregroundColor(.orange)
.foregroundStyle(.orange)
} else {
Label("Calibration active and valid", systemImage: "checkmark.circle.fill")
.font(.caption)
.foregroundColor(.green)
.foregroundStyle(.green)
}
}
} else {
Text("Not calibrated - using default thresholds")
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
Button(action: {
@@ -258,7 +258,7 @@ struct EnforceModeSetupView: View {
/*? " Break compliance detected" : " Please look away from screen"*/
/*)*/
/*.font(.caption)*/
/*.foregroundColor(lookingAway ? .green : .orange)*/
/*.foregroundStyle(lookingAway ? .green : .orange)*/
/*.frame(maxWidth: .infinity, alignment: .center)*/
/*.padding(.top, 4)*/
/*}*/
@@ -277,15 +277,15 @@ struct EnforceModeSetupView: View {
if cameraService.isCameraAuthorized {
Label("Authorized", systemImage: "checkmark.circle.fill")
.font(.caption)
.foregroundColor(.green)
.foregroundStyle(.green)
} else if let error = cameraService.cameraError {
Label(error.localizedDescription, systemImage: "exclamationmark.triangle.fill")
.font(.caption)
.foregroundColor(.orange)
.foregroundStyle(.orange)
} else {
Label("Not authorized", systemImage: "xmark.circle.fill")
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
}
@@ -337,14 +337,14 @@ struct EnforceModeSetupView: View {
HStack {
Image(systemName: "timer")
.font(.title2)
.foregroundColor(.orange)
.foregroundStyle(.orange)
VStack(alignment: .leading, spacing: 4) {
Text("Camera Ready")
.font(.headline)
Text("Will activate 3 seconds before lookaway reminder")
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
Spacer()
@@ -357,11 +357,11 @@ struct EnforceModeSetupView: View {
VStack(spacing: 8) {
Image(systemName: icon)
.font(.title2)
.foregroundColor(isActive ? .green : .secondary)
.foregroundStyle(isActive ? .green : .secondary)
Text(title)
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
.multilineTextAlignment(.center)
}
.frame(maxWidth: .infinity)
@@ -372,7 +372,7 @@ struct EnforceModeSetupView: View {
HStack {
Image(systemName: "lock.shield.fill")
.font(.title3)
.foregroundColor(.blue)
.foregroundStyle(.blue)
Text("Privacy Information")
.font(.headline)
}
@@ -381,11 +381,10 @@ struct EnforceModeSetupView: View {
privacyBullet("All processing happens on-device")
privacyBullet("No images are stored or transmitted")
privacyBullet("Camera only active during lookaway reminders (3 second window)")
privacyBullet("Eyes closed does not affect countdown")
privacyBullet("You can disable at any time")
privacyBullet("You can always force quit with cmd+q")
}
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
.padding()
.glassEffectIfAvailable(
@@ -396,7 +395,7 @@ struct EnforceModeSetupView: View {
HStack(alignment: .top, spacing: 8) {
Image(systemName: "checkmark")
.font(.caption2)
.foregroundColor(.blue)
.foregroundStyle(.blue)
Text(text)
}
}
@@ -442,7 +441,7 @@ struct EnforceModeSetupView: View {
systemName: eyeTrackingService.enableDebugLogging
? "ant.circle.fill" : "ant.circle"
)
.foregroundColor(eyeTrackingService.enableDebugLogging ? .orange : .secondary)
.foregroundStyle(eyeTrackingService.enableDebugLogging ? .orange : .secondary)
}
.buttonStyle(.plain)
.help("Toggle console debug logging")
@@ -461,7 +460,7 @@ struct EnforceModeSetupView: View {
Text("Live Values:")
.font(.caption)
.fontWeight(.semibold)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
if let leftRatio = eyeTrackingService.debugLeftPupilRatio,
let rightRatio = eyeTrackingService.debugRightPupilRatio
@@ -470,23 +469,23 @@ struct EnforceModeSetupView: View {
VStack(alignment: .leading, spacing: 2) {
Text("Left Pupil: \(String(format: "%.3f", leftRatio))")
.font(.caption2)
.foregroundColor(
.foregroundStyle(
!EyeTrackingConstants.minPupilEnabled
&& !EyeTrackingConstants.maxPupilEnabled
? .secondary
: (leftRatio < EyeTrackingConstants.minPupilRatio
|| leftRatio > EyeTrackingConstants.maxPupilRatio)
? .orange : .green
? Color.orange : Color.green
)
Text("Right Pupil: \(String(format: "%.3f", rightRatio))")
.font(.caption2)
.foregroundColor(
.foregroundStyle(
!EyeTrackingConstants.minPupilEnabled
&& !EyeTrackingConstants.maxPupilEnabled
? .secondary
: (rightRatio < EyeTrackingConstants.minPupilRatio
|| rightRatio > EyeTrackingConstants.maxPupilRatio)
? .orange : .green
? Color.orange : Color.green
)
}
@@ -497,7 +496,7 @@ struct EnforceModeSetupView: View {
"Range: \(String(format: "%.2f", EyeTrackingConstants.minPupilRatio)) - \(String(format: "%.2f", EyeTrackingConstants.maxPupilRatio))"
)
.font(.caption2)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
let bothEyesOut =
(leftRatio < EyeTrackingConstants.minPupilRatio
|| leftRatio > EyeTrackingConstants.maxPupilRatio)
@@ -505,13 +504,13 @@ struct EnforceModeSetupView: View {
|| rightRatio > EyeTrackingConstants.maxPupilRatio)
Text(bothEyesOut ? "Both Out ⚠️" : "In Range ✓")
.font(.caption2)
.foregroundColor(bothEyesOut ? .orange : .green)
.foregroundStyle(bothEyesOut ? .orange : .green)
}
}
} else {
Text("Pupil data unavailable")
.font(.caption2)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
if let yaw = eyeTrackingService.debugYaw,
@@ -521,21 +520,21 @@ struct EnforceModeSetupView: View {
VStack(alignment: .leading, spacing: 2) {
Text("Yaw: \(String(format: "%.3f", yaw))")
.font(.caption2)
.foregroundColor(
.foregroundStyle(
!EyeTrackingConstants.yawEnabled
? .secondary
: abs(yaw) > EyeTrackingConstants.yawThreshold
? .orange : .green
? Color.orange : Color.green
)
Text("Pitch: \(String(format: "%.3f", pitch))")
.font(.caption2)
.foregroundColor(
.foregroundStyle(
!EyeTrackingConstants.pitchUpEnabled
&& !EyeTrackingConstants.pitchDownEnabled
? .secondary
: (pitch > EyeTrackingConstants.pitchUpThreshold
|| pitch < EyeTrackingConstants.pitchDownThreshold)
? .orange : .green
? Color.orange : Color.green
)
}
@@ -546,12 +545,12 @@ struct EnforceModeSetupView: View {
"Yaw Max: \(String(format: "%.2f", EyeTrackingConstants.yawThreshold))"
)
.font(.caption2)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
Text(
"Pitch: \(String(format: "%.2f", EyeTrackingConstants.pitchDownThreshold)) to \(String(format: "%.2f", EyeTrackingConstants.pitchUpThreshold))"
)
.font(.caption2)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
}
}
@@ -565,48 +564,54 @@ struct EnforceModeSetupView: View {
Text("Current Threshold Values:")
.font(.caption)
.fontWeight(.semibold)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
HStack {
Text("Yaw Threshold:")
Spacer()
Text("\(String(format: "%.2f", EyeTrackingConstants.yawThreshold)) rad")
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
HStack {
Text("Pitch Up Threshold:")
Spacer()
Text("\(String(format: "%.2f", EyeTrackingConstants.pitchUpThreshold)) rad")
.foregroundColor(.secondary)
Text(
"\(String(format: "%.2f", EyeTrackingConstants.pitchUpThreshold)) rad"
)
.foregroundStyle(.secondary)
}
HStack {
Text("Pitch Down Threshold:")
Spacer()
Text("\(String(format: "%.2f", EyeTrackingConstants.pitchDownThreshold)) rad")
.foregroundColor(.secondary)
Text(
"\(String(format: "%.2f", EyeTrackingConstants.pitchDownThreshold)) rad"
)
.foregroundStyle(.secondary)
}
HStack {
Text("Min Pupil Ratio:")
Spacer()
Text("\(String(format: "%.2f", EyeTrackingConstants.minPupilRatio))")
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
HStack {
Text("Max Pupil Ratio:")
Spacer()
Text("\(String(format: "%.2f", EyeTrackingConstants.maxPupilRatio))")
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
HStack {
Text("Eye Closed Threshold:")
Spacer()
Text("\(String(format: "%.3f", EyeTrackingConstants.eyeClosedThreshold))")
.foregroundColor(.secondary)
Text(
"\(String(format: "%.3f", EyeTrackingConstants.eyeClosedThreshold))"
)
.foregroundStyle(.secondary)
}
}
.padding(.top, 8)
@@ -622,7 +627,7 @@ struct EnforceModeSetupView: View {
VStack(alignment: .leading, spacing: 12) {
Text("Debug Eye Tracking Data")
.font(.headline)
.foregroundColor(.blue)
.foregroundStyle(.blue)
VStack(alignment: .leading, spacing: 8) {
Text("Face Detected: \(eyeTrackingService.faceDetected ? "Yes" : "No")")
@@ -643,7 +648,7 @@ struct EnforceModeSetupView: View {
}
}
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
.padding()
.glassEffectIfAvailable(GlassStyle.regular, in: .rect(cornerRadius: 12))

View File

@@ -14,13 +14,15 @@ struct GeneralSetupView: View {
var body: some View {
VStack(spacing: 0) {
SetupHeader(icon: "gearshape.fill", title: isOnboarding ? "Final Settings" : "General Settings", color: .accentColor)
SetupHeader(
icon: "gearshape.fill", title: isOnboarding ? "Final Settings" : "General Settings",
color: .accentColor)
Spacer()
VStack(spacing: 30) {
Text("Configure app preferences and support the project")
.font(.title3)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
.multilineTextAlignment(.center)
VStack(spacing: 20) {
@@ -51,7 +53,7 @@ struct GeneralSetupView: View {
.font(.headline)
Text("Start Gaze automatically when you log in")
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
Spacer()
Toggle("", isOn: $settingsManager.settings.launchAtLogin)
@@ -74,12 +76,12 @@ struct GeneralSetupView: View {
if let lastCheck = updateManager.lastUpdateCheckDate {
Text("Last checked: \(lastCheck, style: .relative)")
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
.italic()
} else {
Text("Never checked for updates")
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
.italic()
}
}
@@ -91,10 +93,13 @@ struct GeneralSetupView: View {
}
.buttonStyle(.bordered)
Toggle("Automatically check for updates", isOn: Binding(
Toggle(
"Automatically check for updates",
isOn: Binding(
get: { updateManager.automaticallyChecksForUpdates },
set: { updateManager.automaticallyChecksForUpdates = $0 }
))
)
)
.labelsHidden()
.help("Check for new versions of Gaze in the background")
}
@@ -110,20 +115,28 @@ struct GeneralSetupView: View {
Text("Adjust the size of blink and posture reminders")
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
HStack(spacing: 12) {
ForEach(ReminderSize.allCases, id: \.self) { size in
Button(action: { settingsManager.settings.subtleReminderSize = size }) {
VStack(spacing: 8) {
Circle()
.fill(settingsManager.settings.subtleReminderSize == size ? Color.accentColor : Color.secondary.opacity(0.3))
.fill(
settingsManager.settings.subtleReminderSize == size
? Color.accentColor : Color.secondary.opacity(0.3)
)
.frame(width: iconSize(for: size), height: iconSize(for: size))
Text(size.displayName)
.font(.caption)
.fontWeight(settingsManager.settings.subtleReminderSize == size ? .semibold : .regular)
.foregroundColor(settingsManager.settings.subtleReminderSize == size ? .primary : .secondary)
.fontWeight(
settingsManager.settings.subtleReminderSize == size
? .semibold : .regular
)
.foregroundStyle(
settingsManager.settings.subtleReminderSize == size
? .primary : .secondary)
}
.frame(maxWidth: .infinity, minHeight: 60)
.padding(.vertical, 12)
@@ -205,14 +218,14 @@ struct ExternalLinkButton: View {
HStack {
Image(systemName: icon)
.font(.title3)
.foregroundColor(iconColor)
.foregroundStyle(iconColor)
VStack(alignment: .leading, spacing: 2) {
Text(title)
.font(.subheadline)
.fontWeight(.semibold)
Text(subtitle)
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
Spacer()
Image(systemName: "arrow.up.right")
@@ -224,7 +237,8 @@ struct ExternalLinkButton: View {
}
.buttonStyle(.plain)
.glassEffectIfAvailable(
tint != nil ? GlassStyle.regular.tint(tint!).interactive() : GlassStyle.regular.interactive(),
tint != nil
? GlassStyle.regular.tint(tint!).interactive() : GlassStyle.regular.interactive(),
in: .rect(cornerRadius: 10)
)
}

View File

@@ -21,21 +21,27 @@ struct PostureSetupView: View {
VStack(spacing: 30) {
HStack(spacing: 12) {
Button(action: {
if let url = URL(string: "https://pubmed.ncbi.nlm.nih.gov/40111906/#:~:text=For%20studies%20exploring%20sitting%20posture%2C%20seven%20found%20a%20relationship%20with%20LBP.%20Regarding%20studies%20on%20sitting%20behavior%2C%20only%20one%20showed%20no%20relationship%20between%20LBP%20prevalence") {
if let url = URL(
string:
"https://pubmed.ncbi.nlm.nih.gov/40111906/#:~:text=For%20studies%20exploring%20sitting%20posture%2C%20seven%20found%20a%20relationship%20with%20LBP.%20Regarding%20studies%20on%20sitting%20behavior%2C%20only%20one%20showed%20no%20relationship%20between%20LBP%20prevalence"
) {
NSWorkspace.shared.open(url)
}
}) {
Image(systemName: "info.circle")
.foregroundColor(.white)
.foregroundStyle(.white)
}
.buttonStyle(.plain)
Text("Regular posture checks help prevent back and neck pain from prolonged sitting")
Text(
"Regular posture checks help prevent back and neck pain from prolonged sitting"
)
.font(.headline)
.foregroundColor(.white)
.foregroundStyle(.white)
}
.padding()
.glassEffectIfAvailable(GlassStyle.regular.tint(.accentColor), in: .rect(cornerRadius: 8))
.glassEffectIfAvailable(
GlassStyle.regular.tint(.accentColor), in: .rect(cornerRadius: 8))
SliderSection(
intervalSettings: Binding(
@@ -46,7 +52,8 @@ struct PostureSetupView: View {
)
},
set: { newValue in
settingsManager.settings.postureTimer.intervalSeconds = (newValue.val ?? 30) * 60
settingsManager.settings.postureTimer.intervalSeconds =
(newValue.val ?? 30) * 60
}
),
countdownSettings: nil,
@@ -67,7 +74,9 @@ struct PostureSetupView: View {
guard let screen = NSScreen.main else { return }
previewWindowController = PreviewWindowHelper.showPreview(
on: screen,
content: PostureReminderView(sizePercentage: settingsManager.settings.subtleReminderSize.percentage) { [weak previewWindowController] in
content: PostureReminderView(
sizePercentage: settingsManager.settings.subtleReminderSize.percentage
) { [weak previewWindowController] in
previewWindowController?.window?.close()
}
)

View File

@@ -17,7 +17,7 @@ struct SmartModeSetupView: View {
Text("Automatically manage timers based on your activity")
.font(.subheadline)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
.padding(.bottom, 30)
Spacer()
@@ -42,18 +42,21 @@ struct SmartModeSetupView: View {
VStack(alignment: .leading, spacing: 4) {
HStack {
Image(systemName: "arrow.up.left.and.arrow.down.right")
.foregroundColor(.blue)
.foregroundStyle(.blue)
Text("Auto-pause on Fullscreen")
.font(.headline)
}
Text("Timers will automatically pause when you enter fullscreen mode (videos, games, presentations)")
Text(
"Timers will automatically pause when you enter fullscreen mode (videos, games, presentations)"
)
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
Spacer()
Toggle("", isOn: $settingsManager.settings.smartMode.autoPauseOnFullscreen)
.labelsHidden()
.onChange(of: settingsManager.settings.smartMode.autoPauseOnFullscreen) { _, newValue in
.onChange(of: settingsManager.settings.smartMode.autoPauseOnFullscreen) {
_, newValue in
if newValue {
permissionManager.requestAuthorizationIfNeeded()
}
@@ -61,7 +64,8 @@ struct SmartModeSetupView: View {
}
if settingsManager.settings.smartMode.autoPauseOnFullscreen,
permissionManager.authorizationStatus != .authorized {
permissionManager.authorizationStatus != .authorized
{
permissionWarningView
}
}
@@ -81,7 +85,7 @@ struct SmartModeSetupView: View {
Text("macOS requires Screen Recording permission to detect other apps in fullscreen.")
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
HStack {
Button("Grant Access") {
@@ -107,13 +111,13 @@ struct SmartModeSetupView: View {
VStack(alignment: .leading, spacing: 4) {
HStack {
Image(systemName: "moon.zzz.fill")
.foregroundColor(.indigo)
.foregroundStyle(.indigo)
Text("Auto-pause on Idle")
.font(.headline)
}
Text("Timers will pause when you're inactive for more than the threshold below")
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
Spacer()
Toggle("", isOn: $settingsManager.settings.smartMode.autoPauseOnIdle)
@@ -139,13 +143,15 @@ struct SmartModeSetupView: View {
VStack(alignment: .leading, spacing: 4) {
HStack {
Image(systemName: "chart.line.uptrend.xyaxis")
.foregroundColor(.green)
.foregroundStyle(.green)
Text("Track Usage Statistics")
.font(.headline)
}
Text("Monitor active and idle time, with automatic reset after the specified duration")
Text(
"Monitor active and idle time, with automatic reset after the specified duration"
)
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
Spacer()
Toggle("", isOn: $settingsManager.settings.smartMode.trackUsage)
@@ -182,7 +188,7 @@ struct ThresholdSlider: View {
Spacer()
Text("\(value) \(unit)")
.font(.subheadline)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
Slider(

View File

@@ -17,7 +17,7 @@ struct UserTimersView: View {
VStack(spacing: 16) {
Image(systemName: "clock.badge.checkmark")
.font(.system(size: 60))
.foregroundColor(.purple)
.foregroundStyle(.purple)
Text("Custom Timers")
.font(.system(size: 28, weight: .bold))
}
@@ -28,14 +28,14 @@ struct UserTimersView: View {
VStack(spacing: 30) {
Text("Create your own reminder schedules")
.font(.title3)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
HStack(spacing: 12) {
Image(systemName: "info.circle")
.foregroundColor(.white)
.foregroundStyle(.white)
Text("Add up to 3 custom timers with your own intervals and messages")
.font(.headline)
.foregroundColor(.white)
.foregroundStyle(.white)
}
.padding()
.glassEffectIfAvailable(
@@ -66,13 +66,13 @@ struct UserTimersView: View {
VStack(spacing: 12) {
Image(systemName: "clock.badge.questionmark")
.font(.system(size: 40))
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
Text("No custom timers yet")
.font(.subheadline)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
Text("Click 'Add Timer' to create your first custom reminder")
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
.frame(maxWidth: .infinity)
.padding(40)
@@ -153,7 +153,7 @@ struct UserTimerRow: View {
.frame(width: 12, height: 12)
Image(systemName: timer.type == .subtle ? "eye.circle" : "rectangle.on.rectangle")
.foregroundColor(timer.color)
.foregroundStyle(timer.color)
.frame(width: 24)
VStack(alignment: .leading, spacing: 4) {
@@ -165,7 +165,7 @@ struct UserTimerRow: View {
"\(timer.type.displayName)\(timer.timeOnScreenSeconds)s on screen • \(timer.intervalMinutes) min interval"
)
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
Spacer()
@@ -179,14 +179,14 @@ struct UserTimerRow: View {
Button(action: onEdit) {
Image(systemName: "pencil.circle.fill")
.font(.title3)
.foregroundColor(.accentColor)
.foregroundStyle(Color.accentColor)
}
.buttonStyle(.plain)
Button(action: { showingDeleteConfirmation = true }) {
Image(systemName: "trash.circle.fill")
.font(.title3)
.foregroundColor(.red)
.foregroundStyle(.red)
}
.buttonStyle(.plain)
.confirmationDialog("Delete Timer", isPresented: $showingDeleteConfirmation) {
@@ -264,7 +264,7 @@ struct UserTimerEditSheet: View {
.textFieldStyle(.roundedBorder)
Text("Example: \"Stretch Break\", \"Eye Rest\", \"Water Break\"")
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
VStack(alignment: .leading, spacing: 8) {
@@ -318,7 +318,7 @@ struct UserTimerEditSheet: View {
: "Full screen reminder with animation"
)
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
if type == .overlay {
@@ -359,7 +359,7 @@ struct UserTimerEditSheet: View {
}
Text("How often this reminder will appear (in minutes)")
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
VStack(alignment: .leading, spacing: 8) {
@@ -369,7 +369,7 @@ struct UserTimerEditSheet: View {
.textFieldStyle(.roundedBorder)
Text("Leave blank to show a default timer notification")
.font(.caption)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
}
.padding()

View File

@@ -14,14 +14,14 @@ struct WelcomeView: View {
Image(systemName: "eye.fill")
.font(.system(size: 80))
.foregroundColor(.accentColor)
.foregroundStyle(Color.accentColor)
Text("Welcome to Gaze")
.font(.system(size: 36, weight: .bold))
Text("Take care of your eyes and posture")
.font(.title3)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
VStack(alignment: .leading, spacing: 16) {
FeatureRow(
@@ -66,7 +66,7 @@ struct FeatureRow: View {
HStack(alignment: .top, spacing: 16) {
Image(systemName: icon)
.font(.title2)
.foregroundColor(iconColor)
.foregroundStyle(iconColor)
.frame(width: 30)
VStack(alignment: .leading, spacing: 4) {
@@ -74,7 +74,7 @@ struct FeatureRow: View {
.font(.headline)
Text(description)
.font(.subheadline)
.foregroundColor(.secondary)
.foregroundStyle(.secondary)
}
}
}