diff --git a/bun.lockb b/bun.lockb index 42239b9..5e33967 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 32fb35b..50a9101 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@astrojs/tailwind": "^5.1.2", "@types/react": "^18.3.12", "@types/react-dom": "^18.3.1", + "@jest/globals": "^27.4.6", "astro": "^4.16.7", "lucide-react": "^0.453.0", "react": "^18.3.1", diff --git a/src/components/MicMasterFlex.tsx b/src/components/MicMasterFlex.tsx index 44ede66..cd11612 100644 --- a/src/components/MicMasterFlex.tsx +++ b/src/components/MicMasterFlex.tsx @@ -1,4 +1,10 @@ import React, { useState, useRef, useEffect } from 'react'; + +type Microphone = { + id: string; + x: number; + y: number; +}; import { Copy, ZoomIn, ZoomOut, PlusCircle, Trash2, Hand, Edit2 } from 'lucide-react'; import { gridToScreen, @@ -7,11 +13,13 @@ import { handleMouseMove, handleMouseUp, handleCoordinateUpdate, - generateGridLines, getNumpyArrayString, copyToClipboard, - getCursor -} from '../utils/micLogic'; + getCursor, + generateGridLines, + type Point, + type Mode +} from '../utils/micLogic.tsx'; const MicMasterFlex = () => { const [microphones, setMicrophones] = useState([]); @@ -21,6 +29,8 @@ const MicMasterFlex = () => { const [pan, setPan] = useState({ x: 0, y: 0 }); const [isDragging, setIsDragging] = useState(false); const [dragStart, setDragStart] = useState(null); + + const [mode, setMode] = useState('add'); const [showEditDialog, setShowEditDialog] = useState(false); const [editX, setEditX] = useState(''); @@ -111,7 +121,28 @@ const MicMasterFlex = () => { style={{ cursor: getCursor(mode) }} onMouseDown={(e) => handleMouseDown(e, svgRef, setDragStart, setIsDragging)} onMouseMove={(e) => handleMouseMove(e, svgRef, isDragging, mode, dragStart, setPan, setDragStart)} - onMouseUp={(e) => handleMouseUp(e, svgRef, isDragging, dragStart, mode, hoveredMic, setMicrophones, setHoveredMic, setSelectedMic, setEditX, setEditY, setShowEditDialog, zoom, pan, microphones)} + onMouseUp={(e) => + handleMouseUp( + e, + svgRef, + isDragging, + dragStart, + mode, + hoveredMic, + setMicrophones, + setHoveredMic, + setSelectedMic, + setEditX, + setEditY, + setShowEditDialog, + setIsDragging, + setDragStart, + zoom, + pan, + microphones + ) + } + onMouseLeave={() => setIsDragging(false)} > @@ -152,7 +183,7 @@ const MicMasterFlex = () => { {showEditDialog && (

Edit Microphone Position

-
handleCoordinateUpdate(e, selectedMic, editX, editY, setMicrophones, setShowEditDialog, setSelectedMic)} className="space-y-4"> + { e.preventDefault(); if (selectedMic !== null) { handleCoordinateUpdate(selectedMic.id, parseFloat(editX), parseFloat(editY), setMicrophones); } }} className="space-y-4">
- + diff --git a/src/utils/micLogic.test.ts b/src/utils/micLogic.test.ts index c46da8b..5ae4839 100644 --- a/src/utils/micLogic.test.ts +++ b/src/utils/micLogic.test.ts @@ -1,4 +1,5 @@ -import { gridToScreen, screenToGrid, handleMouseDown, handleMouseMove, handleMouseUp, handleCoordinateUpdate, generateGridLines, getNumpyArrayString, copyToClipboard, getCursor, Microphone, Point, Mode } from './micLogic'; +import { gridToScreen, screenToGrid, handleMouseDown, handleMouseMove, handleMouseUp, handleCoordinateUpdate, generateGridLines, getNumpyArrayString, copyToClipboard, getCursor, type Microphone, type Point, type Mode } from './micLogic'; +import { describe, test, expect } from '@jest/globals'; describe('micLogic utility functions', () => { test('gridToScreen converts grid coordinates to screen coordinates correctly', () => { diff --git a/src/utils/micLogic.ts b/src/utils/micLogic.tsx similarity index 88% rename from src/utils/micLogic.ts rename to src/utils/micLogic.tsx index 44fa9da..6702927 100644 --- a/src/utils/micLogic.ts +++ b/src/utils/micLogic.tsx @@ -8,7 +8,19 @@ export type Point = { x: number; y: number; } - +// micLogic.tsx +export const handleCoordinateUpdate = ( + micId: string, + newX: number, + newY: number, + setMicrophones: React.Dispatch> +) => { + setMicrophones(prevMics => + prevMics.map(mic => + mic.id === micId ? { ...mic, x: newX, y: newY } : mic + ) + ); +}; export type Mode = 'pan' | 'add' | 'delete' | 'edit'; export const gridToScreen = (point: Point, zoom: number, pan: Point): Point => ({ @@ -64,6 +76,7 @@ export const handleMouseMove = ( } }; + export const handleMouseUp = ( e: React.MouseEvent, svgRef: React.RefObject, @@ -77,9 +90,11 @@ export const handleMouseUp = ( setEditX: React.Dispatch>, setEditY: React.Dispatch>, setShowEditDialog: React.Dispatch>, + setIsDragging: React.Dispatch>, + setDragStart: React.Dispatch>, // No default function here zoom: number, pan: Point, - microphones: Microphone[] + microphones: Microphone[] = [] ) => { if (!isDragging || !svgRef.current) return; @@ -100,7 +115,7 @@ export const handleMouseUp = ( }; setMicrophones([...microphones, newMic]); } else if (mode === 'delete' && hoveredMic) { - setMicrophones(mics => mics.filter(m => m.id !== hoveredMic.id)); + setMicrophones(mics => mics ? mics.filter(m => m.id !== hoveredMic.id) : []); setHoveredMic(null); } else if (mode === 'edit' && hoveredMic) { setSelectedMic(hoveredMic); @@ -114,38 +129,16 @@ export const handleMouseUp = ( setDragStart(null); }; -export const handleCoordinateUpdate = ( - e: React.FormEvent, - selectedMic: Microphone | null, - editX: string, - editY: string, - setMicrophones: React.Dispatch>, - setShowEditDialog: React.Dispatch>, - setSelectedMic: React.Dispatch> -) => { - e.preventDefault(); - if (!selectedMic) return; - - const x = parseFloat(editX); - const y = parseFloat(editY); - - if (isNaN(x) || isNaN(y)) return; - setMicrophones(mics => - mics.map(mic => - mic.id === selectedMic.id ? { ...mic, x, y } : mic - ) - ); - setShowEditDialog(false); - setSelectedMic(null); -}; +import React from 'react'; +import { gridToScreen as importedGridToScreen, type Point as ImportedPoint } from './micLogic'; // Adjust the path as necessary export const generateGridLines = ( gridSize: number, gridDivisions: number, zoom: number, pan: Point -) => { +): React.ReactNode => { const lines = []; const step = gridSize / gridDivisions; @@ -181,7 +174,7 @@ export const generateGridLines = ( ); } - return lines; + return <>{lines}; }; export const getNumpyArrayString = (microphones: Microphone[]) => {