make ReminderScheduler remember if a reminder is custom (postponed) or not

Without this, scheduling of any habit caused all other habits to be rescheduled
at their configured time, even if they had been snoozed (thus discarding
the snooze). This includes when the app gets closed and reschedules all habits
the next time it is launched.
pull/355/head
Luboš Luňák 8 years ago
parent 519d24b148
commit dd5f621c38

@ -94,7 +94,7 @@ public class ReminderController
public void snoozeNotificationSetReminderTime(@NonNull Habit habit, long reminderTime)
{
reminderScheduler.schedule(habit, reminderTime);
reminderScheduler.scheduleHabitAtCustom(habit, reminderTime);
notificationTray.cancel(habit);
}

@ -72,7 +72,7 @@ public class ReminderControllerTest extends BaseAndroidJVMTest
controller.onSnooze(habit,null);
verify(reminderScheduler).schedule(habit, nowTz + 900000);
verify(reminderScheduler).scheduleHabitAtCustom(habit, nowTz + 900000);
verify(notificationTray).cancel(habit);
}

@ -69,6 +69,14 @@ public class DeleteHabitsCommand extends Command
throw new UnsupportedOperationException();
}
public List<Long> getHabitIds()
{
List<Long> list = new LinkedList<Long>();
for( Habit habit: selected)
list.add(habit.getId());
return list;
}
public static class Record
{
@NonNull

@ -137,4 +137,6 @@ public class EditHabitCommand extends Command
return command;
}
}
public Long getHabitId() { return savedId; }
}

@ -41,6 +41,8 @@ public class ReminderScheduler implements CommandRunner.Listener
private SystemScheduler sys;
private Map< Long, Long > customReminders; // Habit id, Timestamp
@Inject
public ReminderScheduler(@NonNull CommandRunner commandRunner,
@NonNull HabitList habitList,
@ -49,6 +51,7 @@ public class ReminderScheduler implements CommandRunner.Listener
this.commandRunner = commandRunner;
this.habitList = habitList;
this.sys = sys;
customReminders = new HashMap< Long, Long >();
}
@Override
@ -57,10 +60,45 @@ public class ReminderScheduler implements CommandRunner.Listener
{
if(command instanceof ToggleRepetitionCommand) return;
if(command instanceof ChangeHabitColorCommand) return;
if(command instanceof EditHabitCommand)
{
Long habitId = ((EditHabitCommand)command).getHabitId();
Habit habit = habitList.getById( habitId );
customReminders.remove( habitId );
scheduleHabit( habit );
return;
}
if(command instanceof DeleteHabitsCommand)
{
List<Long> habitIds = ((DeleteHabitsCommand)command).getHabitIds();
for(Long id : habitIds)
customReminders.remove( id );
return;
}
scheduleAll();
}
public void schedule(@NonNull Habit habit, @Nullable Long reminderTime)
public void scheduleHabit(@NonNull Habit habit)
{
Long reminderTime = null;
if( customReminders.containsKey( habit.getId()))
reminderTime = customReminders.get( habit.getId());
scheduleInternal(habit, reminderTime);
}
public void scheduleHabitAtReminder(@NonNull Habit habit)
{
customReminders.remove( habit.getId());
scheduleInternal( habit, null );
}
public void scheduleHabitAtCustom(@NonNull Habit habit, @NonNull Long reminderTime)
{
customReminders.put( habit.getId(), reminderTime );
scheduleInternal(habit, reminderTime);
}
private void scheduleInternal(@NonNull Habit habit, @Nullable Long reminderTime)
{
if (!habit.hasReminder()) return;
if (habit.isArchived()) return;
@ -76,7 +114,7 @@ public class ReminderScheduler implements CommandRunner.Listener
HabitList reminderHabits =
habitList.getFiltered(HabitMatcher.WITH_ALARM);
for (Habit habit : reminderHabits)
schedule(habit, null);
scheduleHabit(habit);
}
public void startListening()

