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()
{