import React, { useState } from "react"; import { AnnotationPath } from "../types"; import { useAppStore } from "../store"; export const AnnotationNode = ({ ann }: { ann: AnnotationPath }) => { const { zoom, selectedNodeIds, setSelectedNodeIds, updateSelectedNodes, isAnnotationMode, isClickThrough, annotations, images, textNotes, } = useAppStore(); const [isDragging, setIsDragging] = useState(false); const isSelected = selectedNodeIds.includes(ann.id); const handlePointerDown = (e: React.PointerEvent) => { if (isAnnotationMode || isClickThrough) return; if (!isSelected) { let idsToSelect = [ann.id]; if (ann.groupId) { const groupAnnotations = annotations .filter((a) => a.groupId === ann.groupId) .map((a) => a.id); const groupImages = images .filter((i) => i.groupId === ann.groupId) .map((i) => i.id); const groupNotes = textNotes .filter((n) => n.groupId === ann.groupId) .map((n) => n.id); idsToSelect = [...groupAnnotations, ...groupImages, ...groupNotes]; } if (e.shiftKey) { setSelectedNodeIds( Array.from(new Set([...selectedNodeIds, ...idsToSelect])), ); } else { setSelectedNodeIds(idsToSelect); } } setIsDragging(true); e.currentTarget.setPointerCapture(e.pointerId); }; const handlePointerMove = (e: React.PointerEvent) => { if (isDragging) { e.stopPropagation(); updateSelectedNodes(e.movementX / zoom, e.movementY / zoom, ann.id); } }; const handlePointerUp = (e: React.PointerEvent) => { if (isDragging) { setIsDragging(false); e.currentTarget.releasePointerCapture(e.pointerId); e.stopPropagation(); } }; return ( `${p.x},${p.y}`).join(" ")} fill="none" stroke={isSelected ? "#0A84FF" : ann.color} strokeWidth={ ann.strokeWidth * zoom * (ann.isHighlighter ? 3 : 1) + (isSelected ? 2 : 0) } strokeLinecap={ann.isHighlighter ? "square" : "round"} strokeLinejoin={ann.isHighlighter ? "miter" : "round"} opacity={ann.isHighlighter ? 0.4 : 1} style={{ ...(ann.isHighlighter ? { mixBlendMode: "screen" } : {}), pointerEvents: isAnnotationMode || isClickThrough ? "none" : "stroke", cursor: "default", }} onPointerDown={handlePointerDown} onPointerMove={handlePointerMove} onPointerUp={handlePointerUp} onDoubleClick={(e) => { e.stopPropagation(); }} /> ); };