|
|
|
@ -89,50 +89,12 @@ public abstract class StreakList
|
|
|
|
|
@NonNull
|
|
|
|
|
protected List<Streak> checkmarksToStreaks(Timestamp beginning, int[] checks)
|
|
|
|
|
{
|
|
|
|
|
ArrayList<Timestamp> transitions = getTransitions(beginning, checks);
|
|
|
|
|
|
|
|
|
|
List<Streak> streaks = new LinkedList<>();
|
|
|
|
|
for (int i = 0; i < transitions.size(); i += 2)
|
|
|
|
|
{
|
|
|
|
|
Timestamp start = transitions.get(i);
|
|
|
|
|
Timestamp end = transitions.get(i + 1);
|
|
|
|
|
streaks.add(new Streak(start, end));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return streaks;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Finds the place where we should start when recomputing the streaks.
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
@Nullable
|
|
|
|
|
protected Timestamp findBeginning()
|
|
|
|
|
{
|
|
|
|
|
Streak newestStreak = getNewestComputed();
|
|
|
|
|
if (newestStreak != null) return newestStreak.getStart();
|
|
|
|
|
|
|
|
|
|
Repetition oldestRep = habit.getRepetitions().getOldestSuccessful();
|
|
|
|
|
if (oldestRep != null) return oldestRep.getTimestamp();
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the timestamps where there was a transition from performing a
|
|
|
|
|
* habit to not performing a habit, and vice-versa.
|
|
|
|
|
*
|
|
|
|
|
* @param beginning the timestamp for the first checkmark
|
|
|
|
|
* @param checks the checkmarks, ordered by decreasing timestamp
|
|
|
|
|
* @return the list of transitions
|
|
|
|
|
*/
|
|
|
|
|
@NonNull
|
|
|
|
|
protected ArrayList<Timestamp> getTransitions(Timestamp beginning, int[] checks)
|
|
|
|
|
{
|
|
|
|
|
ArrayList<Timestamp> list = new ArrayList<>();
|
|
|
|
|
Timestamp current = beginning;
|
|
|
|
|
Timestamp lastChecked = beginning;
|
|
|
|
|
Timestamp streakStart = beginning;
|
|
|
|
|
boolean isInStreak = false;
|
|
|
|
|
int skipDaysInStreak = 0;
|
|
|
|
|
|
|
|
|
|
for (int i = checks.length - 1; i >= 0; --i)
|
|
|
|
|
{
|
|
|
|
@ -149,24 +111,47 @@ public abstract class StreakList
|
|
|
|
|
if (habit.getData().type == Habit.NUMBER_HABIT || isCurrentChecked)
|
|
|
|
|
lastChecked = current;
|
|
|
|
|
|
|
|
|
|
if (isInStreak && isCurrentUnchecked)
|
|
|
|
|
if (isInStreak && checks[i] == Checkmark.SKIPPED_EXPLICITLY)
|
|
|
|
|
skipDaysInStreak += 1;
|
|
|
|
|
else if (isInStreak && isCurrentUnchecked)
|
|
|
|
|
{
|
|
|
|
|
list.add(lastChecked);
|
|
|
|
|
skipDaysInStreak -= lastChecked.daysUntil(current) - 1;
|
|
|
|
|
streaks.add(new Streak(streakStart, lastChecked, skipDaysInStreak));
|
|
|
|
|
isInStreak = false;
|
|
|
|
|
}
|
|
|
|
|
if (!isInStreak && isCurrentChecked)
|
|
|
|
|
else if (!isInStreak && isCurrentChecked)
|
|
|
|
|
{
|
|
|
|
|
list.add(current);
|
|
|
|
|
streakStart = current;
|
|
|
|
|
isInStreak = true;
|
|
|
|
|
skipDaysInStreak = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
current = current.plus(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isInStreak)
|
|
|
|
|
list.add(lastChecked);
|
|
|
|
|
{
|
|
|
|
|
skipDaysInStreak -= lastChecked.daysUntil(current) - 1;
|
|
|
|
|
streaks.add(new Streak(streakStart, lastChecked, skipDaysInStreak));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return list;
|
|
|
|
|
return streaks;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Finds the place where we should start when recomputing the streaks.
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
@Nullable
|
|
|
|
|
protected Timestamp findBeginning()
|
|
|
|
|
{
|
|
|
|
|
Streak newestStreak = getNewestComputed();
|
|
|
|
|
if (newestStreak != null) return newestStreak.getStart();
|
|
|
|
|
|
|
|
|
|
Repetition oldestRep = habit.getRepetitions().getOldestSuccessful();
|
|
|
|
|
if (oldestRep != null) return oldestRep.getTimestamp();
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected abstract void add(@NonNull List<Streak> streaks);
|
|
|
|
|