From 9a410f68c096102f2893da13abbdc5ac97ba7346 Mon Sep 17 00:00:00 2001 From: Ishaan Gupta Date: Fri, 22 May 2026 12:29:37 +0530 Subject: [PATCH] enable timeline memory selection --- apps/web/components/memories-grid.tsx | 3 + apps/web/components/timeline-view.tsx | 239 ++++++++++++++++++++------ 2 files changed, 190 insertions(+), 52 deletions(-) diff --git a/apps/web/components/memories-grid.tsx b/apps/web/components/memories-grid.tsx index d2f93d544..a4e7f1ba7 100644 --- a/apps/web/components/memories-grid.tsx +++ b/apps/web/components/memories-grid.tsx @@ -775,6 +775,9 @@ export function MemoriesGrid({ hasNextPage={hasNextPage} isFetchingNextPage={isFetchingNextPage} onLoadMore={loadMoreDocuments} + isSelectionMode={isSelectionMode} + selectedDocumentIds={selectedDocumentIds} + onToggleSelection={onToggleSelection} /> ) : ( type DocumentWithMemories = DocumentsResponse["documents"][0] @@ -100,6 +100,39 @@ function getPreviewText(doc: DocumentWithMemories): string { return doc.summary || doc.content || doc.title || "" } +function isTemporaryId(id: string | null | undefined): boolean { + if (!id) return false + return id.startsWith("temp-") || id.startsWith("temp-file-") +} + +function SelectionBox({ + isSelected, + isPartial = false, +}: { + isSelected: boolean + isPartial?: boolean +}) { + return ( + + {isSelected ? ( + + ) : isPartial ? ( + + ) : null} + + ) +} + // ─── Grouped data structures ───────────────────────────────────────────────── type TypeGroup = { categoryInfo: CategoryInfo; docs: DocumentWithMemories[] } @@ -126,7 +159,7 @@ function groupDocuments( } return periodOrder.map((label) => { - const docs = periodMap.get(label)! + const docs = periodMap.get(label) ?? [] const categoryMap = new Map< string, { info: CategoryInfo; docs: DocumentWithMemories[] } @@ -144,9 +177,9 @@ function groupDocuments( return { label, - typeGroups: categoryOrder.map((key) => { - const entry = categoryMap.get(key)! - return { categoryInfo: entry.info, docs: entry.docs } + typeGroups: categoryOrder.flatMap((key) => { + const entry = categoryMap.get(key) + return entry ? [{ categoryInfo: entry.info, docs: entry.docs }] : [] }), } }) @@ -157,10 +190,16 @@ function groupDocuments( function TimelineCard({ doc, onOpenDocument, + isSelectionMode = false, + isSelected = false, + onToggleSelection, indent = false, }: { doc: DocumentWithMemories onOpenDocument: (doc: DocumentWithMemories) => void + isSelectionMode?: boolean + isSelected?: boolean + onToggleSelection?: (doc: DocumentWithMemories) => void indent?: boolean }) { const preview = getPreviewText(doc) @@ -168,19 +207,37 @@ function TimelineCard({ ? doc.type.charAt(0).toUpperCase() + doc.type.slice(1).replace(/_/g, " ") : "Document" const totalMemories = doc.memoryEntries.length + const canSelect = !isTemporaryId(doc.id) && !isTemporaryId(doc.customId) + + const handleClick = () => { + if (isSelectionMode && canSelect) { + onToggleSelection?.(doc) + return + } + onOpenDocument(doc) + } return ( + )} - 0 ? "pl-0" : "pl-4", + dmSansClassName(), )} - /> - + onClick={onToggle} + aria-expanded={isExpanded} + > +
+ + + {countLabel} + + {preview && ( + + · {preview} + + )} + {totalMemories > 0 && ( + + {totalMemories} + + )} +
+ + + + {isExpanded && (
{ + if (doc.id) onToggleSelection?.(doc.id) + }} indent /> ))} @@ -341,6 +453,9 @@ interface TimelineViewProps { hasNextPage?: boolean isFetchingNextPage?: boolean onLoadMore?: () => void + isSelectionMode?: boolean + selectedDocumentIds?: Set + onToggleSelection?: (documentId: string) => void } export function TimelineView({ @@ -349,6 +464,9 @@ export function TimelineView({ hasNextPage, isFetchingNextPage, onLoadMore, + isSelectionMode = false, + selectedDocumentIds = new Set(), + onToggleSelection, }: TimelineViewProps) { const [now] = useState(() => new Date()) const [expandedGroups, setExpandedGroups] = useState>(new Set()) @@ -378,6 +496,12 @@ export function TimelineView({ }, []) const periodGroups = groupDocuments(documents, now) + const handleTimelineCardSelection = useCallback( + (doc: DocumentWithMemories) => { + if (doc.id) onToggleSelection?.(doc.id) + }, + [onToggleSelection], + ) return (
) } @@ -416,6 +548,9 @@ export function TimelineView({ isExpanded={expandedGroups.has(expandKey)} onToggle={() => toggleGroup(expandKey)} onOpenDocument={onOpenDocument} + isSelectionMode={isSelectionMode} + selectedDocumentIds={selectedDocumentIds} + onToggleSelection={onToggleSelection} /> ) })}