From ea640a8a171b4ed7be61abc57c915b85d4e92ba2 Mon Sep 17 00:00:00 2001 From: Alinson Xavier Date: Thu, 22 Jun 2017 22:50:27 -0400 Subject: [PATCH] Rebuild order after removing habit --- .../uhabits/receivers/PebbleReceiver.java | 19 +++++----- .../receivers/WidgetControllerTest.java | 3 +- .../commands/ToggleRepetitionCommand.java | 15 +++++--- .../core/models/memory/MemoryHabitList.java | 13 ++++--- .../models/memory/MemoryRepetitionList.java | 1 + .../core/models/memory/MemoryScoreList.java | 9 ++--- .../core/models/memory/MemoryStreakList.java | 14 +++----- .../core/models/sqlite/SQLiteHabitList.java | 35 +++++++++---------- .../habits/list/ListHabitsBehavior.java | 13 +++---- .../habits/show/ShowHabitBehavior.java | 10 ++++-- .../core/ui/widgets/WidgetBehavior.java | 9 +++-- .../core/commands/CommandParserTest.java | 2 +- .../commands/ToggleRepetitionCommandTest.java | 2 +- .../uhabits/core/models/StreakListTest.java | 22 ++---------- .../models/sqlite/SQLiteHabitListTest.java | 15 ++++++++ .../habits/list/HabitCardListCacheTest.java | 2 +- 16 files changed, 96 insertions(+), 88 deletions(-) diff --git a/uhabits-android/src/main/java/org/isoron/uhabits/receivers/PebbleReceiver.java b/uhabits-android/src/main/java/org/isoron/uhabits/receivers/PebbleReceiver.java index 60c67631b..3b4015aa8 100644 --- a/uhabits-android/src/main/java/org/isoron/uhabits/receivers/PebbleReceiver.java +++ b/uhabits-android/src/main/java/org/isoron/uhabits/receivers/PebbleReceiver.java @@ -45,7 +45,7 @@ public class PebbleReceiver extends PebbleDataReceiver @NonNull private Context context; - private HabitList allHabits; + private HabitList habitList; private CommandRunner commandRunner; @@ -76,10 +76,10 @@ public class PebbleReceiver extends PebbleDataReceiver HabitsApplicationComponent component = app.getComponent(); commandRunner = component.getCommandRunner(); taskRunner = component.getTaskRunner(); - allHabits = component.getHabitList(); + habitList = component.getHabitList(); prefs = component.getPreferences(); - if(prefs.isSyncEnabled()) + if (prefs.isSyncEnabled()) context.startService(new Intent(context, SyncService.class)); HabitMatcher build = new HabitMatcherBuilder() @@ -87,7 +87,7 @@ public class PebbleReceiver extends PebbleDataReceiver .setCompletedAllowed(false) .build(); - filteredHabits = allHabits.getFiltered(build); + filteredHabits = habitList.getFiltered(build); PebbleKit.sendAckToPebble(context, transactionId); Log.d("PebbleReceiver", "<-- " + data.getString(0)); @@ -117,8 +117,6 @@ public class PebbleReceiver extends PebbleDataReceiver if (position < 0 || position >= filteredHabits.size()) return; Habit habit = filteredHabits.getByPosition(position.intValue()); - if (habit == null) return; - sendHabit(habit); } @@ -127,12 +125,12 @@ public class PebbleReceiver extends PebbleDataReceiver Long habitId = dict.getInteger(1); if (habitId == null) return; - Habit habit = allHabits.getById(habitId); + Habit habit = habitList.getById(habitId); if (habit == null) return; long today = DateUtils.getStartOfToday(); - commandRunner.execute(new ToggleRepetitionCommand(habit, today), - habitId); + commandRunner.execute( + new ToggleRepetitionCommand(habitList, habit, today), habitId); sendOK(); } @@ -150,8 +148,7 @@ public class PebbleReceiver extends PebbleDataReceiver private void sendDict(@NonNull PebbleDictionary dict) { - PebbleKit.sendDataToPebble(context, - PebbleReceiver.WATCHAPP_UUID, dict); + PebbleKit.sendDataToPebble(context, PebbleReceiver.WATCHAPP_UUID, dict); } private void sendHabit(@NonNull Habit habit) diff --git a/uhabits-android/src/test/java/org/isoron/uhabits/receivers/WidgetControllerTest.java b/uhabits-android/src/test/java/org/isoron/uhabits/receivers/WidgetControllerTest.java index adba7d2b7..8a3966b57 100644 --- a/uhabits-android/src/test/java/org/isoron/uhabits/receivers/WidgetControllerTest.java +++ b/uhabits-android/src/test/java/org/isoron/uhabits/receivers/WidgetControllerTest.java @@ -53,7 +53,8 @@ public class WidgetControllerTest extends BaseAndroidUnitTest habit = fixtures.createEmptyHabit(); commandRunner = mock(CommandRunner.class); notificationTray = mock(NotificationTray.class); - controller = new WidgetBehavior(commandRunner, notificationTray); + controller = + new WidgetBehavior(habitList, commandRunner, notificationTray); } @Test diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/commands/ToggleRepetitionCommand.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/commands/ToggleRepetitionCommand.java index bc9e4b391..e3b2ac793 100644 --- a/uhabits-core/src/main/java/org/isoron/uhabits/core/commands/ToggleRepetitionCommand.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/commands/ToggleRepetitionCommand.java @@ -28,14 +28,20 @@ import org.isoron.uhabits.core.models.*; */ public class ToggleRepetitionCommand extends Command { + @NonNull + private HabitList list; + final long timestamp; @NonNull final Habit habit; - public ToggleRepetitionCommand(@NonNull Habit habit, long timestamp) + public ToggleRepetitionCommand(@NonNull HabitList list, + @NonNull Habit habit, + long timestamp) { super(); + this.list = list; this.timestamp = timestamp; this.habit = habit; } @@ -44,6 +50,7 @@ public class ToggleRepetitionCommand extends Command public void execute() { habit.getRepetitions().toggle(timestamp); + list.update(habit); } @NonNull @@ -81,7 +88,7 @@ public class ToggleRepetitionCommand extends Command { id = command.getId(); Long habitId = command.habit.getId(); - if(habitId == null) throw new RuntimeException("Habit not saved"); + if (habitId == null) throw new RuntimeException("Habit not saved"); this.repTimestamp = command.timestamp; this.habit = habitId; @@ -90,10 +97,10 @@ public class ToggleRepetitionCommand extends Command public ToggleRepetitionCommand toCommand(@NonNull HabitList habitList) { Habit h = habitList.getById(habit); - if(h == null) throw new HabitNotFoundException(); + if (h == null) throw new HabitNotFoundException(); ToggleRepetitionCommand command; - command = new ToggleRepetitionCommand(h, repTimestamp); + command = new ToggleRepetitionCommand(habitList, h, repTimestamp); command.setId(id); return command; } diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryHabitList.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryHabitList.java index f4cbbbf20..dab9ecfd0 100644 --- a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryHabitList.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryHabitList.java @@ -118,6 +118,7 @@ public class MemoryHabitList extends HabitList this.order = order; this.comparator = getComparatorByOrder(order); resort(); + getObservable().notifyListeners(); } private Comparator getComparatorByOrder(Order order) @@ -135,9 +136,10 @@ public class MemoryHabitList extends HabitList Comparator scoreComparator = (h1, h2) -> { - double s1 = h1.getScores().getTodayValue(); - double s2 = h2.getScores().getTodayValue(); - return Double.compare(s2, s1); + Double s1 = h1.getScores().getTodayValue(); + Double s2 = h2.getScores().getTodayValue(); + if (s1.equals(s2)) return nameComparator.compare(h1, h2); + return s2.compareTo(s1); }; if (order == BY_POSITION) return null; @@ -165,6 +167,7 @@ public class MemoryHabitList extends HabitList { throwIfHasParent(); list.remove(habit); + getObservable().notifyListeners(); } @Override @@ -182,6 +185,7 @@ public class MemoryHabitList extends HabitList list.remove(from); list.add(toPos, from); + getObservable().notifyListeners(); } @Override @@ -193,7 +197,8 @@ public class MemoryHabitList extends HabitList @Override public void update(List habits) { - // NOP + resort(); + getObservable().notifyListeners(); } private void throwIfHasParent() diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryRepetitionList.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryRepetitionList.java index 0d63b0529..8bd6441ed 100644 --- a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryRepetitionList.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryRepetitionList.java @@ -127,5 +127,6 @@ public class MemoryRepetitionList extends RepetitionList public void removeAll() { list.clear(); + getObservable().notifyListeners(); } } diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryScoreList.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryScoreList.java index 51b1ba024..cfe1730bf 100644 --- a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryScoreList.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryScoreList.java @@ -41,6 +41,7 @@ public class MemoryScoreList extends ScoreList list.addAll(scores); Collections.sort(list, (s1, s2) -> Long.signum(s2.getTimestamp() - s1.getTimestamp())); + getObservable().notifyListeners(); } @NonNull @@ -71,13 +72,7 @@ public class MemoryScoreList extends ScoreList @Override public void invalidateNewerThan(long timestamp) { - List discard = new LinkedList<>(); - - for (Score s : list) - if (s.getTimestamp() >= timestamp) discard.add(s); - - list.removeAll(discard); - + list.clear(); getObservable().notifyListeners(); } diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryStreakList.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryStreakList.java index 9707c9bbe..a388d7ae1 100644 --- a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryStreakList.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryStreakList.java @@ -19,8 +19,9 @@ package org.isoron.uhabits.core.models.memory; +import android.support.annotation.*; + import org.isoron.uhabits.core.models.*; -import org.isoron.uhabits.core.utils.*; import java.util.*; @@ -48,21 +49,16 @@ public class MemoryStreakList extends StreakList @Override public void invalidateNewerThan(long timestamp) { - LinkedList discard = new LinkedList<>(); - - for (Streak s : list) - if (s.getEnd() >= timestamp - DateUtils.millisecondsInOneDay) - discard.add(s); - - list.removeAll(discard); + list.clear(); observable.notifyListeners(); } @Override - protected void add(List streaks) + protected void add(@NonNull List streaks) { list.addAll(streaks); Collections.sort(list, (s1, s2) -> s2.compareNewer(s1)); + observable.notifyListeners(); } @Override diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitList.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitList.java index bc12b972a..a0e7b9bea 100644 --- a/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitList.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitList.java @@ -89,8 +89,9 @@ public class SQLiteHabitList extends HabitList HabitRecord record = new HabitRecord(); record.copyFrom(habit); - record.position = list.indexOf(habit); + record.position = size(); repository.save(record); + rebuildOrder(); getObservable().notifyListeners(); } @@ -130,6 +131,7 @@ public class SQLiteHabitList extends HabitList public void setOrder(@NonNull Order order) { list.setOrder(order); + getObservable().notifyListeners(); } @Override @@ -146,22 +148,16 @@ public class SQLiteHabitList extends HabitList return list.iterator(); } - private void rebuildOrder() + private synchronized void rebuildOrder() { -// List habits = toList(); -// -// int i = 0; -// for (Habit h : habits) -// { -// HabitRecord record = repository.find(h.getId()); -// if (record == null) -// throw new RuntimeException("habit not in database"); -// -// record.position = i++; -// repository.save(record); -// } -// -// update(habits); + List records = repository.findAll("order by position"); + repository.executeAsTransaction(() -> { + int pos = 0; + for (HabitRecord r : records) { + r.position = pos++; + repository.save(r); + } + }); } @Override @@ -178,6 +174,7 @@ public class SQLiteHabitList extends HabitList repository.remove(record); }); rebuildOrder(); + getObservable().notifyListeners(); } @@ -231,6 +228,7 @@ public class SQLiteHabitList extends HabitList { loadRecords(); rebuildOrder(); + getObservable().notifyListeners(); } @Override @@ -244,11 +242,12 @@ public class SQLiteHabitList extends HabitList public synchronized void update(List habits) { loadRecords(); + list.update(habits); + for (Habit h : habits) { HabitRecord record = repository.find(h.getId()); - if (record == null) - throw new RuntimeException("habit not in database"); + if (record == null) continue; record.copyFrom(h); repository.save(record); } diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.java index e3d57ba34..a6d132440 100644 --- a/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/list/ListHabitsBehavior.java @@ -151,7 +151,8 @@ public class ListHabitsBehavior public void onToggle(@NonNull Habit habit, long timestamp) { - commandRunner.execute(new ToggleRepetitionCommand(habit, timestamp), + commandRunner.execute( + new ToggleRepetitionCommand(habitList, habit, timestamp), habit.getId()); } @@ -168,6 +169,11 @@ public class ListHabitsBehavior String getBugReport() throws IOException; } + public interface DirFinder + { + File getCSVOutputDir(); + } + public interface NumberPickerCallback { void onNumberPicked(double newValue); @@ -189,9 +195,4 @@ public class ListHabitsBehavior void showSendFileScreen(@NonNull String filename); } - - public interface DirFinder - { - File getCSVOutputDir(); - } } diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitBehavior.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitBehavior.java index 5b319957e..9a7ced67e 100644 --- a/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitBehavior.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/screens/habits/show/ShowHabitBehavior.java @@ -28,6 +28,8 @@ import javax.inject.*; public class ShowHabitBehavior { + private HabitList habitList; + @NonNull private final Habit habit; @@ -38,10 +40,12 @@ public class ShowHabitBehavior private Screen screen; @Inject - public ShowHabitBehavior(@NonNull CommandRunner commandRunner, + public ShowHabitBehavior(@NonNull HabitList habitList, + @NonNull CommandRunner commandRunner, @NonNull Habit habit, @NonNull Screen screen) { + this.habitList = habitList; this.habit = habit; this.commandRunner = commandRunner; this.screen = screen; @@ -54,8 +58,8 @@ public class ShowHabitBehavior public void onToggleCheckmark(long timestamp) { - commandRunner.execute(new ToggleRepetitionCommand(habit, timestamp), - null); + commandRunner.execute( + new ToggleRepetitionCommand(habitList, habit, timestamp), null); } public interface Screen diff --git a/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/widgets/WidgetBehavior.java b/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/widgets/WidgetBehavior.java index 217a7b6bc..ff79c6578 100644 --- a/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/widgets/WidgetBehavior.java +++ b/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/widgets/WidgetBehavior.java @@ -29,15 +29,19 @@ import javax.inject.*; public class WidgetBehavior { + private HabitList habitList; + @NonNull private final CommandRunner commandRunner; private NotificationTray notificationTray; @Inject - public WidgetBehavior(@NonNull CommandRunner commandRunner, + public WidgetBehavior(@NonNull HabitList habitList, + @NonNull CommandRunner commandRunner, @NonNull NotificationTray notificationTray) { + this.habitList = habitList; this.commandRunner = commandRunner; this.notificationTray = notificationTray; } @@ -64,7 +68,8 @@ public class WidgetBehavior private void performToggle(@NonNull Habit habit, long timestamp) { - commandRunner.execute(new ToggleRepetitionCommand(habit, timestamp), + commandRunner.execute( + new ToggleRepetitionCommand(habitList, habit, timestamp), habit.getId()); } } diff --git a/uhabits-core/src/test/java/org/isoron/uhabits/core/commands/CommandParserTest.java b/uhabits-core/src/test/java/org/isoron/uhabits/core/commands/CommandParserTest.java index a637ba3e1..376804068 100644 --- a/uhabits-core/src/test/java/org/isoron/uhabits/core/commands/CommandParserTest.java +++ b/uhabits-core/src/test/java/org/isoron/uhabits/core/commands/CommandParserTest.java @@ -140,7 +140,7 @@ public class CommandParserTest extends BaseUnitTest public void testDecodeToggleCommand() throws JSONException { ToggleRepetitionCommand original, decoded; - original = new ToggleRepetitionCommand(habit, 1000); + original = new ToggleRepetitionCommand(habitList, habit, 1000); decoded = (ToggleRepetitionCommand) parser.parse(original.toJson()); MatcherAssert.assertThat(decoded.getId(), equalTo(original.getId())); diff --git a/uhabits-core/src/test/java/org/isoron/uhabits/core/commands/ToggleRepetitionCommandTest.java b/uhabits-core/src/test/java/org/isoron/uhabits/core/commands/ToggleRepetitionCommandTest.java index 3feed8ea2..6fdc0e571 100644 --- a/uhabits-core/src/test/java/org/isoron/uhabits/core/commands/ToggleRepetitionCommandTest.java +++ b/uhabits-core/src/test/java/org/isoron/uhabits/core/commands/ToggleRepetitionCommandTest.java @@ -45,7 +45,7 @@ public class ToggleRepetitionCommandTest extends BaseUnitTest habitList.add(habit); today = DateUtils.getStartOfToday(); - command = new ToggleRepetitionCommand(habit, today); + command = new ToggleRepetitionCommand(habitList, habit, today); } @Test diff --git a/uhabits-core/src/test/java/org/isoron/uhabits/core/models/StreakListTest.java b/uhabits-core/src/test/java/org/isoron/uhabits/core/models/StreakListTest.java index 3890273dc..77db730c4 100644 --- a/uhabits-core/src/test/java/org/isoron/uhabits/core/models/StreakListTest.java +++ b/uhabits-core/src/test/java/org/isoron/uhabits/core/models/StreakListTest.java @@ -25,6 +25,7 @@ import org.junit.*; import java.util.*; +import static junit.framework.TestCase.*; import static org.hamcrest.CoreMatchers.*; import static org.hamcrest.MatcherAssert.*; import static org.mockito.Mockito.*; @@ -70,11 +71,6 @@ public class StreakListTest extends BaseUnitTest public void testFindBeginning_withLongHistory() { streaks.rebuild(); - assertThat(streaks.findBeginning(), equalTo(today - day)); - - streaks.invalidateNewerThan(today - 20 * day); - assertThat(streaks.findBeginning(), equalTo(today - 28 * day)); - streaks.invalidateNewerThan(0); assertThat(streaks.findBeginning(), equalTo(today - 120 * day)); } @@ -111,20 +107,6 @@ public class StreakListTest extends BaseUnitTest assertThat(best.get(1).getLength(), equalTo(6L)); } - @Test - public void testGetNewestComputed() throws Exception - { - Streak s = streaks.getNewestComputed(); - assertThat(s.getEnd(), equalTo(today)); - assertThat(s.getStart(), equalTo(today - day)); - - streaks.invalidateNewerThan(today - 8 * day); - - s = streaks.getNewestComputed(); - assertThat(s.getEnd(), equalTo(today - 12 * day)); - assertThat(s.getStart(), equalTo(today - 12 * day)); - } - @Test public void testInvalidateNewer() { @@ -135,6 +117,6 @@ public class StreakListTest extends BaseUnitTest verify(listener).onModelChange(); s = streaks.getNewestComputed(); - assertThat(s.getEnd(), equalTo(today - 12 * day)); + assertNull(s); } } \ No newline at end of file diff --git a/uhabits-core/src/test/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitListTest.java b/uhabits-core/src/test/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitListTest.java index 120e2aff7..61d153ea8 100644 --- a/uhabits-core/src/test/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitListTest.java +++ b/uhabits-core/src/test/java/org/isoron/uhabits/core/models/sqlite/SQLiteHabitListTest.java @@ -168,4 +168,19 @@ public class SQLiteHabitListTest extends BaseUnitTest h2.setId(1000L); assertThat(habitList.indexOf(h2), equalTo(-1)); } + + @Test + public void testRemove() throws Exception + { + Habit h = habitList.getByPosition(2); + habitList.remove(h); + assertThat(habitList.indexOf(h), equalTo(-1)); + + HabitRecord rec = repository.find(2L); + assertNull(rec); + + rec = repository.find(3L); + assertNotNull(rec); + assertThat(rec.position, equalTo(2)); + } } \ No newline at end of file diff --git a/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/screens/habits/list/HabitCardListCacheTest.java b/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/screens/habits/list/HabitCardListCacheTest.java index e758f5b47..9c28255ce 100644 --- a/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/screens/habits/list/HabitCardListCacheTest.java +++ b/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/screens/habits/list/HabitCardListCacheTest.java @@ -86,7 +86,7 @@ public class HabitCardListCacheTest extends BaseUnitTest { Habit h2 = habitList.getByPosition(2); long today = DateUtils.getStartOfToday(); - commandRunner.execute(new ToggleRepetitionCommand(h2, today), + commandRunner.execute(new ToggleRepetitionCommand(habitList, h2, today), h2.getId()); verify(listener).onItemChanged(2);