bugfix: after memory is moved, when doc is dragged the moved memory stays still instead of following the doc.

This commit is contained in:
Vidya Rupak 2025-12-20 11:00:49 -07:00
parent c42248ff35
commit d1d936ef29
7 changed files with 211 additions and 638 deletions

2
.gitignore vendored
View file

@ -40,6 +40,6 @@ yarn-error.log*
# Misc
.DS_Store
*.pem
.claude
.venv
__pycache__

772
bun.lock

File diff suppressed because it is too large Load diff

View file

@ -31,7 +31,7 @@
"@scalar/hono-api-reference": "^0.9.11",
"@vanilla-extract/recipes": "^0.5.7",
"ai": "^5.0.59",
"alchemy": "^0.55.2",
"alchemy": "^0.81.4",
"atmn": "^0.0.16",
"better-auth": "^1.3.3",
"boxen": "^8.0.1",
@ -61,7 +61,7 @@
"drizzle-kit": "^0.31.4",
"turbo": "^2.5.4",
"typescript": "5.8.3",
"wrangler": "4.22.0"
"wrangler": "^4.42.2"
},
"workerd": {
"import": "./esm/index.mjs",

View file

@ -62,9 +62,11 @@
"@emotion/is-prop-valid": "^1.4.0",
"@radix-ui/react-collapsible": "^1.1.12",
"@radix-ui/react-slot": "^1.2.4",
"@supermemory/memory-graph": "^0.1.7",
"@vanilla-extract/css": "^1.17.4",
"@vanilla-extract/recipes": "^0.5.7",
"@vanilla-extract/sprinkles": "^1.6.5",
"d3-force": "^3.0.0",
"lucide-react": "^0.552.0",
"motion": "^12.23.24"
},

View file

@ -248,6 +248,14 @@ export const MemoryGraph = ({
[handleNodeDragStart, nodes],
)
// Enhanced node drag move that includes nodes data
const handleNodeDragMoveWithNodes = useCallback(
(e: React.MouseEvent) => {
handleNodeDragMove(e, nodes)
},
[handleNodeDragMove, nodes],
)
// Navigation callbacks
const handleCenter = useCallback(() => {
if (nodes.length > 0) {
@ -455,7 +463,7 @@ export const MemoryGraph = ({
onDoubleClick={handleDoubleClick}
onNodeClick={handleNodeClick}
onNodeDragEnd={handleNodeDragEnd}
onNodeDragMove={handleNodeDragMove}
onNodeDragMove={handleNodeDragMoveWithNodes}
onNodeDragStart={handleNodeDragStartWithNodes}
onNodeHover={handleNodeHover}
onPanEnd={handlePanEnd}

View file

@ -19,7 +19,7 @@ import type {
export function useGraphData(
data: DocumentsResponse | null,
selectedSpace: string,
nodePositions: Map<string, { x: number; y: number }>,
nodePositions: Map<string, { x: number; y: number; parentDocId?: string; offsetX?: number; offsetY?: number }>,
draggingNodeId: string | null,
memoryLimit?: number,
) {
@ -200,12 +200,31 @@ export function useGraphData(
const defaultMemY =
docNode.y + Math.sin(clusterAngle) * distance + offsetY
// Calculate final position
let finalMemX = defaultMemX
let finalMemY = defaultMemY
if (customMemPos) {
// If memory was manually positioned and has stored offset relative to parent
if (customMemPos.parentDocId === docNode.id &&
customMemPos.offsetX !== undefined &&
customMemPos.offsetY !== undefined) {
// Apply the stored offset to the current document position
finalMemX = docNode.x + customMemPos.offsetX
finalMemY = docNode.y + customMemPos.offsetY
} else {
// Fallback: use absolute position (for backward compatibility or if parent changed)
finalMemX = customMemPos.x
finalMemY = customMemPos.y
}
}
if (!memoryNodeMap.has(memoryId)) {
const memoryNode: GraphNode = {
id: memoryId,
type: "memory",
x: customMemPos?.x ?? defaultMemX,
y: customMemPos?.y ?? defaultMemY,
x: finalMemX,
y: finalMemY,
data: memory,
size: Math.max(
32,

View file

@ -24,7 +24,7 @@ export function useGraphInteractions(
nodeY: 0,
})
const [nodePositions, setNodePositions] = useState<
Map<string, { x: number; y: number }>
Map<string, { x: number; y: number; parentDocId?: string; offsetX?: number; offsetY?: number }>
>(new Map())
// Touch gesture state
@ -109,7 +109,7 @@ export function useGraphInteractions(
)
const handleNodeDragMove = useCallback(
(e: React.MouseEvent) => {
(e: React.MouseEvent, nodes?: GraphNode[]) => {
if (!draggingNodeId) return
const deltaX = (e.clientX - dragStart.x) / zoom
@ -118,6 +118,36 @@ export function useGraphInteractions(
const newX = dragStart.nodeX + deltaX
const newY = dragStart.nodeY + deltaY
// Find the node being dragged to determine if it's a memory
const draggedNode = nodes?.find((n) => n.id === draggingNodeId)
if (draggedNode?.type === "memory") {
// For memory nodes, find the parent document and store relative offset
const memoryData = draggedNode.data as any // MemoryEntry type
const parentDoc = nodes?.find(
(n) => n.type === "document" &&
(n.data as any).memoryEntries?.some((m: any) => m.id === memoryData.id)
)
if (parentDoc) {
// Store the offset from the parent document
const offsetX = newX - parentDoc.x
const offsetY = newY - parentDoc.y
setNodePositions((prev) =>
new Map(prev).set(draggingNodeId, {
x: newX,
y: newY,
parentDocId: parentDoc.id,
offsetX,
offsetY
}),
)
return
}
}
// For document nodes or if parent not found, just store absolute position
setNodePositions((prev) =>
new Map(prev).set(draggingNodeId, { x: newX, y: newY }),
)