1.0.6: Priority dishes, day rules, auto-assign CTA, tap-to-replace, export incomplete weeks, Sunday notification
- Dish.isPriority: mark dishes as priority; auto-assign gives them 2.5x weight - Tag.dayRestriction: restrict tags to weekdays or weekend only - Auto-assign CTA banner shown when there are empty slots (was hidden in context menu) - Tap on filled slot opens picker to replace dish directly (no need to remove first) - Export callout visible as soon as ≥1 slot is filled (not only when week is complete) - WeekPlanShareView shows localized "TBD" / "Eating out" for empty/eating-out slots - Second Sunday 17:00 push notification to plan next week - DishDrawer sorts: priority first, then by historical usage, then alphabetically - Search in SlotDishPickerSheet already shipped in 1.0.5 (verified ✓) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ final class DishViewModel: ObservableObject {
|
||||
@Published var name: String = ""
|
||||
@Published var descriptionText: String = ""
|
||||
@Published var selectedTagIds: Set<UUID> = []
|
||||
@Published var isPriority: Bool = false
|
||||
@Published var showTagSelector: Bool = false
|
||||
@Published var showDeleteAlert: Bool = false
|
||||
@Published var showAssignedDeleteAlert: Bool = false
|
||||
@@ -23,6 +24,7 @@ final class DishViewModel: ObservableObject {
|
||||
name = dish.name
|
||||
descriptionText = dish.descriptionText ?? ""
|
||||
selectedTagIds = Set(dish.tagIds)
|
||||
isPriority = dish.isPriority
|
||||
}
|
||||
|
||||
func reset() {
|
||||
@@ -30,6 +32,7 @@ final class DishViewModel: ObservableObject {
|
||||
name = ""
|
||||
descriptionText = ""
|
||||
selectedTagIds = []
|
||||
isPriority = false
|
||||
}
|
||||
|
||||
func save(context: ModelContext) {
|
||||
@@ -40,11 +43,13 @@ final class DishViewModel: ObservableObject {
|
||||
dish.name = trimmedName
|
||||
dish.descriptionText = descriptionText.isEmpty ? nil : descriptionText
|
||||
dish.tagIds = Array(selectedTagIds)
|
||||
dish.isPriority = isPriority
|
||||
} else {
|
||||
let dish = Dish(
|
||||
name: trimmedName,
|
||||
descriptionText: descriptionText.isEmpty ? nil : descriptionText,
|
||||
tagIds: Array(selectedTagIds)
|
||||
tagIds: Array(selectedTagIds),
|
||||
isPriority: isPriority
|
||||
)
|
||||
context.insert(dish)
|
||||
AnalyticsService.logDishAdded(tagCount: selectedTagIds.count)
|
||||
|
||||
@@ -8,6 +8,7 @@ final class TagViewModel: ObservableObject {
|
||||
@Published var noConsecutive: Bool = false
|
||||
@Published var noDuplicateInDay: Bool = false
|
||||
@Published var mealTypeRestriction: String? = nil
|
||||
@Published var dayRestriction: String? = nil
|
||||
@Published var useMaxLimit: Bool = true
|
||||
|
||||
func loadTag(_ tag: Tag) {
|
||||
@@ -16,6 +17,7 @@ final class TagViewModel: ObservableObject {
|
||||
noConsecutive = tag.noConsecutive
|
||||
noDuplicateInDay = tag.noDuplicateInDay
|
||||
mealTypeRestriction = tag.mealTypeRestriction
|
||||
dayRestriction = tag.dayRestriction
|
||||
useMaxLimit = tag.maxPerWeek != nil
|
||||
}
|
||||
|
||||
@@ -25,6 +27,7 @@ final class TagViewModel: ObservableObject {
|
||||
tag.noConsecutive = noConsecutive
|
||||
tag.noDuplicateInDay = noDuplicateInDay
|
||||
tag.mealTypeRestriction = mealTypeRestriction
|
||||
tag.dayRestriction = dayRestriction
|
||||
}
|
||||
|
||||
func reset() {
|
||||
|
||||
Reference in New Issue
Block a user