51 lines
1.6 KiB
Dart
51 lines
1.6 KiB
Dart
import '../core/date_keys.dart';
|
|
import 'app_state.dart';
|
|
|
|
class JourneyStats {
|
|
const JourneyStats({
|
|
required this.currentStreakDays,
|
|
required this.weekFocusMinutes,
|
|
required this.activeDaysThisWeek,
|
|
required this.habitCompletionRate,
|
|
});
|
|
|
|
final int currentStreakDays;
|
|
final int weekFocusMinutes;
|
|
final int activeDaysThisWeek;
|
|
final double habitCompletionRate;
|
|
|
|
static JourneyStats fromState(AppState state) {
|
|
final dateKeys = lastSevenDateKeys();
|
|
final dateKeySet = dateKeys.toSet();
|
|
final weekFocusMinutes = dateKeys.fold<int>(
|
|
0,
|
|
(total, key) => total + minutesForDate(state.sessions, key),
|
|
);
|
|
final activeDays = dateKeys.where((key) => _hasProgress(state, key)).length;
|
|
final habitCompletions = state.habits.fold<int>(
|
|
0,
|
|
(total, habit) =>
|
|
total + habit.completedDates.where(dateKeySet.contains).length,
|
|
);
|
|
final habitOpportunities = state.habits.length * dateKeys.length;
|
|
|
|
return JourneyStats(
|
|
currentStreakDays: currentStreak(
|
|
state.habits,
|
|
state.sessions,
|
|
state.reflections,
|
|
),
|
|
weekFocusMinutes: weekFocusMinutes,
|
|
activeDaysThisWeek: activeDays,
|
|
habitCompletionRate:
|
|
habitOpportunities == 0 ? 0 : habitCompletions / habitOpportunities,
|
|
);
|
|
}
|
|
|
|
static bool _hasProgress(AppState state, String key) {
|
|
return state.habits.any((habit) => habit.completedDates.contains(key)) ||
|
|
state.sessions.any((session) => dateKey(session.completedAt) == key) ||
|
|
state.reflections.any((reflection) => reflection.dateKey == key);
|
|
}
|
|
}
|