Repeat from completion will now move forward from completion date to the next day in the recurrence instead of skipping a week. The old behavior is still available as repeat every 2 weeks from completion. The new behavior allows the use case of a weekly repeating event on specific days of the week and ensures upcoming events will not be missed.

pull/14/head
Sam Bosley 13 years ago
parent 408eb95bad
commit 132f27963c

@ -3,6 +3,7 @@ package com.todoroo.astrid.repeats;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
@ -130,18 +131,40 @@ public class RepeatTaskCompleteListener extends BroadcastReceiver {
private static long handleWeeklyRepeatAfterComplete(RRule rrule, Date original, DateValue startDateAsDV) {
List<WeekdayNum> byDay = rrule.getByDay();
rrule.setByDay(Collections.EMPTY_LIST);
long newDate = original.getTime();
newDate += DateUtilities.ONE_WEEK * (rrule.getInterval() - 1);
Calendar date = Calendar.getInstance();
date.setTimeInMillis(invokeRecurrence(rrule, original, startDateAsDV));
outer: while(true) {
for(WeekdayNum weekdayNum : byDay)
if(weekdayNum.wday.javaDayNum == date.get(Calendar.DAY_OF_WEEK))
break outer;
date.setTimeInMillis(newDate);
Collections.sort(byDay, weekdayCompare);
WeekdayNum next = findNextWeekday(byDay, date);
do {
date.add(Calendar.DATE, 1);
}
} while (date.get(Calendar.DAY_OF_WEEK) != next.wday.javaDayNum);
return date.getTimeInMillis();
}
private static Comparator<WeekdayNum> weekdayCompare = new Comparator<WeekdayNum>() {
@Override
public int compare(WeekdayNum object1, WeekdayNum object2) {
return object1.wday.javaDayNum - object2.wday.javaDayNum;
}
};
private static WeekdayNum findNextWeekday(List<WeekdayNum> byDay,
Calendar date) {
WeekdayNum next = byDay.get(0);
for (int i = 0; i < byDay.size(); i++) {
WeekdayNum weekday = byDay.get(i);
if (weekday.wday.javaDayNum > date.get(Calendar.DAY_OF_WEEK)) {
return weekday;
}
}
return next;
}
private static long invokeRecurrence(RRule rrule, Date original,
DateValue startDateAsDV) {
long newDueDate = -1;

@ -168,7 +168,8 @@ public class AdvancedRepeatTests extends TodorooTestCase {
for(Weekday wday : Weekday.values()) {
buildRRule(1, Frequency.WEEKLY, wday);
computeNextDueDate();
long expected = getDate(DateUtilities.now(), NEXT, wday.javaDayNum);
long expected = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, THIS, wday.javaDayNum);
nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate);
assertDateEquals(nextDueDate, expected);
}
@ -178,9 +179,10 @@ public class AdvancedRepeatTests extends TodorooTestCase {
continue;
buildRRule(1, Frequency.WEEKLY, wday1, wday2);
long nextOne = getDate(DateUtilities.now(), NEXT, wday1.javaDayNum);
long nextTwo = getDate(DateUtilities.now(), NEXT, wday2.javaDayNum);
long nextOne = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, THIS, wday1.javaDayNum);
long nextTwo = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, THIS, wday2.javaDayNum);
computeNextDueDate();
nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate);
assertDateEquals(nextDueDate, Math.min(nextOne, nextTwo));
}
}
@ -193,7 +195,8 @@ public class AdvancedRepeatTests extends TodorooTestCase {
for(Weekday wday : Weekday.values()) {
buildRRule(2, Frequency.WEEKLY, wday);
computeNextDueDate();
long expected = getDate(DateUtilities.now(), NEXT_NEXT, wday.javaDayNum);
long expected = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, NEXT, wday.javaDayNum);
nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate);
assertDateEquals(nextDueDate, expected);
}
@ -203,9 +206,10 @@ public class AdvancedRepeatTests extends TodorooTestCase {
continue;
buildRRule(2, Frequency.WEEKLY, wday1, wday2);
long nextOne = getDate(DateUtilities.now(), NEXT_NEXT, wday1.javaDayNum);
long nextTwo = getDate(DateUtilities.now(), NEXT_NEXT, wday2.javaDayNum);
long nextOne = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, NEXT, wday1.javaDayNum);
long nextTwo = getDate(DateUtilities.now() + DateUtilities.ONE_DAY, NEXT, wday2.javaDayNum);
computeNextDueDate();
nextDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, nextDueDate);
assertDateEquals(nextDueDate, Math.min(nextOne, nextTwo));
}
}

@ -132,7 +132,7 @@ public class NewRepeatTests<REMOTE_MODEL> extends DatabaseTestCase {
if (rrule == null) {
rrule = new RRule();
rrule.setFreq(frequency);
int interval = 5;
int interval = 2;
rrule.setInterval(interval);
}
t.setValue(Task.RECURRENCE, rrule.toIcal());
@ -228,7 +228,7 @@ public class NewRepeatTests<REMOTE_MODEL> extends DatabaseTestCase {
}
if (fromCompletion) {
result += DateUtilities.ONE_WEEK * rrule.getInterval();
result += DateUtilities.ONE_WEEK * (rrule.getInterval() - 1);
}
result += DateUtilities.ONE_DAY * daysToAdd;
return result;

Loading…
Cancel
Save