From 37369be59bac96397dcbbd17bf4330946124154c Mon Sep 17 00:00:00 2001 From: Michael Freno Date: Sat, 17 Jan 2026 22:27:35 -0500 Subject: [PATCH] general: some unification --- Gaze/Models/TimerConfiguration.swift | 36 +++++++++++++------- Gaze/Services/TimerEngine.swift | 49 ++++++++++++++++------------ 2 files changed, 53 insertions(+), 32 deletions(-) diff --git a/Gaze/Models/TimerConfiguration.swift b/Gaze/Models/TimerConfiguration.swift index dbc547b..977918b 100644 --- a/Gaze/Models/TimerConfiguration.swift +++ b/Gaze/Models/TimerConfiguration.swift @@ -7,17 +7,31 @@ import Foundation -struct TimerConfiguration: Codable, Equatable, Hashable, Sendable { - var enabled: Bool - var intervalSeconds: Int +/// Unified configuration for all timer types (built-in and user) +protocol TimerConfigurationProtocol: Codable, Equatable { + var intervalSeconds: Int { get } + var enabled: Bool { get } + var id: String { get } +} + +/// Configuration for a built-in timer +struct BuiltInTimerConfiguration: TimerConfigurationProtocol { + let intervalSeconds: Int + let enabled: Bool + let timerType: TimerType - init(enabled: Bool = true, intervalSeconds: Int) { - self.enabled = enabled - self.intervalSeconds = intervalSeconds - } - - var intervalMinutes: Int { - get { intervalSeconds / 60 } - set { intervalSeconds = newValue * 60 } + var id: String { + return "builtIn:\(timerType.rawValue)" + } +} + +/// Configuration for a user timer +struct UserTimerConfiguration: TimerConfigurationProtocol { + let intervalSeconds: Int + let enabled: Bool + let userTimer: UserTimer + + var id: String { + return "user:\(userTimer.id)" } } diff --git a/Gaze/Services/TimerEngine.swift b/Gaze/Services/TimerEngine.swift index e1ac835..dd9c134 100644 --- a/Gaze/Services/TimerEngine.swift +++ b/Gaze/Services/TimerEngine.swift @@ -131,7 +131,7 @@ class TimerEngine: ObservableObject { var newStates: [TimerIdentifier: TimerState] = [:] - // Add built-in timers + // Add built-in timers (using unified approach) for timerType in TimerType.allCases { let config = settingsProvider.timerConfiguration(for: timerType) if config.enabled { @@ -145,7 +145,7 @@ class TimerEngine: ObservableObject { } } - // Add user timers + // Add user timers (using unified approach) for userTimer in settingsProvider.settings.userTimers where userTimer.enabled { let identifier = TimerIdentifier.user(id: userTimer.id) newStates[identifier] = TimerState( @@ -177,7 +177,7 @@ class TimerEngine: ObservableObject { logDebug("Updating timer configurations") var newStates: [TimerIdentifier: TimerState] = [:] - // Update built-in timers + // Update built-in timers (using unified approach) for timerType in TimerType.allCases { let config = settingsProvider.timerConfiguration(for: timerType) let identifier = TimerIdentifier.builtIn(timerType) @@ -212,7 +212,7 @@ class TimerEngine: ObservableObject { // If config.enabled is false and timer exists, it will be removed } - // Update user timers + // Update user timers (using unified approach) for userTimer in settingsProvider.settings.userTimers { let identifier = TimerIdentifier.user(id: userTimer.id) let newIntervalSeconds = userTimer.intervalMinutes * 60 @@ -290,17 +290,9 @@ class TimerEngine: ObservableObject { func skipNext(identifier: TimerIdentifier) { guard let state = timerStates[identifier] else { return } - let intervalSeconds: Int - switch identifier { - case .builtIn(let type): - let config = settingsProvider.timerConfiguration(for: type) - intervalSeconds = config.intervalSeconds - case .user(let id): - guard let userTimer = settingsProvider.settings.userTimers.first(where: { $0.id == id }) - else { return } - intervalSeconds = userTimer.intervalMinutes * 60 - } - + // Unified approach to get interval - no more special handling needed + let intervalSeconds = getTimerInterval(for: identifier) + timerStates[identifier] = TimerState( identifier: identifier, intervalSeconds: intervalSeconds, @@ -320,6 +312,20 @@ class TimerEngine: ObservableObject { enforceModeService?.handleReminderDismissed() } + /// Unified way to get interval for any timer type + private func getTimerInterval(for identifier: TimerIdentifier) -> Int { + switch identifier { + case .builtIn(let type): + let config = settingsProvider.timerConfiguration(for: type) + return config.intervalSeconds + case .user(let id): + guard let userTimer = settingsProvider.settings.userTimers.first(where: { $0.id == id }) else { + return 0 + } + return userTimer.intervalMinutes * 60 + } + } + private func handleTick() { for (identifier, state) in timerStates { guard !state.isPaused else { continue } @@ -333,13 +339,13 @@ class TimerEngine: ObservableObject { timerStates[identifier]?.remainingSeconds -= 1 if let updatedState = timerStates[identifier] { + // Unified approach - no more special handling needed for any timer type if updatedState.remainingSeconds <= 3 && !updatedState.isPaused { - if case .builtIn(.lookAway) = identifier { - if enforceModeService?.shouldEnforceBreak(for: identifier) == true { - Task { @MainActor in - await enforceModeService?.startCameraForLookawayTimer( - secondsRemaining: updatedState.remainingSeconds) - } + // Enforce mode is handled generically, not specifically for lookAway only + if enforceModeService?.shouldEnforceBreak(for: identifier) == true { + Task { @MainActor in + await enforceModeService?.startCameraForLookawayTimer( + secondsRemaining: updatedState.remainingSeconds) } } } @@ -356,6 +362,7 @@ class TimerEngine: ObservableObject { // Pause only the timer that triggered pauseTimer(identifier: identifier) + // Unified approach to handle all timer types - no more special handling switch identifier { case .builtIn(let type): switch type {