110807d239
- Eating out: tap any empty slot → "Mark as eating out"; shows teal indicator, skipped by auto-assign, counts as complete, tap again to unmark - Rule violations panel: access via wand long-press context menu when conflicts exist; shows all isRuleOverridden slots with Fix (clear) or Ignore (acknowledge) actions - Firebase Crashlytics integrated: CrashlyticsService + dSYM upload build phase, isPremium property tracked per session - PremiumSyncService: extracted premium state machine, StoreKit Transaction.updates listener, isPremium no longer synced via iCloud to avoid stale state - StoreManager: analytics on purchase/restore, bundle ID fallback for product ID lookup - Search bar contrast bug fixed: TextField now has explicit foreground color for dark mode - WelcomeStepView: redesigned onboarding welcome screen with week preview - Version bump: 1.0.5 build 22 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
55 lines
1.5 KiB
Swift
55 lines
1.5 KiB
Swift
import Foundation
|
|
import SwiftData
|
|
|
|
@Model
|
|
final class MealSlot {
|
|
@Attribute(.unique) var id: UUID
|
|
var dayOfWeek: Int // 0=Monday, 6=Sunday
|
|
var mealType: String // "lunch", "dinner"
|
|
var dishId: UUID?
|
|
var calendarEventId: String?
|
|
var isRuleOverridden: Bool
|
|
var isEatingOut: Bool
|
|
|
|
var weekPlan: WeekPlan?
|
|
|
|
init(
|
|
id: UUID = UUID(),
|
|
dayOfWeek: Int,
|
|
mealType: String,
|
|
dishId: UUID? = nil,
|
|
calendarEventId: String? = nil,
|
|
isRuleOverridden: Bool = false,
|
|
isEatingOut: Bool = false
|
|
) {
|
|
self.id = id
|
|
self.dayOfWeek = dayOfWeek
|
|
self.mealType = mealType
|
|
self.dishId = dishId
|
|
self.calendarEventId = calendarEventId
|
|
self.isRuleOverridden = isRuleOverridden
|
|
self.isEatingOut = isEatingOut
|
|
}
|
|
|
|
var mealTypeEnum: MealType {
|
|
get { MealType(rawValue: mealType) ?? .dinner }
|
|
set { mealType = newValue.rawValue }
|
|
}
|
|
}
|
|
|
|
extension MealSlot {
|
|
static func preferredForDuplicateResolution(_ slots: [MealSlot]) -> MealSlot {
|
|
slots.sorted { lhs, rhs in
|
|
let lhsHasDish = lhs.dishId != nil
|
|
let rhsHasDish = rhs.dishId != nil
|
|
if lhsHasDish != rhsHasDish { return lhsHasDish }
|
|
|
|
let lhsHasEvent = lhs.calendarEventId != nil
|
|
let rhsHasEvent = rhs.calendarEventId != nil
|
|
if lhsHasEvent != rhsHasEvent { return lhsHasEvent }
|
|
|
|
return lhs.id.uuidString < rhs.id.uuidString
|
|
}.first ?? slots[0]
|
|
}
|
|
}
|