Autocomplete feedback loop: implicit rejection + weekly rating
A) Implicit: HomeViewModel tracks auto-assigned slot IDs after each autocomplete run. When the user manually replaces one of those dishes, the rejected dish ID is recorded in FeedbackStore (UserDefaults). AutocompleteEngine applies a 25% penalty per rejection (floor 0.30). B) Explicit: WeekPlan gains userRating (0/1/-1). Past weeks with dishes show a compact 👍/👎 row (Premium only). Liked weeks boost their dishes (+0.20 each, max +0.50); disliked weeks penalise them (-0.25 each, max -0.50). Signal is intentionally modest so the period cycle score remains dominant. Also adds Stats + week-rating localization strings to all 6 languages (were missing from the previous commit). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -244,6 +244,10 @@ struct HomeView: View {
|
||||
exportCallout(plan: plan, settings: settings)
|
||||
}
|
||||
|
||||
if !viewModel.canEditCurrentWeek && filledCount > 0 && settings.isPremium {
|
||||
weekRatingRow(plan: plan)
|
||||
}
|
||||
|
||||
let emptyCount = plan.slots.filter { $0.dishId == nil && !$0.isEatingOut }.count
|
||||
if viewModel.canEditCurrentWeek && !dishes.isEmpty && emptyCount > 0 {
|
||||
autoAssignBanner(emptyCount: emptyCount, plan: plan, settings: settings)
|
||||
@@ -635,6 +639,36 @@ struct HomeView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private func weekRatingRow(plan: WeekPlan) -> some View {
|
||||
HStack(spacing: 12) {
|
||||
Text("week_rating_prompt")
|
||||
.font(.mealMoodSmall)
|
||||
.foregroundColor(.mealMoodTextSecondary)
|
||||
|
||||
Spacer()
|
||||
|
||||
Button {
|
||||
viewModel.rateWeek(plan: plan, rating: plan.userRating == 1 ? 0 : 1)
|
||||
} label: {
|
||||
Image(systemName: plan.userRating == 1 ? "hand.thumbsup.fill" : "hand.thumbsup")
|
||||
.font(.system(size: 17))
|
||||
.foregroundColor(plan.userRating == 1 ? .mealMoodSuccess : .mealMoodTextSecondary)
|
||||
}
|
||||
|
||||
Button {
|
||||
viewModel.rateWeek(plan: plan, rating: plan.userRating == -1 ? 0 : -1)
|
||||
} label: {
|
||||
Image(systemName: plan.userRating == -1 ? "hand.thumbsdown.fill" : "hand.thumbsdown")
|
||||
.font(.system(size: 17))
|
||||
.foregroundColor(plan.userRating == -1 ? .mealMoodCoral : .mealMoodTextSecondary)
|
||||
}
|
||||
}
|
||||
.padding(.horizontal, 14)
|
||||
.padding(.vertical, 10)
|
||||
.background(Color.mealMoodSurface)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 12))
|
||||
}
|
||||
|
||||
private func dishDrawer(plan: WeekPlan, settings: AppSettings) -> some View {
|
||||
DishDrawerView(
|
||||
dishes: dishes,
|
||||
|
||||
Reference in New Issue
Block a user