From 3982e4ef34cbefe822035123bd576de242712968 Mon Sep 17 00:00:00 2001 From: djk01281 Date: Tue, 19 Nov 2024 18:38:20 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20Y.Doc=EC=9D=98=20node=EC=97=90=20is?= =?UTF-8?q?Holding=20property=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/frontend/src/components/canvas/index.tsx | 54 ++++++++++++++++--- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/apps/frontend/src/components/canvas/index.tsx b/apps/frontend/src/components/canvas/index.tsx index 73ba9040..7b6b006a 100644 --- a/apps/frontend/src/components/canvas/index.tsx +++ b/apps/frontend/src/components/canvas/index.tsx @@ -21,7 +21,6 @@ import "@xyflow/react/dist/style.css"; import { usePages } from "@/hooks/usePages"; import { NoteNode } from "./NoteNode"; import * as Y from "yjs"; -// import { WebsocketProvider } from "y-websocket"; import { SocketIOProvider } from "y-socket.io"; import { cn } from "@/lib/utils"; import { useQueryClient } from "@tanstack/react-query"; @@ -34,6 +33,10 @@ import { getHandlePosition } from "@/lib/getHandlePosition"; const proOptions = { hideAttribution: true }; +interface YNode extends Node { + isHolding: boolean; +} + interface CanvasProps { className?: string; } @@ -54,6 +57,7 @@ function Flow({ className }: CanvasProps) { const provider = useRef(); const existingPageIds = useRef(new Set()); + const holdingNodeRef = useRef(null); useEffect(() => { if (!pages) return; @@ -93,7 +97,15 @@ function Flow({ className }: CanvasProps) { const nodesMap = ydoc.getMap("nodes"); const edgesMap = ydoc.getMap("edges"); - const initialNodes = Array.from(nodesMap.values()) as Node[]; + const yNodes = Array.from(nodesMap.values()) as YNode[]; + + const initialNodes = yNodes.map((yNode) => { + const nodeEntries = Object.entries(yNode).filter( + ([key]) => key !== "isHolding", + ); + return Object.fromEntries(nodeEntries) as Node; + }); + setNodes(initialNodes); let isInitialSync = true; @@ -107,7 +119,12 @@ function Flow({ className }: CanvasProps) { event.changes.keys.forEach((change, key) => { const nodeId = key; if (change.action === "add" || change.action === "update") { - const updatedNode = nodesMap.get(nodeId) as Node; + const updatedYNode = nodesMap.get(nodeId) as YNode; + console.log(updatedYNode); + const updatedNodeEntries = Object.entries(updatedYNode).filter( + ([key]) => key !== "isHolding", + ); + const updatedNode = Object.fromEntries(updatedNodeEntries) as Node; if (change.action === "add") { queryClient.invalidateQueries({ queryKey: ["pages"] }); @@ -157,9 +174,9 @@ function Flow({ className }: CanvasProps) { pages.forEach((page) => { const pageId = page.id.toString(); - const existingNode = nodesMap.get(pageId) as Node | undefined; + const existingNode = nodesMap.get(pageId) as YNode | undefined; - const newNode = { + const newNode: YNode = { id: pageId, type: "note", data: { title: page.title, id: page.id }, @@ -168,6 +185,7 @@ function Flow({ className }: CanvasProps) { y: Math.random() * 500, }, selected: false, + isHolding: false, }; nodesMap.set(pageId, newNode); @@ -185,12 +203,13 @@ function Flow({ className }: CanvasProps) { if (change.type === "position" && change.position) { const node = nodes.find((n) => n.id === change.id); if (node) { - const updatedNode = { + const updatedYNode: YNode = { ...node, position: change.position, selected: false, + isHolding: holdingNodeRef.current === change.id, }; - nodesMap.set(change.id, updatedNode); + nodesMap.set(change.id, updatedYNode); edges.forEach((edge) => { if (edge.source === change.id || edge.target === change.id) { @@ -330,6 +349,25 @@ function Flow({ className }: CanvasProps) { [setEdges, edges, nodes, ydoc], ); + const onNodeDragStart = useCallback( + (_event: React.MouseEvent, node: Node) => { + holdingNodeRef.current = node.id; + }, + [], + ); + + const onNodeDragStop = useCallback( + (_event: React.MouseEvent, node: Node) => { + if (ydoc) { + const nodesMap = ydoc.getMap("nodes"); + const yNode = nodesMap.get(node.id) as YNode | undefined; + if (yNode) { + nodesMap.set(node.id, { ...yNode, isHolding: false }); + } + } + }, + [ydoc], + ); const nodeTypes = useMemo(() => ({ note: NoteNode }), []); return ( @@ -341,6 +379,8 @@ function Flow({ className }: CanvasProps) { onEdgesChange={handleEdgesChange} onMouseLeave={handleMouseLeave} onNodeDrag={handleNodeDrag} + onNodeDragStart={onNodeDragStart} + onNodeDragStop={onNodeDragStop} onConnect={onConnect} proOptions={proOptions} nodeTypes={nodeTypes} From fcb11568931efe42b4c7015be948a4995dbf2b6a Mon Sep 17 00:00:00 2001 From: djk01281 Date: Tue, 19 Nov 2024 18:45:43 +0900 Subject: [PATCH 2/2] =?UTF-8?q?chore:=20console.log()=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/frontend/src/components/canvas/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/frontend/src/components/canvas/index.tsx b/apps/frontend/src/components/canvas/index.tsx index 7b6b006a..1a494b01 100644 --- a/apps/frontend/src/components/canvas/index.tsx +++ b/apps/frontend/src/components/canvas/index.tsx @@ -120,7 +120,6 @@ function Flow({ className }: CanvasProps) { const nodeId = key; if (change.action === "add" || change.action === "update") { const updatedYNode = nodesMap.get(nodeId) as YNode; - console.log(updatedYNode); const updatedNodeEntries = Object.entries(updatedYNode).filter( ([key]) => key !== "isHolding", );