From 727c79c49ef96cdb11696724cc19d466df8ecfd0 Mon Sep 17 00:00:00 2001 From: abhay-codes07 Date: Sun, 16 Aug 2026 14:27:20 +0530 Subject: [PATCH] fix(web): keep timeline date labels fresh and stop regrouping every render Two issues in the timeline view: - `now` was captured once with `useState(() => new Date())`, so the relative date headers ("Today", "Yesterday", weekday names) never updated. A tab left open across midnight kept labelling the previous day's documents as "Today". Refresh `now` on a one-minute interval, but only swap the value when the calendar day actually changes so same-day ticks don't cause re-renders. - `groupDocuments(documents, now)` (sorts the full list and reparses every createdAt) ran on every render, including during scroll and selection. Memoize it on `[documents, now]` so it only recomputes when the data or the day changes. The pre-existing type error at timeline-view.tsx:279 is unrelated (present on main). --- apps/web/components/timeline-view.tsx | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/apps/web/components/timeline-view.tsx b/apps/web/components/timeline-view.tsx index c0975c89..3dc8f9fe 100644 --- a/apps/web/components/timeline-view.tsx +++ b/apps/web/components/timeline-view.tsx @@ -1,6 +1,6 @@ "use client" -import { useState, useEffect, useRef, useCallback } from "react" +import { useState, useEffect, useMemo, useRef, useCallback } from "react" import { AnimatePresence, motion } from "motion/react" import type { DocumentsWithMemoriesResponseSchema } from "@repo/validation/api" import type { z } from "zod" @@ -505,7 +505,21 @@ export function TimelineView({ selectedDocumentIds = new Set(), onToggleSelection, }: TimelineViewProps) { - const [now] = useState(() => new Date()) + // `now` drives the "Today"/"Yesterday"/weekday labels. Refresh it when the + // calendar day rolls over so a tab left open across midnight doesn't keep + // labelling yesterday's documents as "Today". Same-day ticks return the + // previous value, so React skips the re-render and the grouping below only + // recomputes on an actual day change. + const [now, setNow] = useState(() => new Date()) + useEffect(() => { + const id = setInterval(() => { + setNow((prev) => { + const current = new Date() + return current.toDateString() === prev.toDateString() ? prev : current + }) + }, 60_000) + return () => clearInterval(id) + }, []) const [expandedGroups, setExpandedGroups] = useState>(new Set()) const sentinelRef = useRef(null) @@ -532,7 +546,10 @@ export function TimelineView({ }) }, []) - const periodGroups = groupDocuments(documents, now) + const periodGroups = useMemo( + () => groupDocuments(documents, now), + [documents, now], + ) const handleTimelineCardSelection = useCallback( (doc: DocumentWithMemories) => { if (doc.id) onToggleSelection?.(doc.id)