diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/RepetitionList.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/RepetitionList.java index 9cf3205c0..65349cfb9 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/RepetitionList.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/RepetitionList.java @@ -107,6 +107,17 @@ public abstract class RepetitionList @Nullable public abstract Repetition getOldest(); + /** + * Returns the oldest successful repetition in the list. + *

+ * If the list is empty, returns null. Repetitions in the future are + * discarded. + * + * @return oldest sucessful repetition in the list, or null if list is empty. + */ + @Nullable + public abstract Repetition getOldestSuccessful(); + @Nullable /** * Returns the newest repetition in the list. diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/StreakList.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/StreakList.java index 542ed9962..6edea7b34 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/StreakList.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/StreakList.java @@ -113,7 +113,7 @@ public abstract class StreakList Streak newestStreak = getNewestComputed(); if (newestStreak != null) return newestStreak.getStart(); - Repetition oldestRep = habit.getRepetitions().getOldest(); + Repetition oldestRep = habit.getRepetitions().getOldestSuccessful(); if (oldestRep != null) return oldestRep.getTimestamp(); return null; } @@ -131,18 +131,32 @@ public abstract class StreakList { ArrayList list = new ArrayList<>(); Timestamp current = beginning; - list.add(current); + Timestamp lastSuccesful = beginning; + boolean isInStreak = false; - for (int i = 1; i < checks.length; i++) + for (int i = checks.length - 1; i >= 0; --i) { - current = current.plus(1); - int j = checks.length - i - 1; + boolean isCurrentChecked = ( + checks[i] == Checkmark.CHECKED_EXPLICITLY || + checks[i] == Checkmark.CHECKED_IMPLICITLY + ); + if (habit.getData().type == Habit.NUMBER_HABIT || isCurrentChecked) { + lastSuccesful = current; + } + + if (isInStreak && checks[i] == 0) { + list.add(lastSuccesful); + isInStreak = false; + } + if (!isInStreak && isCurrentChecked) { + list.add(current); + isInStreak = true; + } - if ((checks[j + 1] == 0 && checks[j] > 0)) list.add(current); - if ((checks[j + 1] > 0 && checks[j] == 0)) list.add(current.minus(1)); + current = current.plus(1); } - if (list.size() % 2 == 1) list.add(current); + if (isInStreak) list.add(lastSuccesful); return list; } diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryRepetitionList.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryRepetitionList.java index ad3d6e8b5..6019efc13 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryRepetitionList.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/memory/MemoryRepetitionList.java @@ -92,6 +92,29 @@ public class MemoryRepetitionList extends RepetitionList return oldestRep; } + @Nullable + @Override + public Repetition getOldestSuccessful() + { + Timestamp oldestTimestamp = Timestamp.ZERO.plus(1000000); + Repetition oldestRep = null; + + for (Repetition rep : list) + { + if (habit.getData().type == Habit.YES_NO_HABIT + && rep.getValue() == Checkmark.SKIPPED_EXPLICITLY) { + continue; + } + if (rep.getTimestamp().isOlderThan(oldestTimestamp)) + { + oldestRep = rep; + oldestTimestamp = rep.getTimestamp(); + } + } + + return oldestRep; + } + @Nullable @Override public Repetition getNewest() diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLiteRepetitionList.java b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLiteRepetitionList.java index 63e46e5fa..581658494 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLiteRepetitionList.java +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/models/sqlite/SQLiteRepetitionList.java @@ -100,6 +100,13 @@ public class SQLiteRepetitionList extends RepetitionList return list.getOldest(); } + @Override + public Repetition getOldestSuccessful() + { + loadRecords(); + return list.getOldestSuccessful(); + } + @Override public Repetition getNewest() {