Add comprehensive WCAG 2.1 AA accessibility support

- Add VoiceOver labels and hints to all voting layouts, settings, widgets,
  onboarding screens, and entry cells
- Add Reduce Motion support to button animations throughout the app
- Ensure 44x44pt minimum touch targets on widget mood buttons
- Enhance AccessibilityHelpers with Dynamic Type support, ScaledValue wrapper,
  and VoiceOver detection utilities
- Gate premium features (Insights, Month/Year views) behind subscription
- Update widgets to show subscription prompts for non-subscribers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Trey t
2025-12-23 23:26:21 -06:00
parent a6a6912183
commit 086f8b8807
24 changed files with 741 additions and 283 deletions

View File

@@ -43,6 +43,24 @@ struct MonthView: View {
@State private var trialWarningHidden = false
@State private var showSubscriptionStore = false
/// Filters month data to only current month when subscription/trial expired
private var filteredMonthData: [Int: [Int: [MoodEntryModel]]] {
guard iapManager.shouldShowPaywall else {
return viewModel.grouped
}
// Only show current month when paywall should show
let currentMonth = Calendar.current.component(.month, from: Date())
let currentYear = Calendar.current.component(.year, from: Date())
var filtered: [Int: [Int: [MoodEntryModel]]] = [:]
if let yearData = viewModel.grouped[currentYear],
let monthData = yearData[currentMonth] {
filtered[currentYear] = [currentMonth: monthData]
}
return filtered
}
var body: some View {
ZStack {
if viewModel.hasNoData {
@@ -51,7 +69,7 @@ struct MonthView: View {
} else {
ScrollView {
VStack(spacing: 16) {
ForEach(viewModel.grouped.sorted(by: { $0.key > $1.key }), id: \.key) { year, months in
ForEach(filteredMonthData.sorted(by: { $0.key > $1.key }), id: \.key) { year, months in
// for each month
ForEach(months.sorted(by: { $0.key > $1.key }), id: \.key) { month, entries in
MonthCard(
@@ -90,7 +108,7 @@ struct MonthView: View {
}
)
}
.disabled(iapManager.shouldShowPaywall)
.scrollDisabled(iapManager.shouldShowPaywall)
}
// Hidden text to trigger updates when custom tint changes