Add Apple Watch companion app with complications and WCSession sync
- Add watchOS app target with mood voting UI (5 mood buttons) - Add WidgetKit complications (circular, corner, inline, rectangular) - Add WatchConnectivityManager for bidirectional sync between iOS and watch - iOS app acts as central coordinator - all mood logging flows through MoodLogger - Watch votes send to iPhone via WCSession, iPhone logs and notifies watch back - Widget votes use openAppWhenRun=true to run MoodLogger in main app process - Add #if !os(watchOS) guards to Mood.swift and Random.swift for compatibility - Update SKStoreReviewController to AppStore.requestReview (iOS 18 deprecation fix) - Watch reads user's moodImages preference from GroupUserDefaults for emoji style 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,9 @@ import AppIntents
|
||||
struct VoteMoodIntent: AppIntent {
|
||||
static var title: LocalizedStringResource = "Vote Mood"
|
||||
static var description = IntentDescription("Record your mood for today")
|
||||
static var openAppWhenRun: Bool { false }
|
||||
|
||||
// Run in main app process - enables full MoodLogger with watch sync
|
||||
static var openAppWhenRun: Bool { true }
|
||||
|
||||
@Parameter(title: "Mood")
|
||||
var moodValue: Int
|
||||
@@ -32,30 +34,23 @@ struct VoteMoodIntent: AppIntent {
|
||||
let mood = Mood(rawValue: moodValue) ?? .average
|
||||
let votingDate = ShowBasedOnVoteLogics.getCurrentVotingDate(onboardingData: UserDefaultsStore.getOnboarding())
|
||||
|
||||
// Widget uses simplified mood logging since it can't access HealthKitManager/TipsManager
|
||||
// Full side effects (HealthKit sync, TipKit) will run when main app opens via MoodLogger
|
||||
// This code runs in the main app process (openAppWhenRun = true)
|
||||
// Use conditional compilation for widget extension to compile
|
||||
#if !WIDGET_EXTENSION
|
||||
// Main app: use MoodLogger for all side effects including watch sync
|
||||
MoodLogger.shared.logMood(mood, for: votingDate, entryType: .widget)
|
||||
#else
|
||||
// Widget extension compilation path (never executed at runtime)
|
||||
WidgetDataProvider.shared.add(mood: mood, forDate: votingDate, entryType: .widget)
|
||||
WidgetCenter.shared.reloadAllTimelines()
|
||||
#endif
|
||||
|
||||
// Store last voted date
|
||||
let dateString = ISO8601DateFormatter().string(from: Calendar.current.startOfDay(for: votingDate))
|
||||
GroupUserDefaults.groupDefaults.set(dateString, forKey: UserDefaultsStore.Keys.lastVotedDate.rawValue)
|
||||
|
||||
// Update Live Activity
|
||||
let streak = calculateCurrentStreak()
|
||||
LiveActivityManager.shared.updateActivity(streak: streak, mood: mood)
|
||||
LiveActivityScheduler.shared.scheduleForNextDay()
|
||||
|
||||
// Reload widget timeline
|
||||
WidgetCenter.shared.reloadTimelines(ofKind: "FeelsVoteWidget")
|
||||
|
||||
return .result()
|
||||
}
|
||||
|
||||
@MainActor
|
||||
private func calculateCurrentStreak() -> Int {
|
||||
// Use WidgetDataProvider for read operations
|
||||
return WidgetDataProvider.shared.getCurrentStreak()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Vote Widget Provider
|
||||
|
||||
Reference in New Issue
Block a user