1.1.0: Smarter autocomplete + Statistics view

- AutocompleteEngine: MRV heuristic picks the most-constrained slot first
  at each step; historical scoring deprioritises dishes used in recent
  weeks (decay: 0.20 last week → 0.90 four+ weeks ago)
- HomeViewModel: passes last 4 weeks as recentPlans to autocomplete
- StatsView (Premium): streak, weeks planned, completion rate, top 8
  dishes with bar charts, top 6 tags with colour bars — 6 languages
- StoreManager: update product ID to approved bundle-ID convention
- Version bump to 1.1.3 / build 48

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
alexandrev-tibco
2026-05-27 15:05:39 +02:00
parent 0103ee98c6
commit 330f21a019
13 changed files with 433 additions and 59 deletions
+13 -3
View File
@@ -14,6 +14,7 @@ struct HomeView: View {
@State private var editingDish: Dish?
@State private var showPremiumFromExport: Bool = false
@State private var showMonthlyHistory: Bool = false
@State private var showStats: Bool = false
@State private var showWeekLimitUpsell: Bool = false
@State private var wasWeekComplete: Bool = false
@State private var selectedEmptySlotId: UUID?
@@ -62,6 +63,12 @@ struct HomeView: View {
}
if settings?.isPremium == true {
Button {
showStats = true
} label: {
Image(systemName: "chart.bar.xaxis")
.foregroundColor(.mealMoodTextPrimary)
}
Button {
showMonthlyHistory = true
} label: {
@@ -121,7 +128,7 @@ struct HomeView: View {
let plan = fetchWeekPlan(for: viewModel.currentWeekStart) {
if viewModel.canEditCurrentWeek {
Button {
viewModel.autoComplete(plan: plan, dishes: dishes, tags: tags, settings: settings)
viewModel.autoComplete(plan: plan, dishes: dishes, tags: tags, settings: settings, allPlans: weekPlans)
} label: {
Image(systemName: "wand.and.stars")
.foregroundColor(.mealMoodTextPrimary)
@@ -287,7 +294,7 @@ struct HomeView: View {
}
.alert("onboarding_auto_assign_title", isPresented: $showPostOnboardingAutoAssignPrompt) {
Button("onboarding_auto_assign_yes") {
viewModel.autoComplete(plan: plan, dishes: dishes, tags: tags, settings: settings)
viewModel.autoComplete(plan: plan, dishes: dishes, tags: tags, settings: settings, allPlans: weekPlans)
UserDefaults.standard.set(false, forKey: OnboardingViewModel.pendingAutoAssignPromptKey)
schedulePostOnboardingPremiumPromptIfNeeded(settings: settings)
}
@@ -495,6 +502,9 @@ struct HomeView: View {
showMonthlyHistory = false
}
}
.sheet(isPresented: $showStats) {
StatsView(weekPlans: weekPlans, allDishes: dishes, allTags: tags, language: settings.languageEnum.resolved())
}
.task {
await NotificationService.shared.requestPermissionIfNeeded()
let nextPlan = fetchWeekPlan(for: Date().startOfWeek().addingDays(7))
@@ -717,7 +727,7 @@ struct HomeView: View {
}
Spacer()
Button {
viewModel.autoComplete(plan: plan, dishes: dishes, tags: tags, settings: settings)
viewModel.autoComplete(plan: plan, dishes: dishes, tags: tags, settings: settings, allPlans: weekPlans)
} label: {
HStack(spacing: 6) {
Image(systemName: "wand.and.stars")