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:
@@ -82,6 +82,8 @@ struct SmallWidgetView: View {
|
||||
return f
|
||||
}
|
||||
|
||||
private var isSampleData: Bool
|
||||
|
||||
init(entry: Provider.Entry) {
|
||||
self.entry = entry
|
||||
let realData = TimeLineCreator.createViews(daysBack: 2)
|
||||
@@ -89,6 +91,7 @@ struct SmallWidgetView: View {
|
||||
let moodTint: MoodTintable.Type = UserDefaultsStore.moodTintable()
|
||||
return view.color != moodTint.color(forMood: .missing)
|
||||
}
|
||||
isSampleData = !hasRealData
|
||||
todayView = hasRealData ? realData.first : TimeLineCreator.createSampleViews(count: 1).first
|
||||
}
|
||||
|
||||
@@ -98,6 +101,13 @@ struct SmallWidgetView: View {
|
||||
VotingView(family: .systemSmall, promptText: entry.promptText, hasSubscription: entry.hasSubscription)
|
||||
} else if let today = todayView {
|
||||
VStack(spacing: 0) {
|
||||
if isSampleData {
|
||||
Text(String(localized: "Log your first mood!"))
|
||||
.font(.caption2)
|
||||
.foregroundStyle(.secondary)
|
||||
.padding(.top, 8)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
// Large mood icon
|
||||
@@ -152,6 +162,8 @@ struct MediumWidgetView: View {
|
||||
return f
|
||||
}
|
||||
|
||||
private var isSampleData: Bool
|
||||
|
||||
init(entry: Provider.Entry) {
|
||||
self.entry = entry
|
||||
let realData = Array(TimeLineCreator.createViews(daysBack: 6).prefix(5))
|
||||
@@ -159,6 +171,7 @@ struct MediumWidgetView: View {
|
||||
let moodTint: MoodTintable.Type = UserDefaultsStore.moodTintable()
|
||||
return view.color != moodTint.color(forMood: .missing)
|
||||
}
|
||||
isSampleData = !hasRealData
|
||||
timeLineView = hasRealData ? realData : TimeLineCreator.createSampleViews(count: 5)
|
||||
}
|
||||
|
||||
@@ -183,11 +196,19 @@ struct MediumWidgetView: View {
|
||||
Text("Last 5 Days")
|
||||
.font(.subheadline.weight(.semibold))
|
||||
.foregroundStyle(.primary)
|
||||
Text("·")
|
||||
.foregroundStyle(.secondary)
|
||||
Text(headerDateRange)
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
if isSampleData {
|
||||
Text("·")
|
||||
.foregroundStyle(.secondary)
|
||||
Text(String(localized: "Log your first mood!"))
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
} else {
|
||||
Text("·")
|
||||
.foregroundStyle(.secondary)
|
||||
Text(headerDateRange)
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
.padding(.horizontal, 14)
|
||||
@@ -264,6 +285,8 @@ struct LargeWidgetView: View {
|
||||
!entry.hasVotedToday
|
||||
}
|
||||
|
||||
private var isSampleData: Bool
|
||||
|
||||
init(entry: Provider.Entry) {
|
||||
self.entry = entry
|
||||
let realData = Array(TimeLineCreator.createViews(daysBack: 11).prefix(10))
|
||||
@@ -271,6 +294,7 @@ struct LargeWidgetView: View {
|
||||
let moodTint: MoodTintable.Type = UserDefaultsStore.moodTintable()
|
||||
return view.color != moodTint.color(forMood: .missing)
|
||||
}
|
||||
isSampleData = !hasRealData
|
||||
timeLineView = hasRealData ? realData : TimeLineCreator.createSampleViews(count: 10)
|
||||
}
|
||||
|
||||
@@ -301,7 +325,7 @@ struct LargeWidgetView: View {
|
||||
Text("Last 10 Days")
|
||||
.font(.subheadline.weight(.semibold))
|
||||
.foregroundStyle(.primary)
|
||||
Text(headerDateRange)
|
||||
Text(isSampleData ? String(localized: "Log your first mood!") : headerDateRange)
|
||||
.font(.caption2)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user