diff --git a/Sources/RemindersLibrary/CLI.swift b/Sources/RemindersLibrary/CLI.swift index 329b88e..5fa5abb 100644 --- a/Sources/RemindersLibrary/CLI.swift +++ b/Sources/RemindersLibrary/CLI.swift @@ -10,9 +10,18 @@ private struct ShowLists: ParsableCommand { name: .shortAndLong, help: "format, either of 'plain' or 'json'") var format: OutputFormat = .plain + + @Flag( + name: .shortAndLong, + help: "show only the default Reminders list") + var defaultOnly: Bool = false func run() { - reminders.showLists(outputFormat: format) + if defaultOnly { + print(reminders.getDefaultList()) + } else { + reminders.showLists(outputFormat: format) + } } } @@ -229,6 +238,26 @@ private struct Edit: ParsableCommand { @Argument( help: "The index or id of the reminder to delete, see 'show' for indexes") var index: String + + @Option( + name: .shortAndLong, + help: "The new date the reminder is due") + var dueDate: DateComponents? + + @Flag( + name: .shortAndLong, + help: "Clear the due date.") + var clearDueDate: Bool = false + + @Option( + name: .shortAndLong, + help: "The new priority of the reminder") + var priority: Priority? + + @Flag( + name: .shortAndLong, + help: "Clear the priority of the reminder.") + var clearPriority: Bool = false @Option( name: .shortAndLong, @@ -241,8 +270,13 @@ private struct Edit: ParsableCommand { var reminder: [String] = [] func validate() throws { - if self.reminder.isEmpty && self.notes == nil { - throw ValidationError("Must specify either new reminder content or new notes") + + if self.dueDate != nil && self.clearDueDate { + throw ValidationError("Don't try to set & clear the due date at the same time.") + } + + if self.reminder.isEmpty && self.notes == nil && self.dueDate == nil && !self.clearDueDate { + throw ValidationError("Must specify new reminder content, new notes, or a new due date.") } } @@ -252,7 +286,11 @@ private struct Edit: ParsableCommand { itemAtIndex: self.index, onListNamed: self.listName, newText: newText.isEmpty ? nil : newText, - newNotes: self.notes + newNotes: self.notes, + dueDateComponents: self.dueDate, + clearDueDate: self.clearDueDate, + priority: self.priority, + clearPriority: self.clearPriority ) } } diff --git a/Sources/RemindersLibrary/EKReminder+Encodable.swift b/Sources/RemindersLibrary/EKReminder+Encodable.swift index b06f46c..3821b0c 100644 --- a/Sources/RemindersLibrary/EKReminder+Encodable.swift +++ b/Sources/RemindersLibrary/EKReminder+Encodable.swift @@ -3,6 +3,8 @@ import EventKit extension EKReminder: Encodable { private enum EncodingKeys: String, CodingKey { case externalId + case lastModified + case creationDate case title case notes case url @@ -48,6 +50,14 @@ extension EKReminder: Encodable { if let dueDateComponents = self.dueDateComponents { try container.encodeIfPresent(format(dueDateComponents.date), forKey: .dueDate) } + + if let lastModifiedDate = self.lastModifiedDate { + try container.encode(format(lastModifiedDate), forKey: .lastModified) + } + + if let creationDate = self.creationDate { + try container.encode(format(creationDate), forKey: .creationDate) + } } private func format(_ date: Date?) -> String? { diff --git a/Sources/RemindersLibrary/Reminders.swift b/Sources/RemindersLibrary/Reminders.swift index cab7d77..586491a 100644 --- a/Sources/RemindersLibrary/Reminders.swift +++ b/Sources/RemindersLibrary/Reminders.swift @@ -88,6 +88,10 @@ public final class Reminders { func getListNames() -> [String] { return self.getCalendars().map { $0.title } } + + func getDefaultList() -> String { + return Store.defaultCalendarForNewReminders()!.title + } func showLists(outputFormat: OutputFormat) { switch (outputFormat) { @@ -223,7 +227,7 @@ public final class Reminders { } } - func edit(itemAtIndex index: String, onListNamed name: String, newText: String?, newNotes: String?) { + func edit(itemAtIndex index: String, onListNamed name: String, newText: String?, newNotes: String?, dueDateComponents: DateComponents? = nil, clearDueDate: Bool, priority: Priority?, clearPriority: Bool) { let calendar = self.calendar(withName: name) let semaphore = DispatchSemaphore(value: 0) @@ -236,6 +240,32 @@ public final class Reminders { do { reminder.title = newText ?? reminder.title reminder.notes = newNotes ?? reminder.notes + + + if clearPriority { + // https://developer.apple.com/documentation/eventkit/ekreminderpriority/none + reminder.priority = 0 + } + else if priority != nil { + reminder.priority = Int(priority?.value.rawValue ?? UInt(reminder.priority)) + + } + + if clearDueDate || (dueDateComponents != nil) { + // remove previous time-based alarms, leaving location alarms. + reminder.dueDateComponents = nil + for alarm in reminder.alarms ?? [] { + if alarm.structuredLocation != nil { continue } else { reminder.removeAlarm(alarm) } + } + + } + if dueDateComponents != nil { + reminder.dueDateComponents = dueDateComponents + if let dueDate = dueDateComponents?.date, dueDateComponents?.hour != nil { + reminder.addAlarm(EKAlarm(absoluteDate: dueDate)) + } + } + try Store.save(reminder, commit: true) print("Updated reminder '\(reminder.title!)'") } catch let error {