Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
parent
442e507519
commit
78ada0862a
37
TheNoiseClock/Core/Utilities/DebugLogger.swift
Normal file
37
TheNoiseClock/Core/Utilities/DebugLogger.swift
Normal file
@ -0,0 +1,37 @@
|
||||
//
|
||||
// DebugLogger.swift
|
||||
// TheNoiseClock
|
||||
//
|
||||
// Created by Matt Bruce on 9/10/25.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Debug logging utility that can be toggled with build settings
|
||||
struct DebugLogger {
|
||||
|
||||
// MARK: - Log Categories
|
||||
enum Category: String, CaseIterable {
|
||||
case brightness = "BRIGHTNESS"
|
||||
case ambient = "AMBIENT"
|
||||
case nightMode = "NIGHTMODE"
|
||||
case timer = "TIMER"
|
||||
case settings = "SETTINGS"
|
||||
case general = "DEBUG"
|
||||
}
|
||||
|
||||
// MARK: - Build Configuration
|
||||
#if DEBUG
|
||||
private static let isDebugEnabled = true
|
||||
#else
|
||||
private static let isDebugEnabled = false
|
||||
#endif
|
||||
|
||||
// MARK: - Logging Methods
|
||||
|
||||
/// Log debug messages (only in DEBUG builds)
|
||||
static func log(_ message: String, category: Category = .general) {
|
||||
guard isDebugEnabled else { return }
|
||||
print("🔍 [\(category.rawValue)] \(message)")
|
||||
}
|
||||
}
|
||||
@ -20,7 +20,7 @@ enum NotificationUtils {
|
||||
)
|
||||
return granted
|
||||
} catch {
|
||||
print("Error requesting notification permissions: \(error)")
|
||||
DebugLogger.log("Error requesting notification permissions: \(error)", category: .general)
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -38,12 +38,12 @@ enum NotificationUtils {
|
||||
|
||||
if soundName == "default" {
|
||||
content.sound = UNNotificationSound.default
|
||||
print("🔔 Using default notification sound")
|
||||
DebugLogger.log("Using default notification sound", category: .settings)
|
||||
} else {
|
||||
// Use the sound name directly since sounds.json now references CAF files
|
||||
content.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: soundName))
|
||||
print("🔔 Using custom alarm sound: \(soundName)")
|
||||
print("🔔 Sound file should be in main bundle: \(soundName)")
|
||||
DebugLogger.log("Using custom alarm sound: \(soundName)", category: .settings)
|
||||
DebugLogger.log("Sound file should be in main bundle: \(soundName)", category: .settings)
|
||||
}
|
||||
|
||||
return content
|
||||
@ -74,7 +74,7 @@ enum NotificationUtils {
|
||||
try await UNUserNotificationCenter.current().add(request)
|
||||
return true
|
||||
} catch {
|
||||
print("Error scheduling notification: \(error)")
|
||||
DebugLogger.log("Error scheduling notification: \(error)", category: .general)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,16 +319,20 @@ class ClockStyle: Codable, Equatable {
|
||||
/// Get the effective brightness considering color theme and night mode
|
||||
var effectiveBrightness: Double {
|
||||
if !autoBrightness {
|
||||
DebugLogger.log("effectiveBrightness: Auto-brightness disabled, returning 1.0", category: .brightness)
|
||||
return 1.0 // Full brightness when auto-brightness is disabled
|
||||
}
|
||||
|
||||
if isNightModeActive {
|
||||
DebugLogger.log("effectiveBrightness: Night mode active, returning 0.3", category: .brightness)
|
||||
// Dim the display to 30% brightness in night mode
|
||||
return 0.3
|
||||
}
|
||||
|
||||
// Color-aware brightness adaptation
|
||||
return getColorAwareBrightness()
|
||||
let colorAwareBrightness = getColorAwareBrightness()
|
||||
DebugLogger.log("effectiveBrightness: Color-aware brightness = \(String(format: "%.2f", colorAwareBrightness))", category: .brightness)
|
||||
return colorAwareBrightness
|
||||
}
|
||||
|
||||
/// Get brightness based on color theme and ambient light
|
||||
|
||||
@ -42,7 +42,7 @@ class AlarmSoundService {
|
||||
/// Load audio settings from SoundsSettings.json
|
||||
private func loadAudioSettings() -> AudioSettings {
|
||||
guard let url = Bundle.main.url(forResource: "SoundsSettings", withExtension: "json") else {
|
||||
print("⚠️ Warning: SoundsSettings.json not found, using default alarm settings")
|
||||
DebugLogger.log("Warning: SoundsSettings.json not found, using default alarm settings", category: .general)
|
||||
return AudioSettings(
|
||||
defaultVolume: 1.0,
|
||||
defaultLoopCount: -1,
|
||||
@ -57,10 +57,10 @@ class AlarmSoundService {
|
||||
do {
|
||||
let data = try Data(contentsOf: url)
|
||||
let settings = try JSONDecoder().decode(AudioSettings.self, from: data)
|
||||
print("✅ Loaded audio settings for alarms from SoundsSettings.json")
|
||||
DebugLogger.log("Loaded audio settings for alarms from SoundsSettings.json", category: .settings)
|
||||
return settings
|
||||
} catch {
|
||||
print("⚠️ Warning: Error loading audio settings for alarms, using defaults: \(error)")
|
||||
DebugLogger.log("Warning: Error loading audio settings for alarms, using defaults: \(error)", category: .general)
|
||||
return AudioSettings(
|
||||
defaultVolume: 1.0,
|
||||
defaultLoopCount: -1,
|
||||
|
||||
@ -20,6 +20,9 @@ class AmbientLightService {
|
||||
// Timer for periodic brightness checks
|
||||
private var brightnessTimer: Timer?
|
||||
|
||||
// Callback for brightness changes
|
||||
var onBrightnessChange: (() -> Void)?
|
||||
|
||||
// MARK: - Singleton
|
||||
static let shared = AmbientLightService()
|
||||
|
||||
@ -54,8 +57,18 @@ class AmbientLightService {
|
||||
/// Set screen brightness (0.0 to 1.0)
|
||||
func setBrightness(_ brightness: Double) {
|
||||
let clampedBrightness = max(0.0, min(1.0, brightness))
|
||||
let previousBrightness = UIScreen.main.brightness
|
||||
|
||||
DebugLogger.log("AmbientLightService.setBrightness:", category: .ambient)
|
||||
DebugLogger.log(" - Requested brightness: \(String(format: "%.2f", brightness))", category: .ambient)
|
||||
DebugLogger.log(" - Clamped brightness: \(String(format: "%.2f", clampedBrightness))", category: .ambient)
|
||||
DebugLogger.log(" - Previous screen brightness: \(String(format: "%.2f", previousBrightness))", category: .ambient)
|
||||
|
||||
UIScreen.main.brightness = clampedBrightness
|
||||
currentBrightness = clampedBrightness
|
||||
|
||||
DebugLogger.log(" - New screen brightness: \(String(format: "%.2f", UIScreen.main.brightness))", category: .ambient)
|
||||
DebugLogger.log(" - Service currentBrightness: \(String(format: "%.2f", currentBrightness))", category: .ambient)
|
||||
}
|
||||
|
||||
/// Get current screen brightness
|
||||
@ -71,6 +84,15 @@ class AmbientLightService {
|
||||
// MARK: - Private Methods
|
||||
|
||||
private func updateCurrentBrightness() {
|
||||
currentBrightness = UIScreen.main.brightness
|
||||
let newBrightness = UIScreen.main.brightness
|
||||
if abs(newBrightness - currentBrightness) > 0.05 { // Only update if significant change
|
||||
let previousBrightness = currentBrightness
|
||||
currentBrightness = newBrightness
|
||||
|
||||
DebugLogger.log("AmbientLightService: Brightness changed from \(String(format: "%.2f", previousBrightness)) to \(String(format: "%.2f", newBrightness))", category: .ambient)
|
||||
|
||||
// Notify that brightness changed
|
||||
onBrightnessChange?()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ class FocusModeService {
|
||||
|
||||
return granted
|
||||
} catch {
|
||||
print("❌ Error requesting notification permissions: \(error)")
|
||||
DebugLogger.log("Error requesting notification permissions: \(error)", category: .general)
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -85,7 +85,7 @@ class FocusModeService {
|
||||
// Register the category
|
||||
UNUserNotificationCenter.current().setNotificationCategories([alarmCategory])
|
||||
|
||||
print("🔔 Notification settings configured for Focus mode compatibility")
|
||||
DebugLogger.log("Notification settings configured for Focus mode compatibility", category: .settings)
|
||||
}
|
||||
|
||||
/// Schedule alarm notification with Focus mode awareness
|
||||
@ -103,11 +103,11 @@ class FocusModeService {
|
||||
// Use the sound name directly since sounds.json now references CAF files
|
||||
if soundName == "default" {
|
||||
content.sound = UNNotificationSound.default
|
||||
print("🔔 Using default notification sound")
|
||||
DebugLogger.log("Using default notification sound", category: .settings)
|
||||
} else {
|
||||
content.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: soundName))
|
||||
print("🔔 Using custom alarm sound: \(soundName)")
|
||||
print("🔔 Sound file should be in main bundle: \(soundName)")
|
||||
DebugLogger.log("Using custom alarm sound: \(soundName)", category: .settings)
|
||||
DebugLogger.log("Sound file should be in main bundle: \(soundName)", category: .settings)
|
||||
}
|
||||
content.categoryIdentifier = "ALARM_CATEGORY"
|
||||
content.userInfo = [
|
||||
@ -139,9 +139,9 @@ class FocusModeService {
|
||||
// Schedule notification
|
||||
UNUserNotificationCenter.current().add(request) { error in
|
||||
if let error = error {
|
||||
print("❌ Error scheduling alarm notification: \(error)")
|
||||
DebugLogger.log("Error scheduling alarm notification: \(error)", category: .general)
|
||||
} else {
|
||||
print("🔔 Alarm notification scheduled for \(date)")
|
||||
DebugLogger.log("Alarm notification scheduled for \(date)", category: .settings)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -149,13 +149,13 @@ class FocusModeService {
|
||||
/// Cancel alarm notification
|
||||
func cancelAlarmNotification(identifier: String) {
|
||||
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [identifier])
|
||||
print("🔔 Cancelled alarm notification: \(identifier)")
|
||||
DebugLogger.log("Cancelled alarm notification: \(identifier)", category: .settings)
|
||||
}
|
||||
|
||||
/// Cancel all alarm notifications
|
||||
func cancelAllAlarmNotifications() {
|
||||
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
|
||||
print("🔔 Cancelled all alarm notifications")
|
||||
DebugLogger.log("Cancelled all alarm notifications", category: .settings)
|
||||
}
|
||||
|
||||
// MARK: - Private Methods
|
||||
@ -195,9 +195,9 @@ class FocusModeService {
|
||||
self.currentFocusMode = self.isFocusModeActive ? "Active" : nil
|
||||
|
||||
if self.isFocusModeActive {
|
||||
print("🎯 Focus mode is active")
|
||||
DebugLogger.log("Focus mode is active", category: .settings)
|
||||
} else {
|
||||
print("🎯 Focus mode is not active")
|
||||
DebugLogger.log("Focus mode is not active", category: .settings)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -226,7 +226,7 @@ extension FocusModeService {
|
||||
await configureNotificationSettings()
|
||||
}
|
||||
|
||||
print("🎯 App configured for Focus mode compatibility")
|
||||
DebugLogger.log("App configured for Focus mode compatibility", category: .settings)
|
||||
}
|
||||
|
||||
/// Provide user guidance for Focus mode settings
|
||||
|
||||
@ -26,7 +26,7 @@ class NotificationDelegate: NSObject, UNUserNotificationCenterDelegate {
|
||||
// MARK: - Setup
|
||||
private func setupNotificationCenter() {
|
||||
UNUserNotificationCenter.current().delegate = self
|
||||
print("🔔 Notification delegate configured")
|
||||
DebugLogger.log("Notification delegate configured", category: .settings)
|
||||
}
|
||||
|
||||
/// Set the alarm service instance (called from AlarmViewModel)
|
||||
@ -46,7 +46,7 @@ class NotificationDelegate: NSObject, UNUserNotificationCenterDelegate {
|
||||
let notification = response.notification
|
||||
let userInfo = notification.request.content.userInfo
|
||||
|
||||
print("🔔 Notification action received: \(actionIdentifier)")
|
||||
DebugLogger.log("Notification action received: \(actionIdentifier)", category: .settings)
|
||||
|
||||
switch actionIdentifier {
|
||||
case "SNOOZE_ACTION":
|
||||
@ -57,7 +57,7 @@ class NotificationDelegate: NSObject, UNUserNotificationCenterDelegate {
|
||||
// User tapped the notification itself
|
||||
handleNotificationTap(userInfo: userInfo)
|
||||
default:
|
||||
print("🔔 Unknown action: \(actionIdentifier)")
|
||||
DebugLogger.log("Unknown action: \(actionIdentifier)", category: .settings)
|
||||
}
|
||||
|
||||
completionHandler()
|
||||
@ -80,16 +80,16 @@ class NotificationDelegate: NSObject, UNUserNotificationCenterDelegate {
|
||||
let alarmId = UUID(uuidString: alarmIdString),
|
||||
let alarmService = self.alarmService,
|
||||
let alarm = alarmService.getAlarm(id: alarmId) else {
|
||||
print("❌ Could not find alarm for snooze action")
|
||||
DebugLogger.log("Could not find alarm for snooze action", category: .general)
|
||||
return
|
||||
}
|
||||
|
||||
print("🔔 Snoozing alarm: \(alarm.label) for \(alarm.snoozeDuration) minutes")
|
||||
DebugLogger.log("Snoozing alarm: \(alarm.label) for \(alarm.snoozeDuration) minutes", category: .settings)
|
||||
|
||||
// Calculate snooze time (current time + snooze duration)
|
||||
let snoozeTime = Date().addingTimeInterval(TimeInterval(alarm.snoozeDuration * 60))
|
||||
print("🔔 Snooze time: \(snoozeTime)")
|
||||
print("🔔 Current time: \(Date())")
|
||||
DebugLogger.log("Snooze time: \(snoozeTime)", category: .settings)
|
||||
DebugLogger.log("Current time: \(Date())", category: .settings)
|
||||
|
||||
// Create a temporary alarm for the snooze
|
||||
let snoozeAlarm = Alarm(
|
||||
@ -114,11 +114,11 @@ class NotificationDelegate: NSObject, UNUserNotificationCenterDelegate {
|
||||
private func handleStopAction(userInfo: [AnyHashable: Any]) {
|
||||
guard let alarmIdString = userInfo["alarmId"] as? String,
|
||||
let alarmId = UUID(uuidString: alarmIdString) else {
|
||||
print("❌ Could not find alarm ID for stop action")
|
||||
DebugLogger.log("Could not find alarm ID for stop action", category: .general)
|
||||
return
|
||||
}
|
||||
|
||||
print("🔔 Stopping alarm: \(alarmId)")
|
||||
DebugLogger.log("Stopping alarm: \(alarmId)", category: .settings)
|
||||
|
||||
// Cancel any pending notifications for this alarm
|
||||
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [alarmIdString])
|
||||
@ -130,11 +130,11 @@ class NotificationDelegate: NSObject, UNUserNotificationCenterDelegate {
|
||||
private func handleNotificationTap(userInfo: [AnyHashable: Any]) {
|
||||
guard let alarmIdString = userInfo["alarmId"] as? String,
|
||||
let alarmId = UUID(uuidString: alarmIdString) else {
|
||||
print("❌ Could not find alarm ID for notification tap")
|
||||
DebugLogger.log("Could not find alarm ID for notification tap", category: .general)
|
||||
return
|
||||
}
|
||||
|
||||
print("🔔 Notification tapped for alarm: \(alarmId)")
|
||||
DebugLogger.log("Notification tapped for alarm: \(alarmId)", category: .settings)
|
||||
|
||||
// For now, just log the tap. In the future, this could open the alarm details
|
||||
// or perform some other action when the user taps the notification
|
||||
@ -171,9 +171,9 @@ class NotificationDelegate: NSObject, UNUserNotificationCenterDelegate {
|
||||
// Schedule notification
|
||||
do {
|
||||
try await UNUserNotificationCenter.current().add(request)
|
||||
print("🔔 Snooze notification scheduled for \(snoozeAlarm.time)")
|
||||
DebugLogger.log("Snooze notification scheduled for \(snoozeAlarm.time)", category: .settings)
|
||||
} catch {
|
||||
print("❌ Error scheduling snooze notification: \(error)")
|
||||
DebugLogger.log("Error scheduling snooze notification: \(error)", category: .general)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ class NotificationService {
|
||||
isAuthorized = granted
|
||||
return granted
|
||||
} catch {
|
||||
print("Error requesting notification permissions: \(error)")
|
||||
DebugLogger.log("Error requesting notification permissions: \(error)", category: .general)
|
||||
isAuthorized = false
|
||||
return false
|
||||
}
|
||||
@ -54,7 +54,7 @@ class NotificationService {
|
||||
date: Date
|
||||
) async -> Bool {
|
||||
guard isAuthorized else {
|
||||
print("Notifications not authorized")
|
||||
DebugLogger.log("Notifications not authorized", category: .settings)
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@ -166,6 +166,12 @@ class ClockViewModel {
|
||||
/// Start ambient light monitoring
|
||||
private func startAmbientLightMonitoring() {
|
||||
ambientLightService.startMonitoring()
|
||||
|
||||
// Set up callback to respond to brightness changes
|
||||
ambientLightService.onBrightnessChange = { [weak self] in
|
||||
DebugLogger.log("ClockViewModel: Received brightness change notification", category: .brightness)
|
||||
self?.updateBrightness()
|
||||
}
|
||||
}
|
||||
|
||||
/// Stop ambient light monitoring
|
||||
@ -177,7 +183,24 @@ class ClockViewModel {
|
||||
private func updateBrightness() {
|
||||
if style.autoBrightness {
|
||||
let targetBrightness = style.effectiveBrightness
|
||||
let currentScreenBrightness = UIScreen.main.brightness
|
||||
let isNightMode = style.isNightModeActive
|
||||
|
||||
DebugLogger.log("Auto Brightness Debug:", category: .brightness)
|
||||
DebugLogger.log(" - Auto brightness enabled: \(style.autoBrightness)", category: .brightness)
|
||||
DebugLogger.log(" - Current screen brightness: \(String(format: "%.2f", currentScreenBrightness))", category: .brightness)
|
||||
DebugLogger.log(" - Target brightness: \(String(format: "%.2f", targetBrightness))", category: .brightness)
|
||||
DebugLogger.log(" - Night mode active: \(isNightMode)", category: .brightness)
|
||||
DebugLogger.log(" - Color theme: \(style.selectedColorTheme)", category: .brightness)
|
||||
DebugLogger.log(" - Ambient light threshold: \(String(format: "%.2f", style.ambientLightThreshold))", category: .brightness)
|
||||
|
||||
ambientLightService.setBrightness(targetBrightness)
|
||||
|
||||
DebugLogger.log(" - Brightness set to: \(String(format: "%.2f", targetBrightness))", category: .brightness)
|
||||
DebugLogger.log(" - Actual screen brightness now: \(String(format: "%.2f", UIScreen.main.brightness))", category: .brightness)
|
||||
DebugLogger.log("---", category: .brightness)
|
||||
} else {
|
||||
DebugLogger.log("Auto Brightness: DISABLED", category: .brightness)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ struct TimeDisplayView: View {
|
||||
.minimumScaleFactor(0.1)
|
||||
.clipped() // Prevent overflow beyond bounds
|
||||
}
|
||||
//.border(.yellow, width: 1)
|
||||
.border(.yellow, width: 1)
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
.onOrientationChange() // Force updates on orientation changes
|
||||
}
|
||||
|
||||
@ -33,10 +33,10 @@ struct TimeSegment: View {
|
||||
fontDesign: fontDesign
|
||||
)
|
||||
.frame(width: digitWidth)
|
||||
//.border(.red, width: 1)
|
||||
.border(.red, width: 1)
|
||||
}
|
||||
}
|
||||
//.border(Color.green, width: 1)
|
||||
.border(Color.green, width: 1)
|
||||
.frame(maxHeight: .infinity)
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user