fix: match reminder paring with caldav spec and tasks.org code
All checks were successful
continuous-integration/drone/pr Build is passing
All checks were successful
continuous-integration/drone/pr Build is passing
Follow the RFC more strictly: https://icalendar.org/iCalendar-RFC-5545/3-8-6-3-trigger.html Compare with tasks.org, to make sure their alarms will be correctly synced: https://github.com/tasks/tasks/blob/main/app/src/main/java/org/tasks/caldav/extensions/VAlarm.kt
This commit is contained in:
parent
3e49c27ad1
commit
287a21da93
|
@ -204,13 +204,10 @@ func ParseAlarms(alarms []Alarm, taskDescription string) (caldavalarms string) {
|
||||||
caldavalarms += `
|
caldavalarms += `
|
||||||
BEGIN:VALARM`
|
BEGIN:VALARM`
|
||||||
switch a.RelativeTo {
|
switch a.RelativeTo {
|
||||||
case models.ReminderRelationDueDate:
|
|
||||||
caldavalarms += `
|
|
||||||
TRIGGER:` + makeCalDavDuration(a.Duration)
|
|
||||||
case models.ReminderRelationStartDate:
|
case models.ReminderRelationStartDate:
|
||||||
caldavalarms += `
|
caldavalarms += `
|
||||||
TRIGGER;RELATED=START:` + makeCalDavDuration(a.Duration)
|
TRIGGER;RELATED=START:` + makeCalDavDuration(a.Duration)
|
||||||
case models.ReminderRelationEndDate:
|
case models.ReminderRelationEndDate, models.ReminderRelationDueDate:
|
||||||
caldavalarms += `
|
caldavalarms += `
|
||||||
TRIGGER;RELATED=END:` + makeCalDavDuration(a.Duration)
|
TRIGGER;RELATED=END:` + makeCalDavDuration(a.Duration)
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -311,7 +311,7 @@ ACTION:DISPLAY
|
||||||
DESCRIPTION:alarm description
|
DESCRIPTION:alarm description
|
||||||
END:VALARM
|
END:VALARM
|
||||||
BEGIN:VALARM
|
BEGIN:VALARM
|
||||||
TRIGGER:-PT2H0M0S
|
TRIGGER;RELATED=END:-PT2H0M0S
|
||||||
ACTION:DISPLAY
|
ACTION:DISPLAY
|
||||||
DESCRIPTION:Todo #1
|
DESCRIPTION:Todo #1
|
||||||
END:VALARM
|
END:VALARM
|
||||||
|
|
|
@ -141,53 +141,56 @@ func ParseTaskFromVTODO(content string) (vTask *models.Task, err error) {
|
||||||
vTask.EndDate = vTask.StartDate.Add(duration)
|
vTask.EndDate = vTask.StartDate.Add(duration)
|
||||||
}
|
}
|
||||||
|
|
||||||
reminders := make([]*models.TaskReminder, 0)
|
|
||||||
for _, vAlarm := range vTodo.SubComponents() {
|
for _, vAlarm := range vTodo.SubComponents() {
|
||||||
if vAlarm, ok := vAlarm.(*ics.VAlarm); ok {
|
if vAlarm, ok := vAlarm.(*ics.VAlarm); ok {
|
||||||
reminders = parseVAlarm(vAlarm, reminders)
|
vTask = parseVAlarm(vAlarm, vTask)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(reminders) > 0 {
|
|
||||||
vTask.Reminders = reminders
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseVAlarm(vAlarm *ics.VAlarm, reminders []*models.TaskReminder) []*models.TaskReminder {
|
func parseVAlarm(vAlarm *ics.VAlarm, vTask *models.Task) *models.Task {
|
||||||
for _, property := range vAlarm.UnknownPropertiesIANAProperties() {
|
for _, property := range vAlarm.UnknownPropertiesIANAProperties() {
|
||||||
if property.IANAToken == "TRIGGER" {
|
if property.IANAToken == "TRIGGER" {
|
||||||
switch {
|
if contains(property.ICalParameters["VALUE"], "DATE-TIME") {
|
||||||
case len(property.ICalParameters["VALUE"]) > 0:
|
// Example: TRIGGER;VALUE=DATE-TIME:20181201T011210Z
|
||||||
if property.ICalParameters["VALUE"][0] == "DATE-TIME" {
|
vTask.Reminders = append(vTask.Reminders, &models.TaskReminder{
|
||||||
// Example: TRIGGER;VALUE=DATE-TIME:20181201T011210Z
|
Reminder: caldavTimeToTimestamp(property.Value)})
|
||||||
reminders = append(reminders, &models.TaskReminder{
|
} else {
|
||||||
Reminder: caldavTimeToTimestamp(property.Value)})
|
if contains(property.ICalParameters["RELATED"], "END") {
|
||||||
}
|
// Example: TRIGGER;RELATED=END:-P2D
|
||||||
case len(property.ICalParameters["RELATED"]) > 0:
|
duration := utils.ParseISO8601Duration(property.Value)
|
||||||
duration := utils.ParseISO8601Duration(property.Value)
|
if vTask.EndDate.IsZero() {
|
||||||
switch property.ICalParameters["RELATED"][0] {
|
vTask.Reminders = append(vTask.Reminders, &models.TaskReminder{
|
||||||
case "START":
|
RelativePeriod: int64(duration.Seconds()),
|
||||||
|
RelativeTo: models.ReminderRelationDueDate})
|
||||||
|
} else {
|
||||||
|
vTask.Reminders = append(vTask.Reminders, &models.TaskReminder{
|
||||||
|
RelativePeriod: int64(duration.Seconds()),
|
||||||
|
RelativeTo: models.ReminderRelationEndDate})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// Example: TRIGGER;RELATED=START:-P2D
|
// Example: TRIGGER;RELATED=START:-P2D
|
||||||
reminders = append(reminders, &models.TaskReminder{
|
// Example: TRIGGER:-PT60M
|
||||||
|
duration := utils.ParseISO8601Duration(property.Value)
|
||||||
|
vTask.Reminders = append(vTask.Reminders, &models.TaskReminder{
|
||||||
RelativePeriod: int64(duration.Seconds()),
|
RelativePeriod: int64(duration.Seconds()),
|
||||||
RelativeTo: models.ReminderRelationStartDate})
|
RelativeTo: models.ReminderRelationStartDate})
|
||||||
case "END":
|
|
||||||
// Example: TRIGGER;RELATED=END:-P2D
|
|
||||||
reminders = append(reminders, &models.TaskReminder{
|
|
||||||
RelativePeriod: int64(duration.Seconds()),
|
|
||||||
RelativeTo: models.ReminderRelationEndDate})
|
|
||||||
}
|
}
|
||||||
default:
|
|
||||||
duration := utils.ParseISO8601Duration(property.Value)
|
|
||||||
// Example: TRIGGER:-PT60M
|
|
||||||
reminders = append(reminders, &models.TaskReminder{
|
|
||||||
RelativePeriod: int64(duration.Seconds()),
|
|
||||||
RelativeTo: models.ReminderRelationDueDate})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return reminders
|
return vTask
|
||||||
|
}
|
||||||
|
|
||||||
|
func contains(array []string, str string) bool {
|
||||||
|
for _, value := range array {
|
||||||
|
if value == str {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://tools.ietf.org/html/rfc5545#section-3.3.5
|
// https://tools.ietf.org/html/rfc5545#section-3.3.5
|
||||||
|
|
|
@ -170,7 +170,11 @@ TRIGGER:PT0S
|
||||||
ACTION:DISPLAY
|
ACTION:DISPLAY
|
||||||
END:VALARM
|
END:VALARM
|
||||||
BEGIN:VALARM
|
BEGIN:VALARM
|
||||||
TRIGGER:-PT60M
|
TRIGGER;VALUE=DURATION:-PT60M
|
||||||
|
ACTION:DISPLAY
|
||||||
|
END:VALARM
|
||||||
|
BEGIN:VALARM
|
||||||
|
TRIGGER:-PT61M
|
||||||
ACTION:DISPLAY
|
ACTION:DISPLAY
|
||||||
END:VALARM
|
END:VALARM
|
||||||
BEGIN:VALARM
|
BEGIN:VALARM
|
||||||
|
@ -192,19 +196,23 @@ END:VCALENDAR`,
|
||||||
DueDate: time.Date(2023, 3, 4, 15, 0, 0, 0, config.GetTimeZone()),
|
DueDate: time.Date(2023, 3, 4, 15, 0, 0, 0, config.GetTimeZone()),
|
||||||
Reminders: []*models.TaskReminder{
|
Reminders: []*models.TaskReminder{
|
||||||
{
|
{
|
||||||
RelativeTo: models.ReminderRelationDueDate,
|
RelativeTo: models.ReminderRelationStartDate,
|
||||||
RelativePeriod: 0,
|
RelativePeriod: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
RelativeTo: models.ReminderRelationDueDate,
|
RelativeTo: models.ReminderRelationStartDate,
|
||||||
RelativePeriod: -3600,
|
RelativePeriod: -3600,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
RelativeTo: models.ReminderRelationStartDate,
|
||||||
|
RelativePeriod: -3660,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
RelativeTo: models.ReminderRelationStartDate,
|
RelativeTo: models.ReminderRelationStartDate,
|
||||||
RelativePeriod: -86400,
|
RelativePeriod: -86400,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
RelativeTo: models.ReminderRelationEndDate,
|
RelativeTo: models.ReminderRelationDueDate,
|
||||||
RelativePeriod: -1800,
|
RelativePeriod: -1800,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -309,7 +317,7 @@ ACTION:DISPLAY
|
||||||
DESCRIPTION:Task 1
|
DESCRIPTION:Task 1
|
||||||
END:VALARM
|
END:VALARM
|
||||||
BEGIN:VALARM
|
BEGIN:VALARM
|
||||||
TRIGGER:-PT1H0M0S
|
TRIGGER;RELATED=END:-PT1H0M0S
|
||||||
ACTION:DISPLAY
|
ACTION:DISPLAY
|
||||||
DESCRIPTION:Task 1
|
DESCRIPTION:Task 1
|
||||||
END:VALARM
|
END:VALARM
|
||||||
|
|
Loading…
Reference in New Issue
Block a user