Fix timing issue with event loading and month filtering

Removed redundant useEffect that was causing a race condition where:
1. Page would load showing all events first
2. Then switch to month-filtered events after a delay

The issue was two competing useEffects:
- One for month filtering (extractScheduleEventsInRange)
- One for loading all events (extractScheduleEvents)

Now uses only one useEffect for both initial loading and month filtering,
ensuring consistent behavior on page load.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Clas Wen 2025-09-25 23:36:03 +08:00
parent 38e9a6af61
commit a23e262931

View file

@ -110,62 +110,6 @@ const expandEventOccurrences = (
return occurrences
}
const extractScheduleEvents = (icalComp: ICAL.Component): ScheduleEvent[] => {
const vevents = icalComp.getAllSubcomponents("vevent")
const rangeEnd = ICAL.Time.fromDateString("2026-01-01")
const rangeStart = ICAL.Time.fromDateString("2020-01-01")
// First, collect all exception events (events with RECURRENCE-ID)
const exceptions = new Map<string, Set<string>>() // uid -> set of recurrence-id strings
const exceptionEvents: ScheduleEvent[] = []
vevents.forEach((vevent) => {
const recurrenceId = vevent.getFirstPropertyValue("recurrence-id")
if (recurrenceId) {
const uid = vevent.getFirstPropertyValue("uid")
const event = new ICAL.Event(vevent)
// Check if exception is in range
if (event.startDate.compare(rangeEnd) <= 0 && event.endDate.compare(rangeStart) >= 0) {
exceptionEvents.push({
start: event.startDate.toJSDate(),
end: event.endDate.toJSDate(),
summary: event.summary,
description: event.description,
recurrenceId: recurrenceId.toString(),
})
}
// Track exception for filtering recurring events
if (!exceptions.has(uid)) {
exceptions.set(uid, new Set())
}
exceptions.get(uid)!.add(recurrenceId.toString())
}
})
// Process regular and recurring events
const regularEvents = vevents
.filter(vevent => !vevent.getFirstPropertyValue("recurrence-id"))
.flatMap<ScheduleEvent>((vevent) => {
const event = new ICAL.Event(vevent)
if (event.iterator().complete) {
return [{
start: event.startDate.toJSDate(),
end: event.endDate.toJSDate(),
summary: event.summary,
description: event.description,
recurrenceId: event.uid || event.startDate.toString(),
}]
}
const eventExceptions = exceptions.get(event.uid) || new Set()
return expandEventOccurrences(event, rangeStart, rangeEnd, eventExceptions)
})
return [...regularEvents, ...exceptionEvents]
.sort((a, b) => b.start.getTime() - a.start.getTime())
}
const formatTimePair = (s: Date, e: Date): string => {
const start = dayjs(s)
const end = dayjs(e)
@ -216,14 +160,6 @@ export default function Schedule() {
}
}, [focusedDate])
useEffect(() => {
setLoading(true)
parseCal().then((icalComp) => {
setScheduledEvents(extractScheduleEvents(icalComp))
setLoading(false)
})
}, [])
const groupedEvents = useMemo(() => {
const grouped = new Map<string, ScheduleEvent[]>()
scheduledEvents.forEach((event) => {