Skip to content

Commit 0772c25

Browse files
authored
Merge pull request #208 from boostcampwm-2024/feature-fe-#207
Y.Doc의 node에 isHolding property 추가
2 parents 9a05fbe + fcb1156 commit 0772c25

File tree

1 file changed

+46
-7
lines changed

1 file changed

+46
-7
lines changed

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

Lines changed: 46 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,11 @@ 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+
const updatedNodeEntries = Object.entries(updatedYNode).filter(
124+
([key]) => key !== "isHolding",
125+
);
126+
const updatedNode = Object.fromEntries(updatedNodeEntries) as Node;
111127

112128
if (change.action === "add") {
113129
queryClient.invalidateQueries({ queryKey: ["pages"] });
@@ -157,9 +173,9 @@ function Flow({ className }: CanvasProps) {
157173

158174
pages.forEach((page) => {
159175
const pageId = page.id.toString();
160-
const existingNode = nodesMap.get(pageId) as Node | undefined;
176+
const existingNode = nodesMap.get(pageId) as YNode | undefined;
161177

162-
const newNode = {
178+
const newNode: YNode = {
163179
id: pageId,
164180
type: "note",
165181
data: { title: page.title, id: page.id },
@@ -168,6 +184,7 @@ function Flow({ className }: CanvasProps) {
168184
y: Math.random() * 500,
169185
},
170186
selected: false,
187+
isHolding: false,
171188
};
172189

173190
nodesMap.set(pageId, newNode);
@@ -185,12 +202,13 @@ function Flow({ className }: CanvasProps) {
185202
if (change.type === "position" && change.position) {
186203
const node = nodes.find((n) => n.id === change.id);
187204
if (node) {
188-
const updatedNode = {
205+
const updatedYNode: YNode = {
189206
...node,
190207
position: change.position,
191208
selected: false,
209+
isHolding: holdingNodeRef.current === change.id,
192210
};
193-
nodesMap.set(change.id, updatedNode);
211+
nodesMap.set(change.id, updatedYNode);
194212

195213
edges.forEach((edge) => {
196214
if (edge.source === change.id || edge.target === change.id) {
@@ -330,6 +348,25 @@ function Flow({ className }: CanvasProps) {
330348
[setEdges, edges, nodes, ydoc],
331349
);
332350

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

335372
return (
@@ -341,6 +378,8 @@ function Flow({ className }: CanvasProps) {
341378
onEdgesChange={handleEdgesChange}
342379
onMouseLeave={handleMouseLeave}
343380
onNodeDrag={handleNodeDrag}
381+
onNodeDragStart={onNodeDragStart}
382+
onNodeDragStop={onNodeDragStop}
344383
onConnect={onConnect}
345384
proOptions={proOptions}
346385
nodeTypes={nodeTypes}

0 commit comments

Comments
 (0)