mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-09-07 08:26:15 +00:00
bugfix: after memory is moved, when doc is dragged the moved memory stays still instead of following the doc.
This commit is contained in:
parent
c42248ff35
commit
d1d936ef29
7 changed files with 211 additions and 638 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -40,6 +40,6 @@ yarn-error.log*
|
|||
# Misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
.claude
|
||||
.venv
|
||||
__pycache__
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 }),
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue