From 33176f8b95e5541a0ab9f68ae7e30fc428025540 Mon Sep 17 00:00:00 2001 From: Nate Ferrell Date: Mon, 30 Sep 2024 04:23:50 -0500 Subject: [PATCH] feat: #comment updated input/output handling --- src/App.tsx | 48 +++++++++++++++++++++++++++++-- src/components/ConnectionLine.tsx | 19 ++++++++---- src/components/DeviceNode.tsx | 28 ++++++++++++++---- 3 files changed, 81 insertions(+), 14 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 2bc23c8..47cc21a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -39,6 +39,10 @@ function AudioDeviceArrangerApp() { deviceId: string; portId: string; } | null>(null); + const [tempConnection, setTempConnection] = useState<{ + x: number; + y: number; + } | null>(null); const handleAddCustomDevice = (deviceData: Omit) => { addDevice({ @@ -58,7 +62,6 @@ function AudioDeviceArrangerApp() { const handleDeleteDevice = (id: string) => { deleteDevice(id); - // Remove any connections associated with this device setConnections( connections.filter( (conn) => conn.sourceDeviceId !== id && conn.targetDeviceId !== id @@ -69,12 +72,14 @@ function AudioDeviceArrangerApp() { const handlePortClick = ( deviceId: string, portId: string, - isOutput: boolean + isOutput: boolean, + event: React.MouseEvent ) => { if (connectingFrom) { if (isOutput || connectingFrom.deviceId === deviceId) { // Can't connect output to output or to the same device setConnectingFrom(null); + setTempConnection(null); return; } // Complete the connection @@ -87,9 +92,11 @@ function AudioDeviceArrangerApp() { }; setConnections([...connections, newConnection]); setConnectingFrom(null); + setTempConnection(null); } else if (isOutput) { // Start a new connection from an output port setConnectingFrom({ deviceId, portId }); + setTempConnection({ x: event.clientX, y: event.clientY }); } }; @@ -127,6 +134,19 @@ function AudioDeviceArrangerApp() { })); }; + const handleMouseMove = (event: React.MouseEvent) => { + if (connectingFrom) { + setTempConnection({ x: event.clientX, y: event.clientY }); + } + }; + + const handleMouseUp = () => { + if (connectingFrom) { + setConnectingFrom(null); + setTempConnection(null); + } + }; + if (isLoading) return (
@@ -191,7 +211,12 @@ function AudioDeviceArrangerApp() { {/* Grid */} -
+
); })} + {connectingFrom && tempConnection && ( + d.id === connectingFrom.deviceId)! + .position.x + + GRID_SIZE * 1.5 + } + startY={ + devices.find((d) => d.id === connectingFrom.deviceId)! + .position.y + + GRID_SIZE * 1.5 + } + endX={tempConnection.x} + endY={tempConnection.y} + isTemp={true} + /> + )} {devices.map((device) => ( = ({ @@ -14,7 +15,14 @@ const ConnectionLine: React.FC = ({ startY, endX, endY, + isTemp = false, }) => { + // Calculate control points for a quadratic bezier curve + const midX = (startX + endX) / 2; + const midY = (startY + endY) / 2; + const controlX = midX; + const controlY = midY - Math.abs(endY - startY) / 2; + return ( = ({ pointerEvents: "none", }} > - ); diff --git a/src/components/DeviceNode.tsx b/src/components/DeviceNode.tsx index e268617..011fdc6 100644 --- a/src/components/DeviceNode.tsx +++ b/src/components/DeviceNode.tsx @@ -10,7 +10,12 @@ interface DeviceNodeProps { onMove: (id: string, position: { x: number; y: number }) => void; onEdit: (device: Device) => void; onDelete: (id: string) => void; - onPortClick: (deviceId: string, portId: string, isOutput: boolean) => void; + onPortClick: ( + deviceId: string, + portId: string, + isOutput: boolean, + event: React.MouseEvent + ) => void; isConnecting: boolean; gridWidth: number; gridHeight: number; @@ -105,12 +110,25 @@ const DeviceNode: React.FC = ({ {ports.map((port) => (
{ e.stopPropagation(); - onPortClick(device.id, port.id, isOutput); + onPortClick(device.id, port.id, isOutput, e); }} > {port.name}