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:
@@ -305,6 +305,12 @@ struct FlipRevealAnimation: View {
|
||||
struct ShatterReformAnimation: View {
|
||||
let mood: Mood
|
||||
|
||||
private enum AnimationConstants {
|
||||
static let shatterPhaseDuration: TimeInterval = 0.6
|
||||
static let checkmarkAppearDelay: TimeInterval = 1.1
|
||||
static let fadeOutDelay: TimeInterval = 1.8
|
||||
}
|
||||
|
||||
@State private var shardOffsets: [CGSize] = []
|
||||
@State private var shardRotations: [Double] = []
|
||||
@State private var shardOpacities: [Double] = []
|
||||
@@ -354,7 +360,7 @@ struct ShatterReformAnimation: View {
|
||||
|
||||
// Phase 2: Converge to center and fade
|
||||
Task { @MainActor in
|
||||
try? await Task.sleep(for: .seconds(0.6))
|
||||
try? await Task.sleep(for: .seconds(AnimationConstants.shatterPhaseDuration))
|
||||
phase = .reform
|
||||
withAnimation(.easeInOut(duration: 0.5)) {
|
||||
for i in 0..<shardCount {
|
||||
@@ -367,7 +373,7 @@ struct ShatterReformAnimation: View {
|
||||
|
||||
// Phase 3: Show checkmark
|
||||
Task { @MainActor in
|
||||
try? await Task.sleep(for: .seconds(1.1))
|
||||
try? await Task.sleep(for: .seconds(AnimationConstants.checkmarkAppearDelay))
|
||||
withAnimation(.spring(response: 0.3, dampingFraction: 0.6)) {
|
||||
checkmarkOpacity = 1
|
||||
}
|
||||
@@ -375,7 +381,7 @@ struct ShatterReformAnimation: View {
|
||||
|
||||
// Phase 4: Fade out
|
||||
Task { @MainActor in
|
||||
try? await Task.sleep(for: .seconds(1.8))
|
||||
try? await Task.sleep(for: .seconds(AnimationConstants.fadeOutDelay))
|
||||
withAnimation(.easeOut(duration: 0.3)) {
|
||||
checkmarkOpacity = 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user