kyurikotpq / cycleos-rn

Hustle less, flow more. Android app built with React Native.
0 stars 0 forks source link

fix: Logic for overlapping period days during insertCycle #5

Open kyurikotpq opened 3 weeks ago

kyurikotpq commented 3 weeks ago

Description

Currently, the app has "orphaned" cycle records when the user adds overlapping period days. This allows for cycles of < 5 days and incorrectly tagged cycle_days.

Reproducible Example

  1. Create a cycle whose period is from Sep 27 - Oct 1
  2. Create a cycle whose period is from Sep 28 - Oct 1
  3. You will have a cycle of 1 day (but records in cycle_days remains the same because the length of prevCycleDays is zero)

Expected behavior

The app automatically notices that there is a cycle with overlapping period and adjusts the previous and/or next cycle's dates (including cycle_days) accordingly.

Potential Code to Rewrite

File: @/db/controllers/cycles.ts

// Check if the next cycle exists
const nextCycle: Cycle[] = await getNextCycle(startDayjsUnix);

// If yes, use that as the current cycle's endDate
// ^^^ @TODO: WRONG! THIS MAKES IT POSSIBLE TO HAVE CYCLES OF < 5 DAYS!
// SHOULD CHECK IF nextCycle[0].startDate <  startDayjs.add(periodLength, "day").valueOf() 

if (nextCycle && nextCycle.length == 1 && nextCycle[0].startDate) {
  const thisCycleLength = Math.round(
    (nextCycle[0].startDate - startDayjsUnix) / NUM_MS_PER_DAY
  );
  cycleDetails.cycleLength = thisCycleLength;
  cycleDetails.endDate = nextCycle[0].startDate - NUM_MS_PER_DAY;
} else {
  cycleDetails.endDate = startDayjs.add(cycleLength, "day").valueOf();
  cycleDetails.cycleLength = cycleLength;
}
// Update previous cycle's end dates where relevant
const prevCycle: Cycle[] = await getPrevCycle(startDayjsUnix);
if (prevCycle.length > 0 && prevCycle[0].startDate) {
  const prevCycleDetails = {
    cycleLength: Math.round(
      (startDayjsUnix - prevCycle[0].startDate) / NUM_MS_PER_DAY
    ), // <--- @TODO: Check for the overlap here
    endDate: startDayjs.subtract(1, "day").valueOf(),
  };

  await updateCycle(prevCycle[0].id, prevCycleDetails);

  const prevCycleDays = getCycleDaysFromDates(
    dayjs(prevCycle[0].startDate),
    dayjs(prevCycleDetails.endDate),
    prevCycleDetails.cycleLength,
    prevCycle[0].periodLength ?? 0,
    prevCycle[0].id,
    zoneOffset
  );

  await upsertCycleDays(prevCycleDays);
}