Skip to content

Commit 3982e4e

Browse files
committed
feat: Y.Doc의 node에 isHolding property 추가
1 parent a6ce459 commit 3982e4e

File tree

1 file changed

+47
-7
lines changed

1 file changed

+47
-7
lines changed

apps/frontend/src/components/canvas/index.tsx

Lines changed: 47 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import "@xyflow/react/dist/style.css";
2121
import { usePages } from "@/hooks/usePages";
2222
import { NoteNode } from "./NoteNode";
2323
import * as Y from "yjs";
24-
// import { WebsocketProvider } from "y-websocket";
2524
import { SocketIOProvider } from "y-socket.io";
2625
import { cn } from "@/lib/utils";
2726
import { useQueryClient } from "@tanstack/react-query";
@@ -34,6 +33,10 @@ import { getHandlePosition } from "@/lib/getHandlePosition";
3433

3534
const proOptions = { hideAttribution: true };
3635

36+
interface YNode extends Node {
37+
isHolding: boolean;
38+
}
39+
3740
interface CanvasProps {
3841
className?: string;
3942
}
@@ -54,6 +57,7 @@ function Flow({ className }: CanvasProps) {
5457

5558
const provider = useRef<SocketIOProvider>();
5659
const existingPageIds = useRef(new Set<string>());
60+
const holdingNodeRef = useRef<string | null>(null);
5761

5862
useEffect(() => {
5963
if (!pages) return;
@@ -93,7 +97,15 @@ function Flow({ className }: CanvasProps) {
9397
const nodesMap = ydoc.getMap("nodes");
9498
const edgesMap = ydoc.getMap("edges");
9599

96-
const initialNodes = Array.from(nodesMap.values()) as Node[];
100+
const yNodes = Array.from(nodesMap.values()) as YNode[];
101+
102+
const initialNodes = yNodes.map((yNode) => {
103+
const nodeEntries = Object.entries(yNode).filter(
104+
([key]) => key !== "isHolding",
105+
);
106+
return Object.fromEntries(nodeEntries) as Node;
107+
});
108+
97109
setNodes(initialNodes);
98110

99111
let isInitialSync = true;
@@ -107,7 +119,12 @@ function Flow({ className }: CanvasProps) {
107119
event.changes.keys.forEach((change, key) => {
108120
const nodeId = key;
109121
if (change.action === "add" || change.action === "update") {
110-
const updatedNode = nodesMap.get(nodeId) as Node;
122+
const updatedYNode = nodesMap.get(nodeId) as YNode;
123+
console.log(updatedYNode);
124+
const updatedNodeEntries = Object.entries(updatedYNode).filter(
125+
([key]) => key !== "isHolding",
126+
);
127+
const updatedNode = Object.fromEntries(updatedNodeEntries) as Node;
111128

112129
if (change.action === "add") {
113130
queryClient.invalidateQueries({ queryKey: ["pages"] });
@@ -157,9 +174,9 @@ function Flow({ className }: CanvasProps) {
157174

158175
pages.forEach((page) => {
159176
const pageId = page.id.toString();
160-
const existingNode = nodesMap.get(pageId) as Node | undefined;
177+
const existingNode = nodesMap.get(pageId) as YNode | undefined;
161178

162-
const newNode = {
179+
const newNode: YNode = {
163180
id: pageId,
164181
type: "note",
165182
data: { title: page.title, id: page.id },
@@ -168,6 +185,7 @@ function Flow({ className }: CanvasProps) {
168185
y: Math.random() * 500,
169186
},
170187
selected: false,
188+
isHolding: false,
171189
};
172190

173191
nodesMap.set(pageId, newNode);
@@ -185,12 +203,13 @@ function Flow({ className }: CanvasProps) {
185203
if (change.type === "position" && change.position) {
186204
const node = nodes.find((n) => n.id === change.id);
187205
if (node) {
188-
const updatedNode = {
206+
const updatedYNode: YNode = {
189207
...node,
190208
position: change.position,
191209
selected: false,
210+
isHolding: holdingNodeRef.current === change.id,
192211
};
193-
nodesMap.set(change.id, updatedNode);
212+
nodesMap.set(change.id, updatedYNode);
194213

195214
edges.forEach((edge) => {
196215
if (edge.source === change.id || edge.target === change.id) {
@@ -330,6 +349,25 @@ function Flow({ className }: CanvasProps) {
330349
[setEdges, edges, nodes, ydoc],
331350
);
332351

352+
const onNodeDragStart = useCallback(
353+
(_event: React.MouseEvent, node: Node) => {
354+
holdingNodeRef.current = node.id;
355+
},
356+
[],
357+
);
358+
359+
const onNodeDragStop = useCallback(
360+
(_event: React.MouseEvent, node: Node) => {
361+
if (ydoc) {
362+
const nodesMap = ydoc.getMap("nodes");
363+
const yNode = nodesMap.get(node.id) as YNode | undefined;
364+
if (yNode) {
365+
nodesMap.set(node.id, { ...yNode, isHolding: false });
366+
}
367+
}
368+
},
369+
[ydoc],
370+
);
333371
const nodeTypes = useMemo(() => ({ note: NoteNode }), []);
334372

335373
return (
@@ -341,6 +379,8 @@ function Flow({ className }: CanvasProps) {
341379
onEdgesChange={handleEdgesChange}
342380
onMouseLeave={handleMouseLeave}
343381
onNodeDrag={handleNodeDrag}
382+
onNodeDragStart={onNodeDragStart}
383+
onNodeDragStop={onNodeDragStop}
344384
onConnect={onConnect}
345385
proOptions={proOptions}
346386
nodeTypes={nodeTypes}

0 commit comments

Comments
 (0)