@ -20,6 +20,7 @@
package org.isoron.uhabits.core.reminders;
import org.isoron.uhabits.core.*;
import org.isoron.uhabits.core.commands.*;
import org.isoron.uhabits.core.models.*;
import org.isoron.uhabits.core.utils.*;
import org.junit.*;
@ -118,10 +119,69 @@ public class ReminderSchedulerTest extends BaseUnitTest
@Test
public void testSchedule_withoutReminder()
{
reminderScheduler.schedule(habit, null);
reminderScheduler.scheduleHabit(habit);
Mockito.verifyZeroInteractions(sys);
}
@Test
public void testOnCommand() throws Exception
{
long now = timestamp(2015, 1, 26, 8, 0);
DateUtils.setFixedLocalTime(now);
Habit h1 = fixtures.createEmptyHabit();
h1.setReminder(new Reminder(14, 30, WeekdayList.EVERY_DAY));
habitList.add(h1);
reminderScheduler.scheduleAll();
verify(sys).scheduleShowReminder(eq(timestamp(2015, 1, 26, 18, 30)),
eq(h1), anyLong());
reset(sys);
reminderScheduler.scheduleHabitAtCustom(h1,
DateUtils.applyTimezone( timestamp( 2015, 1, 26, 15, 15)));
verify(sys).scheduleShowReminder(eq(timestamp(2015, 1, 26, 19, 15)),
eq(h1), anyLong());
Habit h2Model = fixtures.createEmptyHabit();
h2Model.setReminder(new Reminder(15,30, WeekdayList.EVERY_DAY));
CreateHabitCommand createCommand = new CreateHabitCommand(modelFactory,habitList,h2Model);
createCommand.execute();
reminderScheduler.onCommandExecuted(createCommand, null);
Habit h2 = habitList.getByPosition(1);
verify(sys).scheduleShowReminder(eq(timestamp(2015, 1, 26, 19, 30)),
eq(h2), anyLong());
verify(sys, never()).scheduleShowReminder(eq(timestamp(2015, 1, 26, 18, 30)),
eq(h1), anyLong());
verify(sys,never()).scheduleShowReminder(eq(timestamp(2015, 1, 26, 19, 30)),
eq(h1), anyLong());
Habit h1New = fixtures.createEmptyHabit();
h1New.copyFrom(h1);
h1New.setReminder(new Reminder(17,30, WeekdayList.EVERY_DAY));
EditHabitCommand editCommand = new EditHabitCommand(modelFactory,habitList,h1,h1New);
editCommand.execute();
reminderScheduler.onCommandExecuted(editCommand, null);
verify(sys).scheduleShowReminder(eq(timestamp(2015, 1, 26, 21, 30)),
eq(h1), anyLong());
verify(sys,never()).scheduleShowReminder(eq(timestamp(2015, 1, 26, 21, 30)),
eq(h2), anyLong());
h1.setReminder(new Reminder( 18, 30, WeekdayList.EVERY_DAY));
reminderScheduler.scheduleHabitAtCustom(h1,
DateUtils.applyTimezone( timestamp( 2015, 1, 26,18, 45)));
reminderScheduler.scheduleAll();
verify(sys, atLeastOnce()).scheduleShowReminder(eq(timestamp(2015, 1, 26, 22, 45)),
eq(h1), anyLong());
verify(sys, never()).scheduleShowReminder(eq(timestamp(2015, 1, 26, 22, 30)),
eq(h1), anyLong());
}
public long timestamp(int year, int month, int day, int hour, int minute)
{
Calendar cal = DateUtils.getStartOfTodayCalendar();
@ -133,7 +193,7 @@ public class ReminderSchedulerTest extends BaseUnitTest
long expectedCheckmarkTime,
long expectedReminderTime)
{
reminderScheduler.schedule(habit, atTime);
reminderScheduler.scheduleHabitAtCustom(habit, atTime);
verify(sys).scheduleShowReminder(expectedReminderTime, habit,
expectedCheckmarkTime);
}

Loading…
Cancel
Save