From fc9ab378410a89b82e4c07af560dea6a61406ef8 Mon Sep 17 00:00:00 2001 From: Michael Freno Date: Sun, 1 Feb 2026 11:29:49 -0500 Subject: [PATCH] bit smoother --- .../EnforceModeCalibrationService.swift | 18 +++-- .../EnforceModeCalibrationOverlayView.swift | 78 +++++++++---------- 2 files changed, 51 insertions(+), 45 deletions(-) diff --git a/Gaze/Services/Calibration/EnforceModeCalibrationService.swift b/Gaze/Services/Calibration/EnforceModeCalibrationService.swift index 5cc51b6..6cdfeae 100644 --- a/Gaze/Services/Calibration/EnforceModeCalibrationService.swift +++ b/Gaze/Services/Calibration/EnforceModeCalibrationService.swift @@ -28,10 +28,10 @@ final class EnforceModeCalibrationService: ObservableObject { private var countdownTimer: Timer? private var sampleTimer: Timer? - private let countdownDuration: TimeInterval = 1.0 - private let preCountdownPause: TimeInterval = 0.5 - private let sampleInterval: TimeInterval = 0.1 - private let samplesPerTarget = 12 + private let countdownDuration: TimeInterval = 0.8 + private let preCountdownPause: TimeInterval = 0.8 + private let sampleInterval: TimeInterval = 0.02 + private let samplesPerTarget = 20 private var windowController: NSWindowController? func start() { @@ -89,6 +89,7 @@ final class EnforceModeCalibrationService: ObservableObject { switch currentStep { case .eyeBox: currentStep = .targets + // Start countdown immediately when transitioning to targets to avoid first point duplication startCountdown() case .targets: if targetIndex < targets.count - 1 { @@ -135,13 +136,17 @@ final class EnforceModeCalibrationService: ObservableObject { guard let self else { return } Task { @MainActor in let elapsed = Date().timeIntervalSince(startTime) - let countdownElapsed = max(0, elapsed - self.preCountdownPause) + // Pause before starting the countdown if elapsed < self.preCountdownPause { self.countdownProgress = 1.0 return } + + // Start the actual countdown after pause + let countdownElapsed = elapsed - self.preCountdownPause let remaining = max(0, self.countdownDuration - countdownElapsed) self.countdownProgress = remaining / self.countdownDuration + if remaining <= 0 { self.stopCountdown() self.startSampleCollection() @@ -153,7 +158,8 @@ final class EnforceModeCalibrationService: ObservableObject { private func stopCountdown() { countdownTimer?.invalidate() countdownTimer = nil - countdownProgress = 1.0 + // Only reset to 1.0 when actually stopping, not during transitions + // countdownProgress = 1.0 } private func startSampleCollection() { diff --git a/Gaze/Views/Components/EnforceModeCalibrationOverlayView.swift b/Gaze/Views/Components/EnforceModeCalibrationOverlayView.swift index 8bb4ce3..b846bb9 100644 --- a/Gaze/Views/Components/EnforceModeCalibrationOverlayView.swift +++ b/Gaze/Views/Components/EnforceModeCalibrationOverlayView.swift @@ -31,48 +31,47 @@ struct EnforceModeCalibrationOverlayView: View { private var eyeBoxStep: some View { ZStack { - VStack(spacing: 16) { - Text("Adjust Eye Box") - .font(.title2) - .foregroundStyle(.white) + VStack(spacing: 20) { + VStack(spacing: 16) { + Text("Adjust Eye Box") + .font(.title2) + .foregroundStyle(.white) - Text( - "Use the sliders to fit the boxes around your eyes. It need not be perfect." - ) - .font(.callout) - .multilineTextAlignment(.center) - .foregroundStyle(.white.opacity(0.8)) - } - .padding(.horizontal, 40) - .padding(.top, 40) - .frame(maxWidth: 520) - .frame(maxWidth: .infinity, alignment: .top) - - VStack(alignment: .leading, spacing: 12) { - Text("Width") - .font(.caption) + Text( + "Use the sliders to fit the boxes around your eyes. It need not be perfect." + ) + .font(.callout) + .multilineTextAlignment(.center) .foregroundStyle(.white.opacity(0.8)) - Slider( - value: $settingsManager.settings.enforceModeEyeBoxWidthFactor, - in: 0.12...0.25 - ) + } + .padding(.horizontal, 40) + .frame(maxWidth: 520) + .frame(maxWidth: .infinity, alignment: .top) - Text("Height") - .font(.caption) - .foregroundStyle(.white.opacity(0.8)) - Slider( - value: $settingsManager.settings.enforceModeEyeBoxHeightFactor, - in: 0.01...0.10 - ) - } - .padding(16) - .background(.black.opacity(0.3)) - .clipShape(RoundedRectangle(cornerRadius: 12)) - .frame(maxWidth: 420) - .frame(maxHeight: .infinity, alignment: .center) + VStack(alignment: .leading, spacing: 12) { + Text("Width") + .font(.caption) + .foregroundStyle(.white.opacity(0.8)) + Slider( + value: $settingsManager.settings.enforceModeEyeBoxWidthFactor, + in: 0.12...0.25 + ) + + Text("Height") + .font(.caption) + .foregroundStyle(.white.opacity(0.8)) + Slider( + value: $settingsManager.settings.enforceModeEyeBoxHeightFactor, + in: 0.01...0.10 + ) + } + .padding(16) + .background(.black.opacity(0.3)) + .clipShape(RoundedRectangle(cornerRadius: 12)) + .frame(maxWidth: 420) - VStack { Spacer() + HStack(spacing: 12) { Button("Cancel") { calibrationService.dismissOverlay() @@ -85,8 +84,8 @@ struct EnforceModeCalibrationOverlayView: View { } .buttonStyle(.borderedProminent) } + .padding(.bottom, 40) } - .padding(.bottom, 40) } } @@ -130,7 +129,7 @@ struct EnforceModeCalibrationOverlayView: View { Text("Calibration Complete") .font(.title2) .foregroundStyle(.white) - Text("You can close this window and start testing.") + Text("Enforce Mode is ready to use.") .font(.callout) .foregroundStyle(.white.opacity(0.8)) @@ -163,6 +162,7 @@ struct EnforceModeCalibrationOverlayView: View { .animation(.linear(duration: 0.02), value: calibrationService.countdownProgress) } .position(center) + .animation(.easeInOut(duration: 0.3), value: center) } .ignoresSafeArea() }