Fix external calendar timezone conversion and styling
- Add comprehensive Windows timezone support for global external calendars - Map Windows timezone names (e.g. "Mountain Standard Time") to IANA zones (e.g. "America/Denver") - Support 60+ timezone mappings across North America, Europe, Asia, Asia Pacific, Africa, South America - Add chrono-tz dependency for proper timezone handling - Fix external calendar event colors by setting calendar_path for color lookup - Add visual distinction for external calendar events with dashed borders and calendar emoji - Update timezone parsing to extract TZID parameters from iCalendar DTSTART/DTEND properties - Pass external calendar data through component hierarchy for color matching 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use crate::components::{EventCreationData, RecurringEditAction, RecurringEditModal};
|
||||
use crate::models::ical::VEvent;
|
||||
use crate::services::calendar_service::UserInfo;
|
||||
use crate::services::calendar_service::{UserInfo, ExternalCalendar};
|
||||
use chrono::{Datelike, Duration, Local, NaiveDate, NaiveDateTime, NaiveTime, Timelike, Weekday};
|
||||
use std::collections::HashMap;
|
||||
use web_sys::MouseEvent;
|
||||
@@ -17,6 +17,8 @@ pub struct WeekViewProps {
|
||||
#[prop_or_default]
|
||||
pub user_info: Option<UserInfo>,
|
||||
#[prop_or_default]
|
||||
pub external_calendars: Vec<ExternalCalendar>,
|
||||
#[prop_or_default]
|
||||
pub on_event_context_menu: Option<Callback<(web_sys::MouseEvent, VEvent)>>,
|
||||
#[prop_or_default]
|
||||
pub on_calendar_context_menu: Option<Callback<(web_sys::MouseEvent, NaiveDate)>>,
|
||||
@@ -81,8 +83,20 @@ pub fn week_view(props: &WeekViewProps) -> Html {
|
||||
|
||||
// Helper function to get calendar color for an event
|
||||
let get_event_color = |event: &VEvent| -> String {
|
||||
if let Some(user_info) = &props.user_info {
|
||||
if let Some(calendar_path) = &event.calendar_path {
|
||||
if let Some(calendar_path) = &event.calendar_path {
|
||||
// Check external calendars first (path format: "external_{id}")
|
||||
if calendar_path.starts_with("external_") {
|
||||
if let Ok(id_str) = calendar_path.strip_prefix("external_").unwrap_or("").parse::<i32>() {
|
||||
if let Some(external_calendar) = props.external_calendars
|
||||
.iter()
|
||||
.find(|cal| cal.id == id_str)
|
||||
{
|
||||
return external_calendar.color.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check regular calendars
|
||||
else if let Some(user_info) = &props.user_info {
|
||||
if let Some(calendar) = user_info
|
||||
.calendars
|
||||
.iter()
|
||||
@@ -371,6 +385,7 @@ pub fn week_view(props: &WeekViewProps) -> Html {
|
||||
<div
|
||||
class="all-day-event"
|
||||
style={format!("background-color: {}", event_color)}
|
||||
data-external={event.categories.contains(&"__EXTERNAL_CALENDAR__".to_string()).to_string()}
|
||||
{onclick}
|
||||
{oncontextmenu}
|
||||
>
|
||||
@@ -905,6 +920,7 @@ pub fn week_view(props: &WeekViewProps) -> Html {
|
||||
column_width
|
||||
)
|
||||
}
|
||||
data-external={event.categories.contains(&"__EXTERNAL_CALENDAR__".to_string()).to_string()}
|
||||
{onclick}
|
||||
{oncontextmenu}
|
||||
onmousedown={onmousedown_event}
|
||||
@@ -992,6 +1008,7 @@ pub fn week_view(props: &WeekViewProps) -> Html {
|
||||
<div
|
||||
class="temp-event-box moving-event"
|
||||
style={format!("top: {}px; height: {}px; background-color: {}; opacity: 0.7;", preview_position, duration_pixels, event_color)}
|
||||
data-external={event.categories.contains(&"__EXTERNAL_CALENDAR__".to_string()).to_string()}
|
||||
>
|
||||
<div class="event-title">{event.summary.as_ref().unwrap_or(&"Untitled".to_string())}</div>
|
||||
{if duration_pixels > 30.0 {
|
||||
@@ -1025,6 +1042,7 @@ pub fn week_view(props: &WeekViewProps) -> Html {
|
||||
<div
|
||||
class="temp-event-box resizing-event"
|
||||
style={format!("top: {}px; height: {}px; background-color: {}; opacity: 0.7;", new_start_pixels, new_height, event_color)}
|
||||
data-external={event.categories.contains(&"__EXTERNAL_CALENDAR__".to_string()).to_string()}
|
||||
>
|
||||
<div class="event-title">{event.summary.as_ref().unwrap_or(&"Untitled".to_string())}</div>
|
||||
{if new_height > 30.0 {
|
||||
@@ -1052,6 +1070,7 @@ pub fn week_view(props: &WeekViewProps) -> Html {
|
||||
<div
|
||||
class="temp-event-box resizing-event"
|
||||
style={format!("top: {}px; height: {}px; background-color: {}; opacity: 0.7;", original_start_pixels, new_height, event_color)}
|
||||
data-external={event.categories.contains(&"__EXTERNAL_CALENDAR__".to_string()).to_string()}
|
||||
>
|
||||
<div class="event-title">{event.summary.as_ref().unwrap_or(&"Untitled".to_string())}</div>
|
||||
{if new_height > 30.0 {
|
||||
|
||||
Reference in New Issue
Block a user