Fix multi-day all-day events to display across all days they span
All-day events spanning multiple days were only showing on their start date. For example, a "Vacation (Dec 20-25)" event would only appear on Dec 20th. Root cause: Logic only checked events stored in each day's HashMap entry, missing events that span into other days. Solution: - Modified all-day event collection to search all events across all days - Added event_spans_date() helper function to check if event spans given date - Properly handles iCalendar dtend convention (day after event ends) - Added deduplication to prevent duplicate events from multiple day buckets - Removed unused day_events variable Result: Multi-day all-day events now correctly appear on every day they span, while single-day events continue to work as before. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -316,10 +316,19 @@ pub fn week_view(props: &WeekViewProps) -> Html {
|
||||
week_days.iter().map(|date| {
|
||||
let is_today = *date == props.today;
|
||||
let weekday_name = get_weekday_name(date.weekday());
|
||||
let day_events = props.events.get(date).cloned().unwrap_or_default();
|
||||
|
||||
// Filter for all-day events only
|
||||
let all_day_events: Vec<_> = day_events.iter().filter(|event| event.all_day).collect();
|
||||
// Collect all-day events that span this date (from any day in the week)
|
||||
let mut all_day_events: Vec<&VEvent> = Vec::new();
|
||||
for events_list in props.events.values() {
|
||||
for event in events_list {
|
||||
if event.all_day && event_spans_date(event, *date) {
|
||||
all_day_events.push(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Remove duplicates (same event might appear in multiple day buckets)
|
||||
all_day_events.sort_by_key(|e| &e.uid);
|
||||
all_day_events.dedup_by_key(|e| &e.uid);
|
||||
|
||||
html! {
|
||||
<div class={classes!("week-day-header", if is_today { Some("today") } else { None })}>
|
||||
@@ -1308,3 +1317,19 @@ fn calculate_event_layout(events: &[VEvent], date: NaiveDate, time_increment: u3
|
||||
|
||||
event_columns
|
||||
}
|
||||
|
||||
// Check if an all-day event spans the given date
|
||||
fn event_spans_date(event: &VEvent, date: NaiveDate) -> bool {
|
||||
let start_date = event.dtstart.with_timezone(&Local).date_naive();
|
||||
let end_date = if let Some(dtend) = event.dtend {
|
||||
// For all-day events, dtend is often set to the day after the last day
|
||||
// So we need to subtract a day to get the actual last day of the event
|
||||
dtend.with_timezone(&Local).date_naive() - chrono::Duration::days(1)
|
||||
} else {
|
||||
// Single day event
|
||||
start_date
|
||||
};
|
||||
|
||||
// Check if the given date falls within the event's date range
|
||||
date >= start_date && date <= end_date
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user