앱 수정
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import type { ReactFlowInstance } from '@xyflow/react';
|
||||
import { getLastHtmlPaletteDragClientXY, isPaletteHtmlDragActive } from './paletteDragSession';
|
||||
|
||||
type FlowProjector = Pick<ReactFlowInstance, 'screenToFlowPosition' | 'getViewport'>;
|
||||
|
||||
@@ -89,8 +90,27 @@ export function isOverStrategyBuilder(clientX: number, clientY: number): boolean
|
||||
return false;
|
||||
}
|
||||
|
||||
/** DOM hit-test — overlay 아래 react-flow 노드 탐색 */
|
||||
/** DOM hit-test — react-flow 노드 id (Safari HTML5 drag: elementsFromPoint 불가 → rect 우선) */
|
||||
export function findFlowNodeIdAtClientPoint(clientX: number, clientY: number): string | null {
|
||||
const pad = 10;
|
||||
const nodeEls = document.querySelectorAll<HTMLElement>('.react-flow__node');
|
||||
for (const nodeEl of nodeEls) {
|
||||
const rect = nodeEl.getBoundingClientRect();
|
||||
if (
|
||||
clientX >= rect.left - pad && clientX <= rect.right + pad
|
||||
&& clientY >= rect.top - pad && clientY <= rect.bottom + pad
|
||||
) {
|
||||
const id = nodeEl.getAttribute('data-id')
|
||||
?? nodeEl.dataset.id
|
||||
?? (nodeEl.id.startsWith('react-flow__node-')
|
||||
? nodeEl.id.slice('react-flow__node-'.length)
|
||||
: null)
|
||||
?? nodeEl.querySelector<HTMLElement>('[data-nodeid]')?.getAttribute('data-nodeid')
|
||||
?? null;
|
||||
if (id) return id;
|
||||
}
|
||||
}
|
||||
|
||||
for (const el of elementsUnderDragPoint(clientX, clientY)) {
|
||||
const nodeEl = el.closest('.react-flow__node') as HTMLElement | null;
|
||||
if (nodeEl) {
|
||||
@@ -98,7 +118,9 @@ export function findFlowNodeIdAtClientPoint(clientX: number, clientY: number): s
|
||||
?? nodeEl.dataset.id
|
||||
?? (nodeEl.id.startsWith('react-flow__node-')
|
||||
? nodeEl.id.slice('react-flow__node-'.length)
|
||||
: null);
|
||||
: null)
|
||||
?? nodeEl.querySelector<HTMLElement>('[data-nodeid]')?.getAttribute('data-nodeid')
|
||||
?? null;
|
||||
if (id) return id;
|
||||
}
|
||||
const handleEl = el.closest('[data-nodeid]') as HTMLElement | null;
|
||||
@@ -115,6 +137,14 @@ export interface PaletteDropResolution {
|
||||
anchorId: string | null;
|
||||
}
|
||||
|
||||
/** WKWebView HTML5 drag — dragover client 좌표가 0,0 으로 오는 경우 보정 */
|
||||
export function resolvePaletteDragClientPoint(clientX: number, clientY: number): { x: number; y: number } {
|
||||
if (clientX !== 0 || clientY !== 0) return { x: clientX, y: clientY };
|
||||
if (!isPaletteHtmlDragActive()) return { x: clientX, y: clientY };
|
||||
const last = getLastHtmlPaletteDragClientXY();
|
||||
return last ?? { x: clientX, y: clientY };
|
||||
}
|
||||
|
||||
/** client 좌표 → flow 위치 + 연결 대상 노드 (DOM 우선, flow hit 보조) */
|
||||
export function resolvePaletteDropClientPoint(
|
||||
clientX: number,
|
||||
@@ -128,9 +158,10 @@ export function resolvePaletteDropClientPoint(
|
||||
) => { id: string } | null,
|
||||
isConnectTarget: (nodeId: string) => boolean,
|
||||
): PaletteDropResolution {
|
||||
const flowPos = projectScreenToFlowPosition(clientX, clientY, rf, containerEl);
|
||||
const { x: px, y: py } = resolvePaletteDragClientPoint(clientX, clientY);
|
||||
const flowPos = projectScreenToFlowPosition(px, py, rf, containerEl);
|
||||
|
||||
const domId = findFlowNodeIdAtClientPoint(clientX, clientY);
|
||||
const domId = findFlowNodeIdAtClientPoint(px, py);
|
||||
if (domId && nodes.some(n => n.id === domId) && isConnectTarget(domId)) {
|
||||
return { flowPos, anchorId: domId };
|
||||
}
|
||||
@@ -140,12 +171,13 @@ export function resolvePaletteDropClientPoint(
|
||||
const escaped = typeof CSS !== 'undefined' && CSS.escape
|
||||
? CSS.escape(node.id)
|
||||
: node.id.replace(/"/g, '\\"');
|
||||
const el = document.querySelector(`.react-flow__node[data-id="${escaped}"]`);
|
||||
const el = document.querySelector(`.react-flow__node[data-id="${escaped}"]`)
|
||||
?? document.getElementById(`react-flow__node-${node.id}`);
|
||||
if (!el) continue;
|
||||
const rect = el.getBoundingClientRect();
|
||||
if (
|
||||
clientX >= rect.left && clientX <= rect.right
|
||||
&& clientY >= rect.top && clientY <= rect.bottom
|
||||
px >= rect.left && px <= rect.right
|
||||
&& py >= rect.top && py <= rect.bottom
|
||||
) {
|
||||
return { flowPos, anchorId: node.id };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user