From 02577c75021f5a8756db1cc9313e645064354c19 Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Sun, 29 Mar 2026 14:10:28 +0200 Subject: [PATCH] feat: add calendar hover preview settings and functionality --- app/[locale]/calendar/page.tsx | 24 +++++++++++++++-------- components/settings/calendar-settings.tsx | 18 +++++++++++++++++ locales/en/common.json | 9 ++++++++- stores/settings-store.ts | 4 ++++ 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/app/[locale]/calendar/page.tsx b/app/[locale]/calendar/page.tsx index a526546f..712cc606 100644 --- a/app/[locale]/calendar/page.tsx +++ b/app/[locale]/calendar/page.tsx @@ -69,7 +69,7 @@ export default function CalendarPage() { setSelectedDate, setViewMode, toggleCalendarVisibility, updateCalendar, refreshAllSubscriptions, } = useCalendarStore(); - const { firstDayOfWeek, timeFormat, showWeekNumbers, enableCalendarTasks, showTasksOnCalendar } = useSettingsStore(); + const { firstDayOfWeek, timeFormat, showWeekNumbers, enableCalendarTasks, showTasksOnCalendar, calendarHoverPreview } = useSettingsStore(); const taskStore = useTaskStore(); const fetchTasksFn = useTaskStore(state => state.fetchTasks); const { identities } = useIdentityStore(); @@ -338,18 +338,26 @@ export default function CalendarPage() { const handleHoverEvent = useCallback((event: CalendarEvent, anchorRect: DOMRect) => { if (isMobile) return; + if (calendarHoverPreview === 'off') return; if (hoverTimerRef.current) { clearTimeout(hoverTimerRef.current); hoverTimerRef.current = null; } // Don't show hover popover if the sidebar is already open for this event if (showEventModal && editEvent?.id === event.id) return; - setDetailEvent(event); - setDetailAnchorRect(anchorRect); - }, [isMobile, showEventModal, editEvent]); + if (calendarHoverPreview === 'delay-500ms' || calendarHoverPreview === 'delay-1s' || calendarHoverPreview === 'delay-2s') { + const ms = calendarHoverPreview === 'delay-500ms' ? 500 : calendarHoverPreview === 'delay-1s' ? 1000 : 2000; + hoverTimerRef.current = setTimeout(() => { + setDetailEvent(event); + setDetailAnchorRect(anchorRect); + }, ms); + } else { + setDetailEvent(event); + setDetailAnchorRect(anchorRect); + } + }, [isMobile, calendarHoverPreview, showEventModal, editEvent]); const handleHoverLeave = useCallback(() => { - hoverTimerRef.current = setTimeout(() => { - setDetailEvent(null); - setDetailAnchorRect(null); - }, 200); + if (hoverTimerRef.current) { clearTimeout(hoverTimerRef.current); hoverTimerRef.current = null; } + setDetailEvent(null); + setDetailAnchorRect(null); }, []); const handleEditFromDetail = useCallback(() => { diff --git a/components/settings/calendar-settings.tsx b/components/settings/calendar-settings.tsx index 9834a614..479b99c1 100644 --- a/components/settings/calendar-settings.tsx +++ b/components/settings/calendar-settings.tsx @@ -19,6 +19,7 @@ export function CalendarSettings() { showWeekNumbers, enableCalendarTasks, showTasksOnCalendar, + calendarHoverPreview, updateSetting, } = useSettingsStore(); const { isFeatureEnabled } = usePolicyStore(); @@ -80,6 +81,23 @@ export function CalendarSettings() { /> + +