Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ format:

lint:
swift format lint --recursive Sources Tests
swiftlint
swiftlint lint --no-cache

test:
scripts/generate-version.sh
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ remindctl complete 1 2 3
remindctl delete 4A83 --force
remindctl status # permission status
remindctl authorize # request permissions

remindctl add "Water plants" --repeat weekly --on sat
remindctl add "Pay rent" --repeat monthly --month-day 1
remindctl add "Sprint retro" --repeat monthly --on thu --setpos 2
remindctl add "File taxes" --repeat yearly --month 4 --month-day 15
remindctl edit 3 --repeat none
```

## Output formats
Expand Down
19 changes: 19 additions & 0 deletions Sources/RemindCore/EventKitStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ public actor RemindersStore {
if let dueDate = draft.dueDate {
reminder.dueDateComponents = calendarComponents(from: dueDate)
}
if let recurrence = draft.recurrence {
reminder.recurrenceRules = [RecurrenceAdapter.rule(from: recurrence)]
}
try eventStore.save(reminder, commit: true)
return ReminderItem(
id: reminder.calendarItemIdentifier,
Expand All @@ -112,6 +115,7 @@ public actor RemindersStore {
completionDate: reminder.completionDate,
priority: ReminderPriority(eventKitValue: Int(reminder.priority)),
dueDate: date(from: reminder.dueDateComponents),
recurrence: reminder.recurrenceRules?.compactMap(RecurrenceAdapter.recurrence(from:)).first,
listID: reminder.calendar.calendarIdentifier,
listName: reminder.calendar.title
)
Expand All @@ -136,6 +140,13 @@ public actor RemindersStore {
if let priority = update.priority {
reminder.priority = priority.eventKitValue
}
if let recurrenceUpdate = update.recurrence {
if let recurrence = recurrenceUpdate {
reminder.recurrenceRules = [RecurrenceAdapter.rule(from: recurrence)]
} else {
reminder.recurrenceRules = nil
}
}
if let listName = update.listName {
reminder.calendar = try calendar(named: listName)
}
Expand All @@ -153,6 +164,7 @@ public actor RemindersStore {
completionDate: reminder.completionDate,
priority: ReminderPriority(eventKitValue: Int(reminder.priority)),
dueDate: date(from: reminder.dueDateComponents),
recurrence: reminder.recurrenceRules?.compactMap(RecurrenceAdapter.recurrence(from:)).first,
listID: reminder.calendar.calendarIdentifier,
listName: reminder.calendar.title
)
Expand All @@ -173,6 +185,7 @@ public actor RemindersStore {
completionDate: reminder.completionDate,
priority: ReminderPriority(eventKitValue: Int(reminder.priority)),
dueDate: date(from: reminder.dueDateComponents),
recurrence: reminder.recurrenceRules?.compactMap(RecurrenceAdapter.recurrence(from:)).first,
listID: reminder.calendar.calendarIdentifier,
listName: reminder.calendar.title
)
Expand All @@ -190,7 +203,9 @@ public actor RemindersStore {
}
return deleted
}
}

extension RemindersStore {
private func requestFullAccess() async throws -> Bool {
try await withCheckedThrowingContinuation { continuation in
eventStore.requestFullAccessToReminders { granted, error in
Expand All @@ -212,6 +227,7 @@ public actor RemindersStore {
let completionDate: Date?
let priority: Int
let dueDateComponents: DateComponents?
let recurrence: ReminderRecurrence?
let listID: String
let listName: String
}
Expand All @@ -228,6 +244,7 @@ public actor RemindersStore {
completionDate: reminder.completionDate,
priority: Int(reminder.priority),
dueDateComponents: reminder.dueDateComponents,
recurrence: reminder.recurrenceRules?.compactMap(RecurrenceAdapter.recurrence(from:)).first,
listID: reminder.calendar.calendarIdentifier,
listName: reminder.calendar.title
)
Expand All @@ -245,6 +262,7 @@ public actor RemindersStore {
completionDate: data.completionDate,
priority: ReminderPriority(eventKitValue: data.priority),
dueDate: date(from: data.dueDateComponents),
recurrence: data.recurrence,
listID: data.listID,
listName: data.listName
)
Expand Down Expand Up @@ -284,6 +302,7 @@ public actor RemindersStore {
completionDate: reminder.completionDate,
priority: ReminderPriority(eventKitValue: Int(reminder.priority)),
dueDate: date(from: reminder.dueDateComponents),
recurrence: reminder.recurrenceRules?.compactMap(RecurrenceAdapter.recurrence(from:)).first,
listID: reminder.calendar.calendarIdentifier,
listName: reminder.calendar.title
)
Expand Down
88 changes: 87 additions & 1 deletion Sources/RemindCore/Models.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,78 @@ public enum ReminderPriority: String, Codable, CaseIterable, Sendable {
}
}

public enum ReminderRecurrenceFrequency: String, Codable, CaseIterable, Sendable {
case daily
case weekly
case monthly
case yearly
}

public enum ReminderWeekday: String, Codable, CaseIterable, Sendable {
case monday = "mon"
case tuesday = "tue"
case wednesday = "wed"
case thursday = "thu"
case friday = "fri"
case saturday = "sat"
case sunday = "sun"

public var displayOrder: Int {
switch self {
case .monday:
return 1
case .tuesday:
return 2
case .wednesday:
return 3
case .thursday:
return 4
case .friday:
return 5
case .saturday:
return 6
case .sunday:
return 7
}
}
}

public enum ReminderRecurrenceEnd: Codable, Sendable, Equatable {
case count(Int)
case until(Date)
}

public struct ReminderRecurrence: Codable, Sendable, Equatable {
public let frequency: ReminderRecurrenceFrequency
public let interval: Int
public let daysOfWeek: [ReminderWeekday]?
public let daysOfMonth: [Int]?
public let setPositions: [Int]?
public let monthsOfYear: [Int]?
public let weeksOfYear: [Int]?
public let end: ReminderRecurrenceEnd?

public init(
frequency: ReminderRecurrenceFrequency,
interval: Int = 1,
daysOfWeek: [ReminderWeekday]? = nil,
daysOfMonth: [Int]? = nil,
setPositions: [Int]? = nil,
monthsOfYear: [Int]? = nil,
weeksOfYear: [Int]? = nil,
end: ReminderRecurrenceEnd? = nil
) {
self.frequency = frequency
self.interval = interval
self.daysOfWeek = daysOfWeek
self.daysOfMonth = daysOfMonth
self.setPositions = setPositions
self.monthsOfYear = monthsOfYear
self.weeksOfYear = weeksOfYear
self.end = end
}
}

public struct ReminderList: Identifiable, Codable, Sendable, Equatable {
public let id: String
public let title: String
Expand All @@ -51,6 +123,7 @@ public struct ReminderItem: Identifiable, Codable, Sendable, Equatable {
public let completionDate: Date?
public let priority: ReminderPriority
public let dueDate: Date?
public let recurrence: ReminderRecurrence?
public let listID: String
public let listName: String

Expand All @@ -62,6 +135,7 @@ public struct ReminderItem: Identifiable, Codable, Sendable, Equatable {
completionDate: Date?,
priority: ReminderPriority,
dueDate: Date?,
recurrence: ReminderRecurrence? = nil,
listID: String,
listName: String
) {
Expand All @@ -72,6 +146,7 @@ public struct ReminderItem: Identifiable, Codable, Sendable, Equatable {
self.completionDate = completionDate
self.priority = priority
self.dueDate = dueDate
self.recurrence = recurrence
self.listID = listID
self.listName = listName
}
Expand All @@ -82,12 +157,20 @@ public struct ReminderDraft: Sendable {
public let notes: String?
public let dueDate: Date?
public let priority: ReminderPriority
public let recurrence: ReminderRecurrence?

public init(title: String, notes: String?, dueDate: Date?, priority: ReminderPriority) {
public init(
title: String,
notes: String?,
dueDate: Date?,
priority: ReminderPriority,
recurrence: ReminderRecurrence? = nil
) {
self.title = title
self.notes = notes
self.dueDate = dueDate
self.priority = priority
self.recurrence = recurrence
}
}

Expand All @@ -96,6 +179,7 @@ public struct ReminderUpdate: Sendable {
public let notes: String?
public let dueDate: Date??
public let priority: ReminderPriority?
public let recurrence: ReminderRecurrence??
public let listName: String?
public let isCompleted: Bool?

Expand All @@ -104,13 +188,15 @@ public struct ReminderUpdate: Sendable {
notes: String? = nil,
dueDate: Date?? = nil,
priority: ReminderPriority? = nil,
recurrence: ReminderRecurrence?? = nil,
listName: String? = nil,
isCompleted: Bool? = nil
) {
self.title = title
self.notes = notes
self.dueDate = dueDate
self.priority = priority
self.recurrence = recurrence
self.listName = listName
self.isCompleted = isCompleted
}
Expand Down
Loading