전략편집기 수정1

This commit is contained in:
Macbook
2026-06-15 01:49:33 +09:00
parent 12c556a95e
commit dbad00aa0f
4 changed files with 135 additions and 32 deletions
@@ -33,9 +33,11 @@ import { buildSidewaysFilterNode } from '../../utils/sidewaysFilterPaletteStorag
import {
isPaletteHtmlDrag,
isPaletteHtmlDragActive,
getLastHtmlPaletteDragClientXY,
markPaletteHtmlDragEnd,
needsPointerPaletteDrag,
readPaletteHtmlDragData,
setHtmlPaletteDropRouter,
setPaletteDragDropHandler,
subscribePaletteDrag,
type PaletteDragEvent,
@@ -1281,6 +1283,15 @@ function StrategyEditorCanvasInner({
const clearPreviewRef = useRef(clearDropPreview);
clearPreviewRef.current = clearDropPreview;
useLayoutEffect(() => {
if (needsPointerPaletteDrag()) return undefined;
setHtmlPaletteDropRouter((x, y, payload) => {
clearPreviewRef.current();
applyDropRef.current(payload, x, y);
});
return () => setHtmlPaletteDropRouter(null);
}, []);
useLayoutEffect(() => {
if (!needsPointerPaletteDrag()) return undefined;
setPaletteDragDropHandler((ev) => {
@@ -1299,6 +1310,37 @@ function StrategyEditorCanvasInner({
const lastPreviewAnchorRef = useRef<string | null>(null);
const lastPreviewKeyRef = useRef<string | null>(null);
useEffect(() => {
if (needsPointerPaletteDrag()) return undefined;
let rafId = 0;
const tick = () => {
if (!isPaletteHtmlDragActive()) {
rafId = 0;
return;
}
const xy = getLastHtmlPaletteDragClientXY();
if (xy) {
const { flowPos, anchorId } = resolveDropFromClientRef.current(xy.x, xy.y);
if (anchorId) {
updatePreviewRef.current(anchorId, flowPos);
lastPreviewAnchorRef.current = anchorId;
} else if (lastPreviewAnchorRef.current != null) {
lastPreviewAnchorRef.current = null;
clearPreviewRef.current();
}
}
rafId = requestAnimationFrame(tick);
};
const onDragStart = () => {
if (!rafId) rafId = requestAnimationFrame(tick);
};
document.addEventListener('dragstart', onDragStart, true);
return () => {
document.removeEventListener('dragstart', onDragStart, true);
if (rafId) cancelAnimationFrame(rafId);
};
}, []);
useEffect(() => {
if (needsPointerPaletteDrag()) return;
const onDocDragOver = (e: DragEvent) => {
@@ -32,10 +32,11 @@ import StartTimeframeCheckboxes from './StartTimeframeCheckboxes';
import LogicGateOpToggle from './LogicGateOpToggle';
import { formatStartCandleTypesLabel } from '../../utils/strategyStartNodes';
import { buildSidewaysFilterNode } from '../../utils/sidewaysFilterPaletteStorage';
import { isOverListEditor } from '../../utils/flowScreenProjection';
import {
findPaletteDropKeyAtPoint,
needsPointerPaletteDrag,
readPaletteHtmlDragData,
setHtmlPaletteDropRouter,
setPaletteDragDropHandler,
subscribePaletteDrag,
type PaletteDragPayload,
@@ -303,12 +304,9 @@ function StartSectionBlock({
e.preventDefault();
e.stopPropagation();
setDragOverKey(null);
try {
const data = JSON.parse(e.dataTransfer.getData('application/json'));
applyDrop(null, data);
} catch {
/* ignore */
}
const data = readPaletteHtmlDragData(e);
if (!data) return;
applyDrop(null, data);
};
const handleDropOnNode = (targetId: string, data: { type: string; value: string; label: string; composite?: boolean }) => {
@@ -480,13 +478,22 @@ export default function StrategyListEditor({
const applyDropRef = useRef(applyPaletteDropAtKey);
applyDropRef.current = applyPaletteDropAtKey;
useLayoutEffect(() => {
if (needsPointerPaletteDrag()) return undefined;
setHtmlPaletteDropRouter((x, y, payload) => {
dragOverKeyRef.current = null;
setDragOverKey(null);
applyDropRef.current(findPaletteDropKeyAtPoint(x, y), payload);
});
return () => setHtmlPaletteDropRouter(null);
}, []);
useLayoutEffect(() => {
if (!needsPointerPaletteDrag()) return undefined;
setPaletteDragDropHandler(ev => {
if (ev.phase !== 'end') return;
dragOverKeyRef.current = null;
setDragOverKey(null);
if (!isOverListEditor(ev.x, ev.y)) return;
applyDropRef.current(findPaletteDropKeyAtPoint(ev.x, ev.y), ev.payload);
});
return () => setPaletteDragDropHandler(null);
@@ -495,10 +502,6 @@ export default function StrategyListEditor({
useEffect(() => {
return subscribePaletteDrag(ev => {
if (ev.phase === 'move') {
if (!isOverListEditor(ev.x, ev.y)) {
setDragOverKeyThrottled(null);
return;
}
setDragOverKeyThrottled(findPaletteDropKeyAtPoint(ev.x, ev.y));
return;
}
@@ -519,14 +522,9 @@ export default function StrategyListEditor({
e.preventDefault();
e.stopPropagation();
setDragOverKey(null);
try {
const data = JSON.parse(e.dataTransfer.getData('application/json'));
if (data.type === 'start') {
handleAddStart();
}
} catch {
/* ignore */
}
const data = readPaletteHtmlDragData(e);
if (!data) return;
applyDropRef.current(findPaletteDropKeyAtPoint(e.clientX, e.clientY) ?? LIST_DROP_KEY, data);
};
return (