Add interactive widget voting and fix warnings/bugs
Widget Features: - Add inline voting to timeline widget when no entry exists for today - Show random prompt from notification strings in voting mode - Update vote widget to use simple icon style for selection - Make stats bar full width in voted state view - Add Localizable.strings to widget extension target Bug Fixes: - Fix inverted date calculation in InsightsViewModel streak logic - Replace force unwraps with safe optional handling in widgets - Replace fatalError calls with graceful error handling - Fix CSV import safety in SettingsView Warning Fixes: - Add @retroactive to Color and Date extension conformances - Update deprecated onChange(of:perform:) to new syntax - Replace deprecated applicationIconBadgeNumber with setBadgeCount - Replace deprecated UIApplication.shared.windows API - Add @preconcurrency for Swift 6 protocol conformances - Add missing widget family cases to switch statement - Remove unused variables and #warning directives 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -62,14 +62,15 @@ class UserDefaultsStore {
|
||||
}
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
static func saveOnboarding(onboardingData: OnboardingData) -> OnboardingData {
|
||||
do {
|
||||
let data = try JSONEncoder().encode(onboardingData)
|
||||
GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.savedOnboardingData.rawValue)
|
||||
return UserDefaultsStore.getOnboarding()
|
||||
} catch {
|
||||
fatalError("error saving")
|
||||
print("Error saving onboarding: \(error)")
|
||||
}
|
||||
return UserDefaultsStore.getOnboarding()
|
||||
}
|
||||
|
||||
static func moodMoodImagable() -> MoodImagable.Type {
|
||||
@@ -114,21 +115,21 @@ class UserDefaultsStore {
|
||||
return model
|
||||
} else {
|
||||
GroupUserDefaults.groupDefaults.removeObject(forKey: UserDefaultsStore.Keys.customWidget.rawValue)
|
||||
|
||||
|
||||
let widget = CustomWidgetModel.randomWidget
|
||||
widget.isSaved = true
|
||||
let widgets = [widget]
|
||||
let data = try! JSONEncoder().encode(widgets)
|
||||
|
||||
guard let data = try? JSONEncoder().encode(widgets) else {
|
||||
return widgets
|
||||
}
|
||||
GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.customWidget.rawValue)
|
||||
|
||||
if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.customWidget.rawValue) as? Data,
|
||||
let models = try? JSONDecoder().decode([CustomWidgetModel].self, from: data) {
|
||||
let sorted = models.sorted(by: {
|
||||
$0.createdDate < $1.createdDate
|
||||
})
|
||||
return sorted
|
||||
if let savedData = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.customWidget.rawValue) as? Data,
|
||||
let models = try? JSONDecoder().decode([CustomWidgetModel].self, from: savedData) {
|
||||
return models.sorted { $0.createdDate < $1.createdDate }
|
||||
} else {
|
||||
fatalError("error getting widgets")
|
||||
return widgets
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -160,12 +161,12 @@ class UserDefaultsStore {
|
||||
})
|
||||
let data = try JSONEncoder().encode(existingWidgets)
|
||||
GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.customWidget.rawValue)
|
||||
return UserDefaultsStore.getCustomWidgets()
|
||||
} catch {
|
||||
fatalError("error saving")
|
||||
print("Error saving custom widget: \(error)")
|
||||
}
|
||||
return UserDefaultsStore.getCustomWidgets()
|
||||
}
|
||||
|
||||
|
||||
@discardableResult
|
||||
static func deleteCustomWidget(withUUID uuid: String) -> [CustomWidgetModel] {
|
||||
do {
|
||||
@@ -184,22 +185,18 @@ class UserDefaultsStore {
|
||||
existingWidgets.append(widget)
|
||||
}
|
||||
|
||||
if let _ = existingWidgets.first(where: {
|
||||
$0.inUse == true
|
||||
}) {} else {
|
||||
if let first = existingWidgets.first {
|
||||
first.inUse = true
|
||||
}
|
||||
if existingWidgets.first(where: { $0.inUse == true }) == nil {
|
||||
existingWidgets.first?.inUse = true
|
||||
}
|
||||
|
||||
|
||||
let data = try JSONEncoder().encode(existingWidgets)
|
||||
GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.customWidget.rawValue)
|
||||
return UserDefaultsStore.getCustomWidgets()
|
||||
} catch {
|
||||
fatalError("error saving")
|
||||
print("Error deleting custom widget: \(error)")
|
||||
}
|
||||
return UserDefaultsStore.getCustomWidgets()
|
||||
}
|
||||
|
||||
|
||||
static func getCustomMoodTint() -> SavedMoodTint {
|
||||
if let data = GroupUserDefaults.groupDefaults.object(forKey: UserDefaultsStore.Keys.customMoodTint.rawValue) as? Data{
|
||||
do {
|
||||
@@ -226,11 +223,10 @@ class UserDefaultsStore {
|
||||
do {
|
||||
let data = try JSONEncoder().encode(customTint)
|
||||
GroupUserDefaults.groupDefaults.set(data, forKey: UserDefaultsStore.Keys.customMoodTint.rawValue)
|
||||
return UserDefaultsStore.getCustomMoodTint()
|
||||
} catch {
|
||||
print(error)
|
||||
fatalError("error saving")
|
||||
print("Error saving custom mood tint: \(error)")
|
||||
}
|
||||
return UserDefaultsStore.getCustomMoodTint()
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
|
||||
Reference in New Issue
Block a user