앱 수정

This commit is contained in:
Macbook
2026-06-15 01:16:14 +09:00
parent 16178cb475
commit b0e2efd7cb
4 changed files with 90 additions and 20 deletions
@@ -37,9 +37,14 @@ import StochPairNodeSettings from './StochPairNodeSettings';
import PriceExtremePairNodeSettings from './PriceExtremePairNodeSettings';
import {
isPaletteHtmlDrag,
isPaletteHtmlDragActive,
readPaletteHtmlDragData,
} from '../../utils/paletteDragSession';
function isPaletteDropDrag(e: React.DragEvent): boolean {
return isPaletteHtmlDragActive() || isPaletteHtmlDrag(e);
}
const LOGIC_COLORS: Record<string, string> = {
AND: '#00aaff',
OR: '#00d4ff',
@@ -130,13 +135,13 @@ function usePaletteDropHandlers(id: string, d: StrategyFlowNodeData) {
const { screenToFlowPosition } = useReactFlow();
const onDragEnter = useCallback((e: React.DragEvent) => {
if (!isPaletteHtmlDrag(e)) return;
if (!isPaletteDropDrag(e)) return;
e.preventDefault();
e.stopPropagation();
}, []);
const onDragOver = useCallback((e: React.DragEvent) => {
if (!isPaletteHtmlDrag(e)) return;
if (!isPaletteDropDrag(e)) return;
e.preventDefault();
e.stopPropagation();
e.dataTransfer.dropEffect = 'copy';
@@ -146,8 +151,10 @@ function usePaletteDropHandlers(id: string, d: StrategyFlowNodeData) {
const onDragLeave = useCallback((e: React.DragEvent) => {
e.stopPropagation();
// WebKit HTML5 drag — relatedTarget 이 null 인 spurious dragleave 무시
const rel = e.relatedTarget as Node | null;
if (rel && e.currentTarget.contains(rel)) return;
if (!rel) return;
if (e.currentTarget.contains(rel)) return;
d.onDragLeaveTarget?.(id);
}, [d, id]);
@@ -82,6 +82,7 @@ import {
spawnPositionNearAnchor,
subtreeToFlatOrphans,
type EdgeHandleBinding,
type StrategyFlowNodeData,
} from '../../utils/strategyFlowLayout';
import {
createStartNodeId,
@@ -906,10 +907,16 @@ function StrategyEditorCanvasInner({
const syncNodesFromLayout = () => setNodes(layoutNodes.map(n => {
const prev = nodesRef.current.find(p => p.id === n.id);
const savedPos = layoutSeed.positions[n.id];
const dragOver = (prev?.data as StrategyFlowNodeData | undefined)?.dragOver;
const activeSourceSide = (prev?.data as StrategyFlowNodeData | undefined)?.activeSourceSide;
return {
...n,
position: savedPos ? { x: savedPos.x, y: savedPos.y } : n.position,
selected: prev?.selected ?? false,
data: {
...n.data,
...(dragOver ? { dragOver, activeSourceSide } : {}),
},
};
}));
@@ -933,10 +940,15 @@ function StrategyEditorCanvasInner({
const fresh = layoutNodes.find(ln => ln.id === n.id);
if (!fresh) return n;
const savedPos = layoutSeed.positions[n.id];
const dragOver = (n.data as StrategyFlowNodeData).dragOver;
const activeSourceSide = (n.data as StrategyFlowNodeData).activeSourceSide;
return {
...n,
position: savedPos ? { x: savedPos.x, y: savedPos.y } : fresh.position,
data: fresh.data,
data: {
...fresh.data,
...(dragOver ? { dragOver, activeSourceSide } : {}),
},
};
}));
setEdges(mergedEdges);
@@ -1226,7 +1238,10 @@ function StrategyEditorCanvasInner({
)
), [root, orphans]);
const isPaletteDrag = (e: React.DragEvent) => isPaletteHtmlDrag(e);
const isPaletteDrag = useCallback(
(e: React.DragEvent) => isPaletteHtmlDragActive() || isPaletteHtmlDrag(e),
[],
);
const applyPaletteDropAt = useCallback((
data: { type: string; value: string; label: string; composite?: boolean },
@@ -1291,11 +1306,8 @@ function StrategyEditorCanvasInner({
e.preventDefault();
const { flowPos, anchorId } = resolveDropFromClientRef.current(e.clientX, e.clientY);
if (anchorId) {
const sideKey = `${anchorId}:${Math.round(flowPos.x / 8)}:${Math.round(flowPos.y / 8)}`;
if (sideKey === lastPreviewKeyRef.current) return;
lastPreviewKeyRef.current = sideKey;
lastPreviewAnchorRef.current = anchorId;
updatePreviewRef.current(anchorId, flowPos);
lastPreviewAnchorRef.current = anchorId;
return;
}
if (lastPreviewAnchorRef.current != null) {
@@ -1311,9 +1323,11 @@ function StrategyEditorCanvasInner({
markPaletteHtmlDragEnd();
};
document.addEventListener('dragover', onDocDragOver, { passive: false });
document.addEventListener('drag', onDocDragOver);
document.addEventListener('dragend', onDocDragEnd);
return () => {
document.removeEventListener('dragover', onDocDragOver);
document.removeEventListener('drag', onDocDragOver);
document.removeEventListener('dragend', onDocDragEnd);
};
}, []);
@@ -1368,14 +1382,13 @@ function StrategyEditorCanvasInner({
const { flowPos, anchorId } = resolveDropFromClient(e.clientX, e.clientY);
if (anchorId) {
updateDropPreview(anchorId, flowPos);
} else {
clearDropPreview();
}
}, [resolveDropFromClient, updateDropPreview, clearDropPreview]);
}, [resolveDropFromClient, updateDropPreview, isPaletteDrag]);
const onPaneDragLeave = useCallback((e: React.DragEvent) => {
const rel = e.relatedTarget as Element | null;
if (rel && e.currentTarget.contains(rel)) return;
if (!rel) return;
if (e.currentTarget.contains(rel)) return;
clearDropPreview();
}, [clearDropPreview]);