|
1 | 1 | import React, { useCallback, useEffect, useRef, useState } from "react"; |
2 | | -import { |
3 | | - TLShapeId, |
4 | | - createShapeId, |
5 | | - useEditor, |
6 | | - useValue, |
7 | | -} from "tldraw"; |
8 | | -import { |
9 | | - BaseDiscourseNodeUtil, |
10 | | - DiscourseNodeShape, |
11 | | -} from "~/components/canvas/DiscourseNodeUtil"; |
| 2 | +import { TLShapeId, createShapeId, useEditor, useValue } from "tldraw"; |
| 3 | +import { DiscourseNodeShape } from "~/components/canvas/DiscourseNodeUtil"; |
12 | 4 | import { |
13 | 5 | BaseDiscourseRelationUtil, |
14 | 6 | DiscourseRelationShape, |
15 | 7 | getRelationColor, |
16 | 8 | } from "~/components/canvas/DiscourseRelationShape/DiscourseRelationUtil"; |
| 9 | +import { createOrUpdateArrowBinding } from "~/components/canvas/DiscourseRelationShape/helpers"; |
17 | 10 | import { |
18 | | - createOrUpdateArrowBinding, |
19 | | -} from "~/components/canvas/DiscourseRelationShape/helpers"; |
20 | | -import { discourseContext } from "~/components/canvas/Tldraw"; |
| 11 | + getAllRelations, |
| 12 | + hasValidRelationTypes, |
| 13 | + isDiscourseNodeShape, |
| 14 | +} from "~/components/canvas/canvasUtils"; |
21 | 15 | import { dispatchToastEvent } from "~/components/canvas/ToastListener"; |
22 | 16 | import { RelationTypeDropdown } from "./RelationTypeDropdown"; |
23 | 17 |
|
@@ -67,30 +61,6 @@ const getEdgeMidpoints = (bounds: { |
67 | 61 | }, |
68 | 62 | ]; |
69 | 63 |
|
70 | | -const isDiscourseNode = ( |
71 | | - editor: ReturnType<typeof useEditor>, |
72 | | - shapeType: string, |
73 | | -): boolean => { |
74 | | - try { |
75 | | - const util = editor.getShapeUtil(shapeType); |
76 | | - return util instanceof BaseDiscourseNodeUtil; |
77 | | - } catch { |
78 | | - return false; |
79 | | - } |
80 | | -}; |
81 | | - |
82 | | -const hasValidRelationTypes = ( |
83 | | - sourceNodeType: string, |
84 | | - targetNodeType: string, |
85 | | -): boolean => { |
86 | | - const allRelations = Object.values(discourseContext.relations).flat(); |
87 | | - return allRelations.some( |
88 | | - (r) => |
89 | | - (r.source === sourceNodeType && r.destination === targetNodeType) || |
90 | | - (r.source === targetNodeType && r.destination === sourceNodeType), |
91 | | - ); |
92 | | -}; |
93 | | - |
94 | 64 | export const DragHandleOverlay = () => { |
95 | 65 | const editor = useEditor(); |
96 | 66 |
|
@@ -120,7 +90,7 @@ export const DragHandleOverlay = () => { |
120 | 90 | () => { |
121 | 91 | if (isDragging || pending) return sourceNodeRef.current; |
122 | 92 | const shape = editor.getOnlySelectedShape(); |
123 | | - if (shape && isDiscourseNode(editor, shape.type)) { |
| 93 | + if (shape && isDiscourseNodeShape(editor, shape)) { |
124 | 94 | return shape as DiscourseNodeShape; |
125 | 95 | } |
126 | 96 | return null; |
@@ -187,7 +157,7 @@ export const DragHandleOverlay = () => { |
187 | 157 | hitFrameInside: true, |
188 | 158 | margin: 0, |
189 | 159 | filter: (s) => |
190 | | - isDiscourseNode(editor, s.type) && |
| 160 | + isDiscourseNodeShape(editor, s) && |
191 | 161 | s.id !== selectedNode.id && |
192 | 162 | !s.isLocked, |
193 | 163 | }); |
@@ -215,7 +185,7 @@ export const DragHandleOverlay = () => { |
215 | 185 | hitFrameInside: true, |
216 | 186 | margin: 0, |
217 | 187 | filter: (s) => |
218 | | - isDiscourseNode(editor, s.type) && |
| 188 | + isDiscourseNodeShape(editor, s) && |
219 | 189 | s.id !== selectedNode.id && |
220 | 190 | !s.isLocked, |
221 | 191 | }); |
@@ -276,8 +246,9 @@ export const DragHandleOverlay = () => { |
276 | 246 | (relationId: string) => { |
277 | 247 | if (!pending) return; |
278 | 248 |
|
279 | | - const allRelations = Object.values(discourseContext.relations).flat(); |
280 | | - const selectedRelation = allRelations.find((r) => r.id === relationId); |
| 249 | + const selectedRelation = getAllRelations().find( |
| 250 | + (r) => r.id === relationId, |
| 251 | + ); |
281 | 252 | if (!selectedRelation) { |
282 | 253 | setPending(null); |
283 | 254 | sourceNodeRef.current = null; |
|
0 commit comments