데스크탑 앱 전략편집기 수정
This commit is contained in:
@@ -39,7 +39,7 @@ import {
|
||||
} from '../../utils/paletteDragSession';
|
||||
import {
|
||||
isOverStrategyBuilder,
|
||||
projectScreenToFlowPosition,
|
||||
resolvePaletteDropClientPoint,
|
||||
} from '../../utils/flowScreenProjection';
|
||||
import { setStochPairSecondary } from '../../utils/stochOverboughtPair';
|
||||
import {
|
||||
@@ -300,7 +300,7 @@ function StrategyEditorCanvasInner({
|
||||
onExtraStartIdsChange,
|
||||
onExtraRootsChange,
|
||||
}: Props) {
|
||||
const { fitView, screenToFlowPosition } = useReactFlow();
|
||||
const { fitView } = useReactFlow();
|
||||
const canvasWrapRef = useRef<HTMLDivElement>(null);
|
||||
const reactFlowRef = useRef<ReactFlowInstance | null>(null);
|
||||
const positionsRef = useRef(new Map<string, { x: number; y: number }>());
|
||||
@@ -1211,24 +1211,20 @@ function StrategyEditorCanvasInner({
|
||||
));
|
||||
}, [root, orphans, extraRoots, applyResolvedConnection, setEdges]);
|
||||
|
||||
const resolvePaletteDrop = useCallback((flowPos: { x: number; y: number }) => {
|
||||
const hit = findNodeAtFlowPosition(flowPos, nodesRef.current);
|
||||
if (hit && isPaletteConnectTarget(hit.id, root, orphans)) {
|
||||
return { mode: 'connect' as const, anchorId: hit.id };
|
||||
}
|
||||
return { mode: 'orphan' as const };
|
||||
}, [root, orphans]);
|
||||
const resolveDropFromClient = useCallback((clientX: number, clientY: number) => (
|
||||
resolvePaletteDropClientPoint(
|
||||
clientX,
|
||||
clientY,
|
||||
reactFlowRef.current,
|
||||
canvasWrapRef.current,
|
||||
nodesRef.current,
|
||||
findNodeAtFlowPosition,
|
||||
nodeId => isPaletteConnectTarget(nodeId, root, orphans),
|
||||
)
|
||||
), [root, orphans]);
|
||||
|
||||
const isPaletteDrag = (e: React.DragEvent) => isPaletteHtmlDrag(e);
|
||||
|
||||
const clientToFlow = useCallback((clientX: number, clientY: number) => {
|
||||
const rf = reactFlowRef.current;
|
||||
if (rf) {
|
||||
return projectScreenToFlowPosition(clientX, clientY, rf, canvasWrapRef.current);
|
||||
}
|
||||
return screenToFlowPosition({ x: clientX, y: clientY });
|
||||
}, [screenToFlowPosition]);
|
||||
|
||||
const applyPaletteDropAt = useCallback((
|
||||
data: { type: string; value: string; label: string; composite?: boolean },
|
||||
clientX: number,
|
||||
@@ -1236,15 +1232,14 @@ function StrategyEditorCanvasInner({
|
||||
) => {
|
||||
if (!isOverStrategyBuilder(clientX, clientY)) return;
|
||||
|
||||
const flowPos = clientToFlow(clientX, clientY);
|
||||
const { flowPos, anchorId } = resolveDropFromClient(clientX, clientY);
|
||||
if (data.type === 'start') {
|
||||
addStartAt(flowPos);
|
||||
return;
|
||||
}
|
||||
|
||||
const hit = findNodeAtFlowPosition(flowPos, nodesRef.current);
|
||||
if (hit && isPaletteConnectTarget(hit.id, root, orphans)) {
|
||||
handleDropTarget(hit.id, data, flowPos);
|
||||
if (anchorId) {
|
||||
handleDropTarget(anchorId, data, flowPos);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1253,7 +1248,7 @@ function StrategyEditorCanvasInner({
|
||||
requestAnimationFrame(() => {
|
||||
reactFlowRef.current?.fitView({ padding: 0.35, duration: 180 });
|
||||
});
|
||||
}, [clientToFlow, addStartAt, handleDropTarget, addOrphanAt, root, orphans]);
|
||||
}, [resolveDropFromClient, addStartAt, handleDropTarget, addOrphanAt]);
|
||||
|
||||
const onPaneDrop = useCallback((e: React.DragEvent) => {
|
||||
e.preventDefault();
|
||||
@@ -1267,12 +1262,10 @@ function StrategyEditorCanvasInner({
|
||||
applyDropRef.current = applyPaletteDropAt;
|
||||
const clearPreviewRef = useRef(clearDropPreview);
|
||||
clearPreviewRef.current = clearDropPreview;
|
||||
const resolveDropRef = useRef(resolvePaletteDrop);
|
||||
resolveDropRef.current = resolvePaletteDrop;
|
||||
const updatePreviewRef = useRef(updateDropPreview);
|
||||
updatePreviewRef.current = updateDropPreview;
|
||||
const clientToFlowRef = useRef(clientToFlow);
|
||||
clientToFlowRef.current = clientToFlow;
|
||||
const resolveDropFromClientRef = useRef(resolveDropFromClient);
|
||||
resolveDropFromClientRef.current = resolveDropFromClient;
|
||||
|
||||
useEffect(() => {
|
||||
if (!needsPointerPaletteDrag()) return;
|
||||
@@ -1282,10 +1275,9 @@ function StrategyEditorCanvasInner({
|
||||
clearPreviewRef.current();
|
||||
return;
|
||||
}
|
||||
const flowPos = clientToFlowRef.current(ev.x, ev.y);
|
||||
const drop = resolveDropRef.current(flowPos);
|
||||
if (drop.mode === 'connect') {
|
||||
updatePreviewRef.current(drop.anchorId, flowPos);
|
||||
const { flowPos, anchorId } = resolveDropFromClientRef.current(ev.x, ev.y);
|
||||
if (anchorId) {
|
||||
updatePreviewRef.current(anchorId, flowPos);
|
||||
} else {
|
||||
clearPreviewRef.current();
|
||||
}
|
||||
@@ -1306,14 +1298,13 @@ function StrategyEditorCanvasInner({
|
||||
e.preventDefault();
|
||||
if (!isPaletteDrag(e)) return;
|
||||
e.dataTransfer.dropEffect = 'copy';
|
||||
const flowPos = clientToFlow(e.clientX, e.clientY);
|
||||
const drop = resolvePaletteDrop(flowPos);
|
||||
if (drop.mode === 'connect') {
|
||||
updateDropPreview(drop.anchorId, flowPos);
|
||||
const { flowPos, anchorId } = resolveDropFromClient(e.clientX, e.clientY);
|
||||
if (anchorId) {
|
||||
updateDropPreview(anchorId, flowPos);
|
||||
} else {
|
||||
clearDropPreview();
|
||||
}
|
||||
}, [clientToFlow, resolvePaletteDrop, updateDropPreview, clearDropPreview]);
|
||||
}, [resolveDropFromClient, updateDropPreview, clearDropPreview]);
|
||||
|
||||
const onPaneDragLeave = useCallback((e: React.DragEvent) => {
|
||||
const rel = e.relatedTarget as Element | null;
|
||||
|
||||
Reference in New Issue
Block a user