Skip to content

Commit

Permalink
feat: Refactor MicMasterFlex component and update utility functions f…
Browse files Browse the repository at this point in the history
…or better type handling
  • Loading branch information
nkzarrabi committed Oct 31, 2024
1 parent 26a9455 commit 9df0121
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 36 deletions.
Binary file modified bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
41 changes: 36 additions & 5 deletions src/components/MicMasterFlex.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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<Microphone[]>([]);
Expand All @@ -21,6 +29,8 @@ const MicMasterFlex = () => {
const [pan, setPan] = useState<Point>({ x: 0, y: 0 });
const [isDragging, setIsDragging] = useState(false);
const [dragStart, setDragStart] = useState<Point | null>(null);


const [mode, setMode] = useState<Mode>('add');
const [showEditDialog, setShowEditDialog] = useState(false);
const [editX, setEditX] = useState('');
Expand Down Expand Up @@ -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)}
>
<g>
Expand Down Expand Up @@ -152,7 +183,7 @@ const MicMasterFlex = () => {
{showEditDialog && (
<div className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 bg-white p-4 rounded-lg shadow-lg z-20">
<h3 className="text-lg font-semibold mb-4">Edit Microphone Position</h3>
<form onSubmit={(e) => handleCoordinateUpdate(e, selectedMic, editX, editY, setMicrophones, setShowEditDialog, setSelectedMic)} className="space-y-4">
<form onSubmit={(e) => { e.preventDefault(); if (selectedMic !== null) { handleCoordinateUpdate(selectedMic.id, parseFloat(editX), parseFloat(editY), setMicrophones); } }} className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700">X Coordinate (m)</label>
<input
Expand Down
2 changes: 1 addition & 1 deletion src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ import Layout from "../layouts/Layout.astro";
title="MicMasterFlex"
description="MicMasterFlex is an interactive configuration tool for microphone arrays"
>
<MicMasterFlex client:only />
<MicMasterFlex client:only="react" />
</Layout>
3 changes: 2 additions & 1 deletion src/utils/micLogic.test.ts
Original file line number Diff line number Diff line change
@@ -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', () => {
Expand Down
51 changes: 22 additions & 29 deletions src/utils/micLogic.ts → src/utils/micLogic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<React.SetStateAction<Microphone[]>>
) => {
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 => ({
Expand Down Expand Up @@ -64,6 +76,7 @@ export const handleMouseMove = (
}
};


export const handleMouseUp = (
e: React.MouseEvent,
svgRef: React.RefObject<SVGSVGElement>,
Expand All @@ -77,9 +90,11 @@ export const handleMouseUp = (
setEditX: React.Dispatch<React.SetStateAction<string>>,
setEditY: React.Dispatch<React.SetStateAction<string>>,
setShowEditDialog: React.Dispatch<React.SetStateAction<boolean>>,
setIsDragging: React.Dispatch<React.SetStateAction<boolean>>,
setDragStart: React.Dispatch<React.SetStateAction<Point | null>>, // No default function here
zoom: number,
pan: Point,
microphones: Microphone[]
microphones: Microphone[] = []
) => {
if (!isDragging || !svgRef.current) return;

Expand All @@ -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);
Expand All @@ -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<React.SetStateAction<Microphone[]>>,
setShowEditDialog: React.Dispatch<React.SetStateAction<boolean>>,
setSelectedMic: React.Dispatch<React.SetStateAction<Microphone | null>>
) => {
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;

Expand Down Expand Up @@ -181,7 +174,7 @@ export const generateGridLines = (
);
}

return lines;
return <>{lines}</>;
};

export const getNumpyArrayString = (microphones: Microphone[]) => {
Expand Down

0 comments on commit 9df0121

Please sign in to comment.