Add reminder notifications to schedules
- ScheduleDocument/Schedule gain optional reminderMinutes (minutes from midnight; decode-compatible, no schema bump) - New Workout form gets a Reminder section (toggle + time picker, hidden for Now; footer warns when notifications are denied) - ReminderPlanner (pure, tested) derives notification triggers: daily repeating, per-weekday repeating for fixed days, one-shot for once - ReminderScheduler resyncs pending requests from the cache on every change, multiplexed onto onCacheChanged after the watch push; asks notification permission only once a reminder actually exists
This commit is contained in:
@@ -377,6 +377,10 @@ struct ScheduleDocument: Codable, Sendable, Equatable, Identifiable {
|
||||
var recurrence: String // ScheduleRecurrence raw value
|
||||
var weekdays: [Int]? // Calendar weekday numbers 1 (Sun) – 7 (Sat); .fixedDays only
|
||||
var date: Date? = nil // the one-off day; .once only
|
||||
/// Reminder time as minutes from midnight (local wall-clock, 0–1439); nil = no
|
||||
/// reminder. Optional addition — decode-compatible, deliberately NOT schema-bumped
|
||||
/// (an older app dropping it on rewrite loses only a notification preference).
|
||||
var reminderMinutes: Int? = nil
|
||||
var order: Int
|
||||
var createdAt: Date
|
||||
var updatedAt: Date
|
||||
|
||||
@@ -318,13 +318,15 @@ final class Schedule {
|
||||
var recurrenceRaw: String = ScheduleRecurrence.daily.rawValue
|
||||
var weekdays: [Int]?
|
||||
var date: Date?
|
||||
/// Reminder time as minutes from midnight (local wall-clock); nil = no reminder.
|
||||
var reminderMinutes: Int?
|
||||
var order: Int = 0
|
||||
var createdAt: Date = Date()
|
||||
var updatedAt: Date = Date()
|
||||
var jsonRelativePath: String = ""
|
||||
|
||||
init(id: String, routineID: String, routineName: String, goalRaw: String?,
|
||||
recurrenceRaw: String, weekdays: [Int]?, date: Date? = nil,
|
||||
recurrenceRaw: String, weekdays: [Int]?, date: Date? = nil, reminderMinutes: Int? = nil,
|
||||
order: Int, createdAt: Date, updatedAt: Date, jsonRelativePath: String) {
|
||||
self.id = id
|
||||
self.routineID = routineID
|
||||
@@ -333,6 +335,7 @@ final class Schedule {
|
||||
self.recurrenceRaw = recurrenceRaw
|
||||
self.weekdays = weekdays
|
||||
self.date = date
|
||||
self.reminderMinutes = reminderMinutes
|
||||
self.order = order
|
||||
self.createdAt = createdAt
|
||||
self.updatedAt = updatedAt
|
||||
|
||||
@@ -92,7 +92,7 @@ extension ScheduleDocument {
|
||||
routineID: schedule.routineID, routineName: schedule.routineName,
|
||||
goal: schedule.goalRaw, recurrence: schedule.recurrenceRaw,
|
||||
weekdays: schedule.weekdays,
|
||||
date: schedule.date,
|
||||
date: schedule.date, reminderMinutes: schedule.reminderMinutes,
|
||||
order: schedule.order, createdAt: schedule.createdAt, updatedAt: schedule.updatedAt)
|
||||
}
|
||||
}
|
||||
@@ -255,7 +255,7 @@ enum CacheMapper {
|
||||
} else {
|
||||
schedule = Schedule(id: doc.id, routineID: doc.routineID, routineName: doc.routineName,
|
||||
goalRaw: doc.goal, recurrenceRaw: doc.recurrence, weekdays: doc.weekdays,
|
||||
date: doc.date, order: doc.order,
|
||||
date: doc.date, reminderMinutes: doc.reminderMinutes, order: doc.order,
|
||||
createdAt: doc.createdAt, updatedAt: doc.updatedAt,
|
||||
jsonRelativePath: relativePath)
|
||||
context.insert(schedule)
|
||||
@@ -266,6 +266,7 @@ enum CacheMapper {
|
||||
schedule.recurrenceRaw = doc.recurrence
|
||||
schedule.weekdays = doc.weekdays
|
||||
schedule.date = doc.date
|
||||
schedule.reminderMinutes = doc.reminderMinutes
|
||||
schedule.order = doc.order
|
||||
schedule.createdAt = doc.createdAt
|
||||
schedule.updatedAt = doc.updatedAt
|
||||
|
||||
Reference in New Issue
Block a user