feat: calorie ring widget — home screen + lock screen
All checks were successful
Security Checks / dockerfile-lint (push) Successful in 4s
Security Checks / dependency-audit (push) Successful in 13s
Security Checks / secret-scanning (push) Successful in 4s

Widget displays:
- systemSmall: calorie ring + "X left" text
- systemMedium: ring + "Calories" / "X of Y" / "X remaining"
- accessoryCircular: gauge ring for lock screen
- accessoryInline: "🔥 845 / 2000 cal" text for lock screen
- accessoryRectangular: linear gauge + calorie count

Data flow: main app writes totalCalories + calorieGoal to
UserDefaults on each loadTodayData(), then calls
WidgetCenter.shared.reloadAllTimelines(). Widget reads on
15-minute refresh cycle.

Note: currently uses standard UserDefaults (same app container).
For production, migrate to App Group UserDefaults so widget
process can read the data. Requires Xcode App Group setup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yusuf Suleman
2026-04-04 11:21:40 -05:00
parent a4ebe77973
commit 9965b1d634
2 changed files with 194 additions and 30 deletions

View File

@@ -1,5 +1,6 @@
import SwiftUI
import PhotosUI
import WidgetKit
@Observable
final class HomeViewModel {
@@ -32,6 +33,11 @@ final class HomeViewModel {
totalCalories = repo.entries.reduce(0) { $0 + $1.snapshotCalories }
calorieGoal = repo.goal?.calories ?? 2000
isLoading = false
// Write to UserDefaults for widget
UserDefaults.standard.set(totalCalories, forKey: "widget_totalCalories")
UserDefaults.standard.set(calorieGoal, forKey: "widget_calorieGoal")
WidgetCenter.shared.reloadAllTimelines()
}
// MARK: - Background Image