fix(calendar): all-day off-by-one (exclusive DTEND) + member color too close to shared rose
All-day: a single-day all-day event displayed across two days. iCal all-day DTEND is EXCLUSIVE (1-day event = DTSTART:24/DTEND:25) and the server occurrence carries that exclusive end, but Schedule-X treats all-day end as INCLUSIVE. hydrateEvents now subtracts one day (clamped to >= start) so a 1-day event shows on one day and an N-day event spans N days. Write path was already correct (verified against stored VEVENTs). +regression test. Color: a member's coral (#E8734A) was mistaken for the shared-family rose (#F25C7A). Reorder COLOR_PALETTE so warm near-rose hues (amber, coral) are assigned LAST; early members get cool, clearly-distinct colors (blue/green/teal).
This commit is contained in:
@@ -76,11 +76,24 @@ export function hydrateEvents(occurrences: CalendarOccurrence[]): ScheduleXEvent
|
||||
if (occ.allDay) {
|
||||
// All-day: use Temporal.PlainDate — do NOT construct ZonedDateTime from
|
||||
// midnight UTC. occ.start and occ.end are 'YYYY-MM-DD' strings.
|
||||
//
|
||||
// Exclusive→inclusive end conversion: iCalendar all-day DTEND is EXCLUSIVE
|
||||
// (a single-day event on the 24th is DTSTART:24 / DTEND:25), and the server
|
||||
// occurrence carries that exclusive end. Schedule-X treats an all-day event's
|
||||
// `end` as INCLUSIVE (the last day it covers), so passing the exclusive DTEND
|
||||
// straight through renders every all-day event one day too long (a 1-day event
|
||||
// showed across two days). Subtract one day to get the inclusive last day,
|
||||
// clamped to never precede start.
|
||||
const startPd = Temporal.PlainDate.from(occ.start)
|
||||
const endExclusive = Temporal.PlainDate.from(occ.end)
|
||||
const endInclusive = endExclusive.subtract({ days: 1 })
|
||||
const end =
|
||||
Temporal.PlainDate.compare(endInclusive, startPd) < 0 ? startPd : endInclusive
|
||||
return {
|
||||
id: occ.id,
|
||||
title: occ.title,
|
||||
start: Temporal.PlainDate.from(occ.start),
|
||||
end: Temporal.PlainDate.from(occ.end),
|
||||
start: startPd,
|
||||
end,
|
||||
calendarId,
|
||||
_familySync: {
|
||||
uid: occ.uid,
|
||||
|
||||
Reference in New Issue
Block a user