diff --git a/.gitea/workflows/build-apk.yml b/.gitea/workflows/build-apk.yml index 18803b0..3c23571 100644 --- a/.gitea/workflows/build-apk.yml +++ b/.gitea/workflows/build-apk.yml @@ -48,9 +48,6 @@ jobs: unzip -q tools.zip rm tools.zip - mkdir -p cmdline-tools/latest - mv cmdline-tools/* cmdline-tools/latest/ 2>/dev/null || true - # 🔥 CRITICAL: disable all interactivity export GRADLE_OPTS="-Dorg.gradle.daemon=false" export TERM=dumb diff --git a/apk/components/birthdate-list.tsx b/apk/components/birthdate-list.tsx index 6e31158..20311cc 100644 --- a/apk/components/birthdate-list.tsx +++ b/apk/components/birthdate-list.tsx @@ -52,34 +52,44 @@ export function BirthdayList() { // Helper function to group and sort function groupBirthdaysByDate(data: BirthdayEntry[]): SectionData[] { - // Sort by date const today = new Date(); const currentYear = today.getFullYear(); + const todayAtMidnight = new Date(today); + todayAtMidnight.setHours(0, 0, 0, 0); const daysUntilNext = (month: number, day: number) => { let target = new Date(currentYear, month, day); - if(target < today.setHours(0, 0, 0, 0)){ + if (target < todayAtMidnight) { target = new Date(currentYear + 1, month, day); } const msPerDay = 1000 * 60 * 60 * 24; - const diff = target - new Date(today.setHours(0,0,0,0)); + const diff = target.getTime() - todayAtMidnight.getTime(); return Math.ceil(diff / msPerDay); }; const sorted = [...data].sort((a, b) => { - const dateA = parseBirthdayDate(a); - const dateB = parseBirthdayDate(b); - return daysUntilNext(dateA.getMonth(), dateA.getDate()) - daysUntilNext(dateB.getMonth(), dateB.getDate()); + const dateA = parseBirthdayDate(a.date); + const dateB = parseBirthdayDate(b.date); + + const nextBirthdayDiff = + daysUntilNext(dateA.getMonth(), dateA.getDate()) - + daysUntilNext(dateB.getMonth(), dateB.getDate()); + + if (nextBirthdayDiff !== 0) { + return nextBirthdayDiff; + } + + return dateA.getFullYear() - dateB.getFullYear(); }); - // Group by date const grouped = sorted.reduce((acc, item) => { - const existing = acc.find((section) => section.title === item.date); + const sectionKey = getMonthDayKey(item.date); + const existing = acc.find((section) => section.title === sectionKey); if (existing) { existing.data.push(item); } else { - acc.push({ title: item.date, data: [item] }); + acc.push({ title: sectionKey, data: [item] }); } return acc; @@ -92,11 +102,20 @@ function parseBirthdayDate(date: string) { return new Date(`${date}T00:00:00`); } +function getMonthDayKey(date: string) { + const parsedDate = parseBirthdayDate(date); + const month = `${parsedDate.getMonth() + 1}`.padStart(2, "0"); + const day = `${parsedDate.getDate()}`.padStart(2, "0"); + + return `${month}-${day}`; +} + function formatDisplayDate(date: string) { - return parseBirthdayDate(date).toLocaleDateString(undefined, { + const [month, day] = date.split("-").map(Number); + + return new Date(2000, month - 1, day).toLocaleDateString(undefined, { month: "long", day: "numeric", - year: "numeric", }); }