package webui import ( "time" "github.com/teambition/rrule-go" "mailgoserver/internal/db" ) // expandOccurrences returns every occurrence of e falling within [rangeStart, // rangeEnd) — a single-element slice (or none, if outside the range) for a // non-recurring event, or every matching occurrence for a recurring one (rrule-go's // own expansion, seeded with the event's own start time as DTSTART since e.RRule only // ever stores the bare "FREQ=..." value, not a full RRULE property with its own // DTSTART). Display-only: an occurrence's time is never itself stored — editing or // deleting always acts on the whole series (see caldav.go/webmail_calendar.go; a // single-occurrence RFC 5545 RECURRENCE-ID override is out of scope for this pass). func expandOccurrences(e db.CalendarEvent, rangeStart, rangeEnd time.Time) []time.Time { if e.RRule == "" { if e.StartAt.Before(rangeEnd) && e.EndAt.After(rangeStart) { return []time.Time{e.StartAt} } return nil } opt, err := rrule.StrToROption(e.RRule) if err != nil { return nil } opt.Dtstart = e.StartAt rule, err := rrule.NewRRule(*opt) if err != nil { return nil } // Between's window needs to start far enough back to catch an occurrence whose // start falls before rangeStart but whose duration still overlaps it (a // multi-hour recurring event straddling midnight) — shift the query window back // by the event's own duration rather than assuming same-day occurrences. duration := e.EndAt.Sub(e.StartAt) return rule.Between(rangeStart.Add(-duration), rangeEnd, true) }