v1.1 polish: accessibility, error logging, localization, and code quality sweep

- Wrap 30+ production print() statements in #if DEBUG guards across 18 files
- Add VoiceOver labels, hints, and traits to Watch app, Live Activities, widgets
- Add .accessibilityAddTraits(.isButton) to 15+ onTapGesture views
- Add text alternatives for color-only indicators (progress dots, mood circles)
- Localize raw string literals in NoteEditorView, EntryDetailView, widgets
- Replace 25+ silent try? with do/catch + AppLogger error logging
- Replace hardcoded font sizes with semantic Dynamic Type fonts
- Fix FIXME in IconPickerView (log icon change errors)
- Extract magic animation delays to named constants across 8 files
- Add widget empty state "Log your first mood!" messaging
- Hide decorative images from VoiceOver, add labels to ColorPickers
- Remove stale TODO in Color+Codable (alpha change deferred for migration)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Trey T
2026-03-26 20:09:14 -05:00
parent 4d9e906c4d
commit 1f040ab676
41 changed files with 427 additions and 107 deletions

View File

@@ -37,7 +37,9 @@ class LiveActivityManager: ObservableObject {
// Start a mood streak Live Activity
func startStreakActivity(streak: Int, lastMood: Mood?, hasLoggedToday: Bool) {
guard ActivityAuthorizationInfo().areActivitiesEnabled else {
#if DEBUG
print("Live Activities not enabled")
#endif
return
}
@@ -76,7 +78,9 @@ class LiveActivityManager: ObservableObject {
)
currentActivity = activity
} catch {
#if DEBUG
print("Error starting Live Activity: \(error)")
#endif
}
}
@@ -257,23 +261,31 @@ class LiveActivityScheduler: ObservableObject {
invalidateTimers()
guard ActivityAuthorizationInfo().areActivitiesEnabled else {
#if DEBUG
print("[LiveActivity] Live Activities not enabled by user")
#endif
return
}
let now = Date()
guard let startTime = getStartTime(),
let endTime = getEndTime() else {
#if DEBUG
print("[LiveActivity] No rating time configured - skipping")
#endif
return
}
let hasRated = hasRatedToday()
#if DEBUG
print("[LiveActivity] Schedule check - now: \(now), start: \(startTime), end: \(endTime), hasRated: \(hasRated)")
#endif
// If user has already rated today, don't show activity - schedule for next day
if hasRated {
#if DEBUG
print("[LiveActivity] User already rated today - scheduling for next day")
#endif
scheduleForNextDay()
return
}
@@ -281,7 +293,9 @@ class LiveActivityScheduler: ObservableObject {
// Check if we're within the activity window (rating time to 5 hrs after)
if now >= startTime && now <= endTime {
// Start activity immediately
#if DEBUG
print("[LiveActivity] Within window - starting activity now")
#endif
let streak = calculateStreak()
LiveActivityManager.shared.startStreakActivity(streak: streak, lastMood: getTodaysMood(), hasLoggedToday: false)
@@ -289,12 +303,16 @@ class LiveActivityScheduler: ObservableObject {
scheduleEnd(at: endTime)
} else if now < startTime {
// Schedule start for later today
#if DEBUG
print("[LiveActivity] Before window - scheduling start for \(startTime)")
#endif
scheduleStart(at: startTime)
scheduleEnd(at: endTime)
} else {
// Past the window for today, schedule for tomorrow
#if DEBUG
print("[LiveActivity] Past window - scheduling for tomorrow")
#endif
scheduleForNextDay()
}
}