release: seal Focus Seed 1.0.0

This commit is contained in:
2026-06-11 00:10:50 +08:00
commit 67ecb15c03
121 changed files with 5253 additions and 0 deletions
+76
View File
@@ -0,0 +1,76 @@
import '../models/focus_session.dart';
import '../models/habit.dart';
import '../models/reflection_entry.dart';
String todayKey() => dateKey(DateTime.now());
String dateKey(DateTime date) {
final local = DateTime(date.year, date.month, date.day);
return '${local.year.toString().padLeft(4, '0')}-'
'${local.month.toString().padLeft(2, '0')}-'
'${local.day.toString().padLeft(2, '0')}';
}
String readableToday() {
const months = [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec',
];
final now = DateTime.now();
return '${months[now.month - 1]} ${now.day}, ${now.year}';
}
List<String> lastSevenDateKeys() {
final now = DateTime.now();
return List.generate(
7,
(index) => dateKey(now.subtract(Duration(days: 6 - index))),
);
}
int minutesForDate(List<FocusSession> sessions, String key) {
return sessions
.where((session) => dateKey(session.completedAt) == key)
.fold<int>(0, (total, session) => total + session.minutes);
}
int currentStreak(
List<Habit> habits,
List<FocusSession> sessions,
List<ReflectionEntry> reflections,
) {
var streak = 0;
var cursor = DateTime.now();
while (true) {
final key = dateKey(cursor);
final hasHabit = habits.any((habit) => habit.completedDates.contains(key));
final hasSession = sessions.any(
(session) => dateKey(session.completedAt) == key,
);
final hasReflection = reflections.any(
(reflection) => reflection.dateKey == key,
);
if (!hasHabit && !hasSession && !hasReflection) {
return streak;
}
streak += 1;
cursor = cursor.subtract(const Duration(days: 1));
}
}
String formatSeconds(int seconds) {
final minutes = seconds ~/ 60;
final remaining = seconds % 60;
return '${minutes.toString().padLeft(2, '0')}:'
'${remaining.toString().padLeft(2, '0')}';
}