calculateStreaks static method
Calculate current and longest streaks from daily activity data.
Implementation
static StreakInfo calculateStreaks(List<DailyActivity> dailyActivity) {
if (dailyActivity.isEmpty) {
return const StreakInfo();
}
final today = DateTime.now();
final todayNorm = DateTime(today.year, today.month, today.day);
final activeDates = dailyActivity.map((d) => d.date).toSet();
// Calculate current streak (working backwards from today).
var currentStreak = 0;
String? currentStreakStart;
var checkDate = todayNorm;
while (true) {
final dateStr = toDateString(checkDate);
if (!activeDates.contains(dateStr)) break;
currentStreak++;
currentStreakStart = dateStr;
checkDate = checkDate.subtract(const Duration(days: 1));
}
// Calculate longest streak.
var longestStreak = 0;
String? longestStreakStart;
String? longestStreakEnd;
final sortedDates = activeDates.toList()..sort();
var tempStreak = 1;
var tempStart = sortedDates.first;
for (var i = 1; i < sortedDates.length; i++) {
final prevDate = DateTime.parse(sortedDates[i - 1]);
final currDate = DateTime.parse(sortedDates[i]);
final dayDiff = currDate.difference(prevDate).inDays;
if (dayDiff == 1) {
tempStreak++;
} else {
if (tempStreak > longestStreak) {
longestStreak = tempStreak;
longestStreakStart = tempStart;
longestStreakEnd = sortedDates[i - 1];
}
tempStreak = 1;
tempStart = sortedDates[i];
}
}
// Check final streak.
if (tempStreak > longestStreak) {
longestStreak = tempStreak;
longestStreakStart = tempStart;
longestStreakEnd = sortedDates.last;
}
return StreakInfo(
currentStreak: currentStreak,
longestStreak: longestStreak,
currentStreakStart: currentStreakStart,
longestStreakStart: longestStreakStart,
longestStreakEnd: longestStreakEnd,
);
}