bit smoother

This commit is contained in:
Michael Freno
2026-02-01 11:29:49 -05:00
parent e0a9d16484
commit fc9ab37841
2 changed files with 51 additions and 45 deletions

View File

@@ -28,10 +28,10 @@ final class EnforceModeCalibrationService: ObservableObject {
private var countdownTimer: Timer? private var countdownTimer: Timer?
private var sampleTimer: Timer? private var sampleTimer: Timer?
private let countdownDuration: TimeInterval = 1.0 private let countdownDuration: TimeInterval = 0.8
private let preCountdownPause: TimeInterval = 0.5 private let preCountdownPause: TimeInterval = 0.8
private let sampleInterval: TimeInterval = 0.1 private let sampleInterval: TimeInterval = 0.02
private let samplesPerTarget = 12 private let samplesPerTarget = 20
private var windowController: NSWindowController? private var windowController: NSWindowController?
func start() { func start() {
@@ -89,6 +89,7 @@ final class EnforceModeCalibrationService: ObservableObject {
switch currentStep { switch currentStep {
case .eyeBox: case .eyeBox:
currentStep = .targets currentStep = .targets
// Start countdown immediately when transitioning to targets to avoid first point duplication
startCountdown() startCountdown()
case .targets: case .targets:
if targetIndex < targets.count - 1 { if targetIndex < targets.count - 1 {
@@ -135,13 +136,17 @@ final class EnforceModeCalibrationService: ObservableObject {
guard let self else { return } guard let self else { return }
Task { @MainActor in Task { @MainActor in
let elapsed = Date().timeIntervalSince(startTime) let elapsed = Date().timeIntervalSince(startTime)
let countdownElapsed = max(0, elapsed - self.preCountdownPause) // Pause before starting the countdown
if elapsed < self.preCountdownPause { if elapsed < self.preCountdownPause {
self.countdownProgress = 1.0 self.countdownProgress = 1.0
return return
} }
// Start the actual countdown after pause
let countdownElapsed = elapsed - self.preCountdownPause
let remaining = max(0, self.countdownDuration - countdownElapsed) let remaining = max(0, self.countdownDuration - countdownElapsed)
self.countdownProgress = remaining / self.countdownDuration self.countdownProgress = remaining / self.countdownDuration
if remaining <= 0 { if remaining <= 0 {
self.stopCountdown() self.stopCountdown()
self.startSampleCollection() self.startSampleCollection()
@@ -153,7 +158,8 @@ final class EnforceModeCalibrationService: ObservableObject {
private func stopCountdown() { private func stopCountdown() {
countdownTimer?.invalidate() countdownTimer?.invalidate()
countdownTimer = nil countdownTimer = nil
countdownProgress = 1.0 // Only reset to 1.0 when actually stopping, not during transitions
// countdownProgress = 1.0
} }
private func startSampleCollection() { private func startSampleCollection() {

View File

@@ -31,48 +31,47 @@ struct EnforceModeCalibrationOverlayView: View {
private var eyeBoxStep: some View { private var eyeBoxStep: some View {
ZStack { ZStack {
VStack(spacing: 16) { VStack(spacing: 20) {
Text("Adjust Eye Box") VStack(spacing: 16) {
.font(.title2) Text("Adjust Eye Box")
.foregroundStyle(.white) .font(.title2)
.foregroundStyle(.white)
Text( Text(
"Use the sliders to fit the boxes around your eyes. It need not be perfect." "Use the sliders to fit the boxes around your eyes. It need not be perfect."
) )
.font(.callout) .font(.callout)
.multilineTextAlignment(.center) .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)
.foregroundStyle(.white.opacity(0.8)) .foregroundStyle(.white.opacity(0.8))
Slider( }
value: $settingsManager.settings.enforceModeEyeBoxWidthFactor, .padding(.horizontal, 40)
in: 0.12...0.25 .frame(maxWidth: 520)
) .frame(maxWidth: .infinity, alignment: .top)
Text("Height") VStack(alignment: .leading, spacing: 12) {
.font(.caption) Text("Width")
.foregroundStyle(.white.opacity(0.8)) .font(.caption)
Slider( .foregroundStyle(.white.opacity(0.8))
value: $settingsManager.settings.enforceModeEyeBoxHeightFactor, Slider(
in: 0.01...0.10 value: $settingsManager.settings.enforceModeEyeBoxWidthFactor,
) in: 0.12...0.25
} )
.padding(16)
.background(.black.opacity(0.3)) Text("Height")
.clipShape(RoundedRectangle(cornerRadius: 12)) .font(.caption)
.frame(maxWidth: 420) .foregroundStyle(.white.opacity(0.8))
.frame(maxHeight: .infinity, alignment: .center) 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() Spacer()
HStack(spacing: 12) { HStack(spacing: 12) {
Button("Cancel") { Button("Cancel") {
calibrationService.dismissOverlay() calibrationService.dismissOverlay()
@@ -85,8 +84,8 @@ struct EnforceModeCalibrationOverlayView: View {
} }
.buttonStyle(.borderedProminent) .buttonStyle(.borderedProminent)
} }
.padding(.bottom, 40)
} }
.padding(.bottom, 40)
} }
} }
@@ -130,7 +129,7 @@ struct EnforceModeCalibrationOverlayView: View {
Text("Calibration Complete") Text("Calibration Complete")
.font(.title2) .font(.title2)
.foregroundStyle(.white) .foregroundStyle(.white)
Text("You can close this window and start testing.") Text("Enforce Mode is ready to use.")
.font(.callout) .font(.callout)
.foregroundStyle(.white.opacity(0.8)) .foregroundStyle(.white.opacity(0.8))
@@ -163,6 +162,7 @@ struct EnforceModeCalibrationOverlayView: View {
.animation(.linear(duration: 0.02), value: calibrationService.countdownProgress) .animation(.linear(duration: 0.02), value: calibrationService.countdownProgress)
} }
.position(center) .position(center)
.animation(.easeInOut(duration: 0.3), value: center)
} }
.ignoresSafeArea() .ignoresSafeArea()
} }