66128e7a5c
Hasta ahora includeWeekends y activeMealTypes vivían solo en AppSettings y aplicaban a todo el calendario. WeekPlan puede ahora sobreescribirlos para su semana (includeWeekendsOverride / mealTypesOverrideRaw) y WeekSchedule resuelve qué manda en cada semana: su override si lo tiene, los ajustes globales si no. Todo lo que pintaba días y comidas —planificador, exports, compartir texto, widget, watch— pasa por settings.schedule(for:), así que una semana con fin de semana añadido o con desayuno activo se ve igual en todas partes. Crear o editar el override es premium; los ya guardados se respetan aunque la suscripción caduque, para no borrar comidas ya planificadas. La hoja avisa y pide confirmación cuando quitar un día o una comida se lleva por delante algo ya planificado. Refs #32 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013su1ttRiMeMYxkZJ1Y3246
39 lines
1.6 KiB
Swift
39 lines
1.6 KiB
Swift
import Foundation
|
|
|
|
/// Which days and which meals a given week is planned with. Until 2.1.1 this
|
|
/// came straight from `AppSettings` and applied to the whole calendar; a week
|
|
/// can now override it (premium), e.g. add the weekend for a trip or turn on
|
|
/// breakfast just for the school week.
|
|
struct WeekSchedule: Equatable {
|
|
let mealTypes: [MealType]
|
|
let includeWeekends: Bool
|
|
/// True when the values come from a per-week override rather than settings.
|
|
let isCustomized: Bool
|
|
|
|
var dayRange: ClosedRange<Int> { includeWeekends ? 0...6 : 0...4 }
|
|
var lastDay: Int { includeWeekends ? 6 : 4 }
|
|
}
|
|
|
|
extension AppSettings {
|
|
/// The schedule applied to every week that has no override of its own.
|
|
var defaultSchedule: WeekSchedule {
|
|
WeekSchedule(mealTypes: activeMealTypes, includeWeekends: includeWeekends, isCustomized: false)
|
|
}
|
|
|
|
/// Resolved schedule for a week: its own override when present, the global
|
|
/// settings otherwise.
|
|
///
|
|
/// Existing overrides are honoured even when `isPremium` is false — a lapsed
|
|
/// subscription must not silently delete slots the user already filled.
|
|
/// Creating or editing an override is what premium gates (see
|
|
/// `PremiumAccess.canCustomizeWeekSchedule`).
|
|
func schedule(for plan: WeekPlan?) -> WeekSchedule {
|
|
guard let plan, plan.hasScheduleOverride else { return defaultSchedule }
|
|
return WeekSchedule(
|
|
mealTypes: plan.mealTypesOverride ?? activeMealTypes,
|
|
includeWeekends: plan.includeWeekendsOverride ?? includeWeekends,
|
|
isCustomized: true
|
|
)
|
|
}
|
|
}
|