From 55fe9e9c0cf044b4724f62751f5024b297e98807 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 15 Oct 2026 01:00:25 +0000 Subject: [PATCH 1/2] fix(web): restore go-to-today now-cue pulse on repeated t presses Co-authored-by: Tyler Dane --- .../src/common/utils/grid/grid.util.ts | 33 +++++++++++-- .../src/components/SelectView/SelectView.tsx | 3 ++ .../src/grid/components/TimedGrid.tsx | 8 ++-- .../src/grid/now-cue/now-cue.store.test.ts | 48 +++++++++++++++++++ .../src/grid/now-cue/now-cue.store.ts | 26 +++++++--- .../now-cue/scroll-to-now-or-pulse.test.ts | 44 ++++++++++++++++- .../grid/now-cue/scroll-to-now-or-pulse.ts | 21 +++++++- apps/calendar-web/src/index.css | 14 ++++-- .../Week/components/Header/DayLabels.test.tsx | 20 +++++++- .../Week/components/Header/DayLabels.tsx | 4 ++ e2e/now-cue-pulse.spec.ts | 33 +++++++++++++ 11 files changed, 230 insertions(+), 24 deletions(-) create mode 100644 apps/calendar-web/src/grid/now-cue/now-cue.store.test.ts create mode 100644 e2e/now-cue-pulse.spec.ts diff --git a/apps/calendar-web/src/common/utils/grid/grid.util.ts b/apps/calendar-web/src/common/utils/grid/grid.util.ts index 77feb3590..90f973bb7 100644 --- a/apps/calendar-web/src/common/utils/grid/grid.util.ts +++ b/apps/calendar-web/src/common/utils/grid/grid.util.ts @@ -63,14 +63,37 @@ export const SCROLL_TO_NOW_BUFFER_PX = 150; const SCROLL_TO_NOW_TOLERANCE_PX = 2; +/** When the now line is visible and scroll is within this window, "t" pulses. */ +export const SCROLL_TO_NOW_PULSE_NEAR_MINUTES = 5; + export const getScrollToNowTop = (clientHeight: number) => - getCurrentMinute() * getMinuteHeight(clientHeight) - SCROLL_TO_NOW_BUFFER_PX; + Math.max( + 0, + getCurrentMinute() * getMinuteHeight(clientHeight) - + SCROLL_TO_NOW_BUFFER_PX, + ); -export const isTimedGridScrolledToNow = (timedGrid: HTMLElement) => { +export const getScrollToNowDelta = (timedGrid: HTMLElement) => { const targetTop = getScrollToNowTop(timedGrid.clientHeight); - return ( - Math.abs(timedGrid.scrollTop - targetTop) <= SCROLL_TO_NOW_TOLERANCE_PX - ); + return Math.abs(timedGrid.scrollTop - targetTop); +}; + +export const isTimedGridScrolledToNow = (timedGrid: HTMLElement) => { + return getScrollToNowDelta(timedGrid) <= SCROLL_TO_NOW_TOLERANCE_PX; +}; + +export const isTimedGridNearScrollToNow = (timedGrid: HTMLElement) => { + const nearPx = + getMinuteHeight(timedGrid.clientHeight) * SCROLL_TO_NOW_PULSE_NEAR_MINUTES; + return getScrollToNowDelta(timedGrid) <= nearPx; +}; + +/** Whether the live now line sits inside the timed grid's visible scroll area. */ +export const isNowLineInTimedGridViewport = (timedGrid: HTMLElement) => { + const nowLineY = getCurrentMinute() * getMinuteHeight(timedGrid.clientHeight); + const viewTop = timedGrid.scrollTop; + const viewBottom = viewTop + timedGrid.clientHeight; + return nowLineY >= viewTop && nowLineY <= viewBottom; }; /** Returns true when the grid scroll position changed. */ diff --git a/apps/calendar-web/src/components/SelectView/SelectView.tsx b/apps/calendar-web/src/components/SelectView/SelectView.tsx index 4b9ec76d1..47de58fef 100644 --- a/apps/calendar-web/src/components/SelectView/SelectView.tsx +++ b/apps/calendar-web/src/components/SelectView/SelectView.tsx @@ -20,6 +20,7 @@ import { Z_INDEX_FLOATING_MENU } from "@web/common/constants/web.constants"; import { ShortcutKeys } from "@web/components/Shortcuts/ShortcutKeys"; import { selectNowCueActive, + selectNowCuePulseGeneration, useNowCueStore, } from "@web/grid/now-cue/now-cue.store"; import { useFloatingLayer } from "@web/shortcuts/floating-layer"; @@ -52,6 +53,7 @@ export const SelectView = ({ const listRef = useRef>([]); useFloatingLayer("viewSelect", isOpen); const pulseDayLabel = useNowCueStore(selectNowCueActive) && emphasizeDayLabel; + const pulseGeneration = useNowCueStore(selectNowCuePulseGeneration); const getCurrentView = (): "Day" | "Week" | "Life" => { const pathname = location.pathname; @@ -190,6 +192,7 @@ export const SelectView = ({ pulseDayLabel && "c-now-cue-label-pulse motion-reduce:transition-none", )} + key={emphasizeDayLabel ? pulseGeneration : undefined} > {label} diff --git a/apps/calendar-web/src/grid/components/TimedGrid.tsx b/apps/calendar-web/src/grid/components/TimedGrid.tsx index c0a201f16..31682d466 100644 --- a/apps/calendar-web/src/grid/components/TimedGrid.tsx +++ b/apps/calendar-web/src/grid/components/TimedGrid.tsx @@ -25,6 +25,7 @@ import { import { useGridMarginLeft } from "@web/grid/grid-margin"; import { selectNowCueActive, + selectNowCuePulseGeneration, useNowCueStore, } from "@web/grid/now-cue/now-cue.store"; import { type GridVisibleDate } from "@web/grid/types/grid.types"; @@ -173,19 +174,18 @@ const CalendarNowLine = ({ useMinuteTick(); const percentOfDay = getCurrentPercentOfDay(effectiveTimeZone); const pulseNowLine = useNowCueStore(selectNowCueActive); + const pulseGeneration = useNowCueStore(selectNowCuePulseGeneration); return (