made dimming animation to last 1.5seconds. also updated popover positioning logic to appear besides the node with a clear 20px gap

This commit is contained in:
Vidya Rupak 2025-12-22 14:38:25 -07:00
parent ac8fad9038
commit acc9181d77
4 changed files with 30 additions and 19 deletions

View file

@ -20,7 +20,7 @@
**Feature:** When a popover is opened for a doc/memory node, the background dims while the selected node and popover remain in full focus.
**Implementation:**
- Smooth animated dimming: 200ms ease-out cubic transition
- Smooth animated dimming: 1500ms ease-out cubic transition
- Canvas-based dimming: non-selected nodes reduced to 20% opacity
- Edges not connected to selected node reduced to 10% opacity
- Selected node remains at full opacity (1.0) for clear focus
@ -37,28 +37,28 @@
- Multiple ways to close: click backdrop, click X button, or press Escape key
**Files Changed:**
- `src/constants.ts:108-114` - Added ANIMATION config with dimDuration
- `src/components/node-popover.tsx:3,20-29` - Escape key handler and transparent backdrop
- `src/components/graph-canvas.tsx:53-54,62-91,289,294,301,306,317,435,454,577` - Smooth animation and dimming logic
- `src/components/graph-canvas.tsx:12,53-54,62-91,289,294,301,306,317,435,454,577` - Smooth animation and dimming logic
- `src/components/memory-graph.tsx:620` - Pass selectedNodeId to canvas
- `src/types.ts:86` - Added selectedNodeId prop to GraphCanvasProps
---
## 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
- Auto-positions to avoid viewport edges with proper gap from node
- Popover positioned next to node (not on top) with 20px gap
- Calculates node dimensions dynamically based on type (document vs memory)
- Flips to opposite side when approaching 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
- `src/components/memory-graph.tsx:421-429,434` - Smart positioning logic with gap calculation
### Document Type Icons on Cards
**Feature:** Document cards now display type-specific icons centered on the card for better visual identification.

View file

@ -9,7 +9,7 @@ import {
useRef,
useState,
} from "react"
import { colors } from "@/constants"
import { colors, ANIMATION } from "@/constants"
import type {
DocumentWithMemories,
GraphCanvasProps,
@ -63,7 +63,7 @@ export const GraphCanvas = memo<GraphCanvasProps>(
// Smooth dimming animation
useEffect(() => {
const targetDim = selectedNodeId ? 1 : 0
const duration = 200 // milliseconds
const duration = ANIMATION.dimDuration // Match physics settling time
const startDim = dimProgress.current
const startTime = Date.now()

View file

@ -416,17 +416,22 @@ export const MemoryGraph = ({
// Popover dimensions (estimated)
const popoverWidth = 320
const popoverHeight = 400
const offset = 40
const padding = 16
// Calculate node dimensions to position popover with proper gap
const nodeSize = selectedNodeData.size * zoom
const nodeWidth = selectedNodeData.type === "document" ? nodeSize * 1.4 : nodeSize
const nodeHeight = selectedNodeData.type === "document" ? nodeSize * 0.9 : nodeSize
const gap = 20 // Gap between node and popover
// Smart positioning: flip to other side if would go off-screen
let popoverX = screenX + offset
let popoverY = screenY - 20
let popoverX = screenX + nodeWidth / 2 + gap
let popoverY = screenY - popoverHeight / 2
// Check right edge
if (popoverX + popoverWidth > containerSize.width - padding) {
// Flip to left side of node
popoverX = screenX - popoverWidth - offset
popoverX = screenX - nodeWidth / 2 - gap - popoverWidth
}
// Check left edge
@ -446,7 +451,7 @@ export const MemoryGraph = ({
}
return { x: popoverX, y: popoverY }
}, [selectedNodeData, zoom, panX, containerSize.width, containerSize.height])
}, [selectedNodeData, zoom, panX, panY, containerSize.width, containerSize.height])
// Viewport-based loading: load more when most documents are visible (optional)
const checkAndLoadMore = useCallback(() => {

View file

@ -7,15 +7,15 @@ export const colors = {
},
document: {
primary: "rgba(255, 255, 255, 0.21)", // Subtle glass white
secondary: "rgba(255, 255, 255, 0.12)", // More visible
accent: "rgba(255, 255, 255, 0.18)", // Hover state
secondary: "rgba(255, 255, 255, 0.31)", // More visible
accent: "rgba(255, 255, 255, 0.31)", // Hover state
border: "rgba(255, 255, 255, 0.6)", // Sharp borders
glow: "rgba(147, 197, 253, 0.4)", // Blue glow for interaction
},
memory: {
primary: "rgba(147, 196, 253, 0.21)", // Subtle glass blue
secondary: "rgba(147, 197, 253, 0.16)", // More visible
accent: "rgba(147, 197, 253, 0.24)", // Hover state
secondary: "rgba(147, 196, 253, 0.31)", // More visible
accent: "rgba(147, 197, 253, 0.31)", // Hover state
border: "rgba(147, 196, 253, 0.6)", // Sharp borders
glow: "rgba(147, 197, 253, 0.5)", // Blue glow for interaction
},
@ -105,6 +105,12 @@ export const GRAPH_SETTINGS = {
},
}
// Animation settings
export const ANIMATION = {
// Dim effect duration - shortened for better UX
dimDuration: 1500, // milliseconds
}
// Responsive positioning for different app variants
export const POSITIONING = {
console: {