diff options
| author | Vidya Rupak <[email protected]> | 2025-12-21 21:40:35 -0700 |
|---|---|---|
| committer | Vidya Rupak <[email protected]> | 2025-12-21 21:40:35 -0700 |
| commit | 696f5bbffa6aa0cff0dbb1d5afd8963ca72372b1 (patch) | |
| tree | f7c20a9fabc88befb2781accdd0614ee06b0e014 | |
| parent | added popover cards for doc and memory to open next to the selected node. (diff) | |
| download | supermemory-696f5bbffa6aa0cff0dbb1d5afd8963ca72372b1.tar.xz supermemory-696f5bbffa6aa0cff0dbb1d5afd8963ca72372b1.zip | |
updated changelog and refactored popover logic to eliminate unnecessary calculations during smooth pan/zoom animations
| -rw-r--r-- | packages/memory-graph/CHANGELOG.md | 14 | ||||
| -rw-r--r-- | packages/memory-graph/src/components/memory-graph.tsx | 97 |
2 files changed, 65 insertions, 46 deletions
diff --git a/packages/memory-graph/CHANGELOG.md b/packages/memory-graph/CHANGELOG.md index c6bee6cf..20ed454a 100644 --- a/packages/memory-graph/CHANGELOG.md +++ b/packages/memory-graph/CHANGELOG.md @@ -2,6 +2,20 @@ ## Visual & Layout Improvements (2025-12-21) +### Smart Positioning Node Popover +**Feature:** Clicking nodes now shows a floating popover with detailed information, positioned near the node with smart viewport edge detection. + +**Implementation:** +- DOM-based popover +- Auto-positions to avoid viewport edges +- Click-outside to close +- Shows all node metadata: title, summary (2-line truncation), type, memory count, URL, creation date, and ID +- For memories: includes space, expiration date (if applicable), and forgotten status + +**Files Changed:** +- `src/components/node-popover.tsx` - New popover component +- `src/components/memory-graph.tsx` - Smart positioning logic + ### Document Type Icons on Cards **Feature:** Document cards now display type-specific icons centered on the card for better visual identification. diff --git a/packages/memory-graph/src/components/memory-graph.tsx b/packages/memory-graph/src/components/memory-graph.tsx index f4194396..98340f4e 100644 --- a/packages/memory-graph/src/components/memory-graph.tsx +++ b/packages/memory-graph/src/components/memory-graph.tsx @@ -405,6 +405,49 @@ export const MemoryGraph = ({ return nodes.find((n) => n.id === selectedNode) || null }, [selectedNode, nodes]) + // Calculate popover position (memoized for performance) + const popoverPosition = useMemo(() => { + if (!selectedNodeData) return null + + // Calculate screen position of the node + const screenX = selectedNodeData.x * zoom + panX + const screenY = selectedNodeData.y * zoom + panY + + // Popover dimensions (estimated) + const popoverWidth = 320 + const popoverHeight = 400 + const offset = 40 + const padding = 16 + + // Smart positioning: flip to other side if would go off-screen + let popoverX = screenX + offset + let popoverY = screenY - 20 + + // Check right edge + if (popoverX + popoverWidth > containerSize.width - padding) { + // Flip to left side of node + popoverX = screenX - popoverWidth - offset + } + + // Check left edge + if (popoverX < padding) { + popoverX = padding + } + + // Check bottom edge + if (popoverY + popoverHeight > containerSize.height - padding) { + // Move up + popoverY = containerSize.height - popoverHeight - padding + } + + // Check top edge + if (popoverY < padding) { + popoverY = padding + } + + return { x: popoverX, y: popoverY } + }, [selectedNodeData, zoom, panX, containerSize.width, containerSize.height]) + // Viewport-based loading: load more when most documents are visible (optional) const checkAndLoadMore = useCallback(() => { if ( @@ -532,52 +575,14 @@ export const MemoryGraph = ({ /> {/* Node popover - positioned near clicked node */} - {selectedNodeData && (() => { - // Calculate screen position of the node - const screenX = selectedNodeData.x * zoom + panX - const screenY = selectedNodeData.y * zoom + panY - - // Popover dimensions (estimated) - const popoverWidth = 300 - const popoverHeight = 200 - const offset = 40 - const padding = 16 - - // Smart positioning: flip to other side if would go off-screen - let popoverX = screenX + offset - let popoverY = screenY - 20 - - // Check right edge - if (popoverX + popoverWidth > containerSize.width - padding) { - // Flip to left side of node - popoverX = screenX - popoverWidth - offset - } - - // Check left edge - if (popoverX < padding) { - popoverX = padding - } - - // Check bottom edge - if (popoverY + popoverHeight > containerSize.height - padding) { - // Move up - popoverY = containerSize.height - popoverHeight - padding - } - - // Check top edge - if (popoverY < padding) { - popoverY = padding - } - - return ( - <NodePopover - node={selectedNodeData} - x={popoverX} - y={popoverY} - onClose={() => setSelectedNode(null)} - /> - ) - })()} + {selectedNodeData && popoverPosition && ( + <NodePopover + node={selectedNodeData} + x={popoverPosition.x} + y={popoverPosition.y} + onClose={() => setSelectedNode(null)} + /> + )} {/* Show welcome screen when no memories exist */} {!isLoading && |