Add current time indicator to week view

- Add real-time current time indicator that updates every 5 seconds
- Display horizontal line with dot and time label on current day only
- Position indicator accurately based on time increment mode (15/30 min)
- Use theme-aware colors with subdued gray styling for dark mode
- Include subtle shadows and proper z-indexing for visibility

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Connor Johnstone
2025-09-05 10:33:07 -04:00
parent bbad327ea2
commit efbaea5ac1
2 changed files with 118 additions and 0 deletions

View File

@@ -81,6 +81,31 @@ pub fn week_view(props: &WeekViewProps) -> Html {
let pending_recurring_edit = use_state(|| None::<PendingRecurringEdit>);
// Current time state for time indicator
let current_time = use_state(|| Local::now());
// Update current time every 5 seconds
{
let current_time = current_time.clone();
use_effect_with((), move |_| {
let interval = gloo_timers::callback::Interval::new(5_000, move || {
current_time.set(Local::now());
});
// Return the interval to keep it alive
move || drop(interval)
});
}
// Helper function to calculate current time indicator position
let calculate_current_time_position = |time_increment: u32| -> f64 {
let now = current_time.time();
let hour = now.hour() as f64;
let minute = now.minute() as f64;
let pixels_per_hour = if time_increment == 15 { 120.0 } else { 60.0 };
(hour + minute / 60.0) * pixels_per_hour
};
// Helper function to get calendar color for an event
let get_event_color = |event: &VEvent| -> String {
if let Some(calendar_path) = &event.calendar_path {
@@ -1089,6 +1114,29 @@ pub fn week_view(props: &WeekViewProps) -> Html {
html! {}
}
}
// Current time indicator - only show on today
{
if *date == props.today {
let current_time_position = calculate_current_time_position(props.time_increment);
let current_time_str = current_time.time().format("%I:%M %p").to_string();
html! {
<div class="current-time-indicator-container">
<div
class="current-time-indicator"
style={format!("top: {}px;", current_time_position)}
>
<div class="current-time-dot"></div>
<div class="current-time-line"></div>
<div class="current-time-label">{current_time_str}</div>
</div>
</div>
}
} else {
html! {}
}
}
</div>
}
}).collect::<Html>()

View File

@@ -1052,6 +1052,76 @@ body {
background: linear-gradient(135deg, var(--event-color, #3B82F6), rgba(255,255,255,0.1)) !important;
}
/* Current Time Indicator */
.current-time-indicator-container {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
pointer-events: none;
z-index: 20;
}
.current-time-indicator {
position: absolute;
left: 0;
right: 0;
height: 2px;
z-index: 20;
display: flex;
align-items: center;
pointer-events: none;
}
.current-time-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background-color: var(--primary-color, #667eea);
position: absolute;
left: -4px;
z-index: 21;
flex-shrink: 0;
}
.current-time-line {
flex: 1;
height: 2px;
background-color: var(--primary-color, #667eea);
position: relative;
}
.current-time-label {
position: absolute;
right: -50px;
top: -10px;
background-color: var(--primary-color, #667eea);
color: white;
padding: 2px 6px;
border-radius: 4px;
font-size: 0.7rem;
font-weight: 600;
white-space: nowrap;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}
/* Dark theme override for current time indicator */
[data-theme="dark"] .current-time-dot {
background-color: #9ca3af;
box-shadow: 0 0 6px rgba(156, 163, 175, 0.4);
}
[data-theme="dark"] .current-time-line {
background-color: #9ca3af;
box-shadow: 0 1px 3px rgba(156, 163, 175, 0.3);
}
[data-theme="dark"] .current-time-label {
background-color: #6b7280;
box-shadow: 0 2px 8px rgba(107, 114, 128, 0.4);
}
/* Legacy Week Grid (for backward compatibility) */
.week-grid {
display: grid;