84b74f9ea4
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>
29 lines
994 B
Swift
29 lines
994 B
Swift
import Foundation
|
|
|
|
struct FeedbackStore {
|
|
private static let rejectionKey = "com.mealmood.dishRejections"
|
|
|
|
static func rejectionCounts() -> [UUID: Int] {
|
|
guard let data = UserDefaults.standard.data(forKey: rejectionKey),
|
|
let raw = try? JSONDecoder().decode([String: Int].self, from: data)
|
|
else { return [:] }
|
|
return Dictionary(uniqueKeysWithValues: raw.compactMap { k, v in
|
|
UUID(uuidString: k).map { ($0, v) }
|
|
})
|
|
}
|
|
|
|
static func recordRejection(for dishId: UUID) {
|
|
var raw: [String: Int]
|
|
if let data = UserDefaults.standard.data(forKey: rejectionKey),
|
|
let decoded = try? JSONDecoder().decode([String: Int].self, from: data) {
|
|
raw = decoded
|
|
} else {
|
|
raw = [:]
|
|
}
|
|
raw[dishId.uuidString, default: 0] += 1
|
|
if let encoded = try? JSONEncoder().encode(raw) {
|
|
UserDefaults.standard.set(encoded, forKey: rejectionKey)
|
|
}
|
|
}
|
|
}
|