Skip to content

Commit

Permalink
Complete recurring tasks by setting their start date to the next recu…
Browse files Browse the repository at this point in the history
…rrence date

Signed-off-by: Sunik Kupfer <[email protected]>
  • Loading branch information
sunkup committed Aug 18, 2023
1 parent 3429db3 commit 452b599
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
35 changes: 32 additions & 3 deletions src/models/task.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ export default class Task {
this._completed = !!comp
this._completedDate = comp ? comp.toJSDate() : null
this._completedDateMoment = moment(this._completedDate, 'YYYYMMDDTHHmmss')
const recur = this.vtodo.getFirstPropertyValue('rrule')
this._recurring = !!recur
this._recurrence = this.vtodo.getFirstPropertyValue('rrule')
this._status = this.vtodo.getFirstPropertyValue('status')
this._note = this.vtodo.getFirstPropertyValue('description') || ''
this._related = this.getParent()?.getFirstValue() || null
Expand Down Expand Up @@ -331,8 +330,17 @@ export default class Task {
return this._completedDateMoment.clone()
}

get recurrence() {
return this._recurrence
}

get recurring() {
return this._recurring
if (this._start === null || this._recurrence === null) {
return false
}
const iter = this._recurrence.iterator(this.start);
iter.next();
return iter.next() !== null
}

get status() {
Expand Down Expand Up @@ -680,6 +688,27 @@ export default class Task {
).toSeconds()
}

/**
* For completing a recurring task, tries to set the task start date to the next recurrence date.
*
* Does nothing if we are at the end of the recurrence (RRULE:UNTIL was reached).
*/
completeRecurring() {
// Get recurrence iterator, starting at start date
const iter = this.recurrence.iterator(this.start);
// Skip the start date itself
iter.next();
// If there is a next recurrence, update the start date to next recurrence date
let nextRecurrence = iter.next();
if (nextRecurrence !== null) {
this.start = nextRecurrence;
// If the due date now lies before start date, clear it
if (this.due !== null && this.due.compare(this.start) < 0) {
this.due = null
}
}
}

/**
* Checks if the task matches the search query
*
Expand Down
6 changes: 6 additions & 0 deletions src/store/tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,12 @@ const actions = {
if (task.calendar.isSharedWithMe && task.class !== 'PUBLIC') {
return
}
// Don't complete a task if it is still recurring, but update its start date instead
if (task.recurring) {
task.completeRecurring()
await context.dispatch('updateTask', task)
return
}
if (task.completed) {
await context.dispatch('setPercentComplete', { task, complete: 0 })
} else {
Expand Down

0 comments on commit 452b599

Please sign in to comment.