Implement husband-wife connection dialogue and theme support for learn articles

This commit is contained in:
2026-01-05 17:09:15 -06:00
parent 02d25d0cc7
commit 96655f9a74
36 changed files with 3849 additions and 819 deletions

View File

@@ -175,6 +175,66 @@ class CycleService {
);
}
/// Calculates the cycle phase for a specific date (past or future)
static CyclePhase? getPhaseForDate(DateTime date, UserProfile? user) {
if (user == null || user.lastPeriodStartDate == null) return null;
final lastPeriodStart = user.lastPeriodStartDate!;
// Normalize dates
final checkDate = DateTime(date.year, date.month, date.day);
final startCycle = DateTime(lastPeriodStart.year, lastPeriodStart.month, lastPeriodStart.day);
final daysDifference = checkDate.difference(startCycle).inDays;
// If date is before the last known period, we can't reliably predict using this simple logic
// (though in reality we could project backwards, but let's stick to forward/current)
if (daysDifference < 0) return null;
final cycleLength = user.averageCycleLength;
final dayOfCycle = (daysDifference % cycleLength) + 1;
if (dayOfCycle <= user.averagePeriodLength) return CyclePhase.menstrual;
if (dayOfCycle <= 13) return CyclePhase.follicular;
if (dayOfCycle <= 16) return CyclePhase.ovulation;
return CyclePhase.luteal;
}
/// Predicts period days for the next [months] months
static List<DateTime> predictNextPeriodDays(UserProfile? user, {int months = 12}) {
if (user == null || user.lastPeriodStartDate == null) return [];
final predictedDays = <DateTime>[];
final lastPeriodStart = user.lastPeriodStartDate!;
final cycleLength = user.averageCycleLength;
final periodLength = user.averagePeriodLength;
// Start predicting from the NEXT cycle if the current one is finished,
// or just project out from the last start date.
// We want to list all future period days.
DateTime currentCycleStart = lastPeriodStart;
// Project forward for roughly 'months' months
// A safe upper bound for loop is months * 30 days
final limitDate = DateTime.now().add(Duration(days: months * 30));
while (currentCycleStart.isBefore(limitDate)) {
// Add period days for this cycle
for (int i = 0; i < periodLength; i++) {
final periodDay = currentCycleStart.add(Duration(days: i));
if (periodDay.isAfter(DateTime.now())) {
predictedDays.add(periodDay);
}
}
// Move to next cycle
currentCycleStart = currentCycleStart.add(Duration(days: cycleLength));
}
return predictedDays;
}
/// Format cycle day for display
static String getDayOfCycleDisplay(int day) => 'Day $day';