Skip to content

Commit 679746a

Browse files
authored
Merge pull request #102 from Ritika8081/refactor
Resolve build failures, upgrade Next.js and dependencies
2 parents cadacc6 + 5f7e14a commit 679746a

File tree

13 files changed

+4018
-4651
lines changed

13 files changed

+4018
-4651
lines changed

package-lock.json

Lines changed: 3899 additions & 4558 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,27 @@
99
"start": "next start",
1010
"lint": "next lint",
1111
"export": "next export",
12-
"distDir": "out"
12+
"distDir": "out",
13+
"generate-manifest": "ts-node scripts/generateManifest.mjs"
1314
},
1415
"dependencies": {
15-
"@radix-ui/react-accordion": "^1.2.0",
16-
"@radix-ui/react-avatar": "^1.0.4",
17-
"@radix-ui/react-checkbox": "^1.0.4",
18-
"@radix-ui/react-dialog": "^1.0.5",
19-
"@radix-ui/react-hover-card": "^1.1.1",
20-
"@radix-ui/react-icons": "^1.3.0",
21-
"@radix-ui/react-label": "^2.0.2",
22-
"@radix-ui/react-popover": "^1.1.1",
23-
"@radix-ui/react-radio-group": "^1.1.3",
24-
"@radix-ui/react-select": "^2.0.0",
25-
"@radix-ui/react-separator": "^1.0.3",
26-
"@radix-ui/react-slider": "^1.1.2",
27-
"@radix-ui/react-slot": "^1.0.2",
28-
"@radix-ui/react-switch": "^1.1.0",
29-
"@radix-ui/react-toggle": "^1.1.0",
30-
"@radix-ui/react-toggle-group": "^1.1.0",
31-
"@radix-ui/react-tooltip": "^1.0.7",
16+
"@radix-ui/react-accordion": "^1.2.12",
17+
"@radix-ui/react-avatar": "^1.1.11",
18+
"@radix-ui/react-checkbox": "^1.3.3",
19+
"@radix-ui/react-dialog": "^1.1.15",
20+
"@radix-ui/react-hover-card": "^1.1.15",
21+
"@radix-ui/react-icons": "^1.3.2",
22+
"@radix-ui/react-label": "^2.1.8",
23+
"@radix-ui/react-popover": "^1.1.15",
24+
"@radix-ui/react-radio-group": "^1.3.8",
25+
"@radix-ui/react-select": "^2.2.6",
26+
"@radix-ui/react-separator": "^1.1.8",
27+
"@radix-ui/react-slider": "^1.3.6",
28+
"@radix-ui/react-slot": "^1.2.4",
29+
"@radix-ui/react-switch": "^1.2.6",
30+
"@radix-ui/react-toggle": "^1.1.10",
31+
"@radix-ui/react-toggle-group": "^1.1.11",
32+
"@radix-ui/react-tooltip": "^1.2.8",
3233
"@types/p5": "^1.7.6",
3334
"@types/w3c-web-serial": "^1.0.6",
3435
"class-variance-authority": "^0.7.0",
@@ -38,20 +39,20 @@
3839
"fft-js": "^0.0.12",
3940
"file-saver": "^2.0.5",
4041
"framer-motion": "^11.5.4",
42+
"glob": "10.5.0",
4143
"html2canvas": "^1.4.1",
4244
"jszip": "^3.10.1",
4345
"lucide-react": "^0.460.0",
44-
"next": "^15.3.3",
46+
"next": "^16.0.3",
4547
"next-pwa": "^5.6.0",
4648
"next-themes": "^0.3.0",
47-
"react": "^18",
48-
"react-dom": "^18",
49+
"react": "18.3.1",
50+
"react-dom": "18.3.1",
4951
"react-icons": "^5.3.0",
5052
"smoothie": "^1.36.1",
5153
"sonner": "^1.5.0",
5254
"tailwind-merge": "^2.3.0",
5355
"tailwindcss-animate": "^1.0.7",
54-
"tailwindcss-textshadow": "^2.1.3",
5556
"uuid": "^11.0.3",
5657
"webgl-plot": "^0.7.2"
5758
},

src/app/favicon.ico

-165 KB
Binary file not shown.

src/app/layout.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@ export default function RootLayout({
4747
}>) {
4848
return (
4949
<html lang="en" suppressHydrationWarning>
50-
<head>
51-
<link rel="manifest" href={`${basePath}/manifest.json`} /> {/* ✅ Dynamic manifest */}
52-
</head>
50+
<head><link rel="manifest" href={`${basePath}/manifest.json`} /></head>
5351
<body
5452
className={cn(
5553
lobsterTwo.variable,
@@ -70,4 +68,4 @@ export default function RootLayout({
7068
</body>
7169
</html>
7270
);
73-
}
71+
}

src/app/muscle-strength/page.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import { useTheme } from "next-themes";
3636

3737
const MuscleStrength = () => {
3838
const [isDisplay, setIsDisplay] = useState<boolean>(true); // Display state
39-
const sampingrateref = useRef<number>(250);
39+
const samplingrateref = useRef<number>(250);
4040
const [isFilterPopoverOpen, setIsFilterPopoverOpen] = useState(false);
4141
const connectedDeviceRef = useRef<any | null>(null); // UseRef for device tracking
4242
const canvasContainerRef = useRef<HTMLDivElement>(null);
@@ -644,7 +644,7 @@ const MuscleStrength = () => {
644644
forceUpdate(); // Trigger re-render
645645
};
646646
useEffect(() => {
647-
dataPointCountRef.current = (sampingrateref.current * timeBase);
647+
dataPointCountRef.current = (samplingrateref.current * timeBase);
648648
}, [timeBase]);
649649
const zoomRef = useRef(Zoom);
650650

@@ -675,10 +675,10 @@ const MuscleStrength = () => {
675675
);
676676

677677
notchFilters.forEach((filter) => {
678-
filter.setbits(sampingrateref.current);
678+
filter.setbits(samplingrateref.current);
679679
});
680680
EXGFilters.forEach((filter) => {
681-
filter.setbits("12", sampingrateref.current);
681+
filter.setbits("12", samplingrateref.current);
682682
});
683683
function processSample(dataView: DataView): void {
684684
if (dataView.byteLength !== SINGLE_SAMPLE_LEN) {

src/app/npg-lite/page.tsx

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const NPG_Ble = () => {
5656
const [recordingElapsedTime, setRecordingElapsedTime] = useState<number>(0); // State to store the recording duration
5757
const [customTimeInput, setCustomTimeInput] = useState<string>(""); // State to store the custom stop time input
5858
const existingRecordRef = useRef<any | undefined>(undefined);
59-
const sampingrateref = useRef<number>(500);
59+
const samplingrateref = useRef<number>(500);
6060
const recordingStartTimeRef = useRef<number>(0);
6161
const endTimeRef = useRef<number | null>(null); // Ref to store the end time of the recording
6262
const canvasElementCountRef = useRef<number>(1);
@@ -105,6 +105,10 @@ const NPG_Ble = () => {
105105
return; // Exit if the ref is null
106106
}
107107

108+
// Ensure dataPointCount is calculated from current sampling rate and timeBase
109+
const dpCount = samplingrateref.current * timeBase;
110+
dataPointCountRef.current = dpCount;
111+
108112
currentSweepPos.current = new Array(numChannels).fill(0);
109113
sweepPositions.current = new Array(numChannels).fill(0);
110114

@@ -137,7 +141,7 @@ const NPG_Ble = () => {
137141
const opacityDarkMinor = "0.05";
138142
const opacityLightMajor = "0.4";
139143
const opacityLightMinor = "0.1";
140-
const distanceminor = sampingrateref.current * 0.04;
144+
const distanceminor = samplingrateref.current * 0.04;
141145
const numGridLines = (500 * 4) / distanceminor;
142146

143147
for (let j = 1; j < numGridLines; j++) {
@@ -188,10 +192,10 @@ const NPG_Ble = () => {
188192
wglp.gScaleY = Zoom;
189193

190194

191-
const line = new WebglLine(getLineColor(channelNumber, theme), dataPointCountRef.current);
195+
const line = new WebglLine(getLineColor(channelNumber, theme), dpCount);
192196
wglp.gOffsetY = 0;
193197
line.offsetY = 0;
194-
line.lineSpaceX(-1, 2 / dataPointCountRef.current);
198+
line.lineSpaceX(-1, 2 / dpCount);
195199

196200
wglp.addLine(line);
197201
newLines.push(line);
@@ -314,7 +318,7 @@ const NPG_Ble = () => {
314318
forceUpdate(); // Trigger re-render
315319
};
316320
useEffect(() => {
317-
dataPointCountRef.current = (sampingrateref.current * timeBase);
321+
dataPointCountRef.current = (samplingrateref.current * timeBase);
318322
}, [timeBase]);
319323
const zoomRef = useRef(Zoom);
320324

@@ -338,13 +342,13 @@ const NPG_Ble = () => {
338342
const exgFiltersRef = useRef(Array.from({ length: maxCanvasElementCountRef.current }, () => new EXGFilter()));
339343
const pointoneFilterRef = useRef(Array.from({ length: maxCanvasElementCountRef.current }, () => new HighPassFilter()));
340344
notchFiltersRef.current.forEach((filter) => {
341-
filter.setbits(sampingrateref.current);
345+
filter.setbits(samplingrateref.current);
342346
});
343347
exgFiltersRef.current.forEach((filter) => {
344-
filter.setbits("12", sampingrateref.current);
348+
filter.setbits("12", samplingrateref.current);
345349
});
346350
pointoneFilterRef.current.forEach((filter) => {
347-
filter.setSamplingRate(sampingrateref.current);
351+
filter.setSamplingRate(samplingrateref.current);
348352
});
349353

350354
// Inside your component
@@ -786,7 +790,6 @@ const NPG_Ble = () => {
786790

787791
const toggleChannel = (channelIndex: number) => {
788792
setSelectedChannels((prevSelected) => {
789-
setManuallySelected(true);
790793
const updatedChannels = prevSelected.includes(channelIndex)
791794
? prevSelected.filter((ch) => ch !== channelIndex)
792795
: [...prevSelected, channelIndex];
@@ -799,6 +802,8 @@ const NPG_Ble = () => {
799802

800803
return sortedChannels;
801804
});
805+
806+
setManuallySelected(true);
802807
};
803808

804809

@@ -1509,6 +1514,7 @@ const NPG_Ble = () => {
15091514
<div className="relative w-[28rem] flex items-center rounded-lg py-2 border border-gray-300 dark:border-gray-600">
15101515
{/* Button for setting Time Base to 1 */}
15111516
<button
1517+
type="button"
15121518
className="text-gray-700 dark:text-gray-400 mx-1 px-2 py-1 border rounded hover:bg-gray-200 dark:hover:bg-gray-700"
15131519
onClick={() => setTimeBase(1)}
15141520
>
@@ -1527,6 +1533,7 @@ const NPG_Ble = () => {
15271533
/>
15281534
{/* Button for setting Time Base to 10 */}
15291535
<button
1536+
type="button"
15301537
className="text-gray-700 dark:text-gray-400 mx-2 px-2 py-1 border rounded hover:bg-gray-200 dark:hover:bg-gray-700"
15311538
onClick={() => setTimeBase(10)}
15321539
>

src/components/Canvas.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const Canvas = forwardRef(
4040
ref
4141
) => {
4242
const { theme } = useTheme();
43-
let previousCounter: number | null = null; // Variable to store the previous counter value for loss detection
43+
const previousCounterRef = useRef<number | null>(null); // Variable to store the previous counter value for loss detection
4444
const canvasContainerRef = useRef<HTMLDivElement>(null);
4545
const [numChannels, setNumChannels] = useState<number>(selectedChannels.length);
4646
const dataPointCountRef = useRef<number>(2000); // To track the calculated value
@@ -165,17 +165,17 @@ const Canvas = forwardRef(
165165
processIncomingData(data);
166166
updatePlots(data, Zoom);
167167
}
168-
if (previousCounter !== null) {
168+
if (previousCounterRef.current !== null) {
169169
// If there was a previous counter value
170-
const expectedCounter: number = (previousCounter + 1) % 256; // Calculate the expected counter value
170+
const expectedCounter: number = (previousCounterRef.current + 1) % 256; // Calculate the expected counter value
171171
if (data[0] !== expectedCounter) {
172172
// Check for data loss by comparing the current counter with the expected counter
173173
console.warn(
174-
`Data loss detected in canvas! Previous counter: ${previousCounter}, Current counter: ${data[0]}`
174+
`Data loss detected in canvas! Previous counter: ${previousCounterRef.current}, Current counter: ${data[0]}`
175175
);
176176
}
177177
}
178-
previousCounter = data[0]; // Update the previous counter with the current counter
178+
previousCounterRef.current = data[0]; // Update the previous counter with the current counter
179179
},
180180
}),
181181
[Zoom, numChannels, timeBase]

src/components/Connection.tsx

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ const Connection: React.FC<ConnectionProps> = ({
124124
const existingRecordRef = useRef<any | undefined>(undefined);
125125
const devicenameref = useRef<string>("");
126126
const [deviceReady, setDeviceReady] = useState(false);
127-
const sampingrateref = useRef<number>(0);
127+
const samplingrateref = useRef<number>(0);
128128
const [open, setOpen] = useState(false);
129129
const [openfft, setOpenfft] = useState(false);
130130
const [isPauseState, setIsPauseState] = useState(false);
@@ -280,8 +280,8 @@ const Connection: React.FC<ConnectionProps> = ({
280280

281281

282282
const toggleChannel = (channelIndex: number) => {
283+
// Mark as manually selected and update selectedChannels
283284
setSelectedChannels((prevSelected) => {
284-
setManuallySelected(true);
285285
const updatedChannels = prevSelected.includes(channelIndex)
286286
? prevSelected.filter((ch) => ch !== channelIndex)
287287
: [...prevSelected, channelIndex];
@@ -292,24 +292,29 @@ const Connection: React.FC<ConnectionProps> = ({
292292
sortedChannels.push(1);
293293
}
294294

295-
// Retrieve saved devices from localStorage
296-
const savedPorts = JSON.parse(localStorage.getItem('savedDevices') || '[]');
297-
const portInfo = portRef.current?.getInfo();
298-
299-
if (portInfo) {
300-
const deviceIndex = savedPorts.findIndex(
301-
(saved: SavedDevice) => saved.deviceName === devicenameref.current
302-
);
295+
// Retrieve saved devices from localStorage and persist selection
296+
try {
297+
const savedPorts = JSON.parse(localStorage.getItem('savedDevices') || '[]');
298+
const portInfo = portRef.current?.getInfo();
303299

304-
if (deviceIndex !== -1) {
305-
savedPorts[deviceIndex].selectedChannels = sortedChannels;
306-
localStorage.setItem('savedDevices', JSON.stringify(savedPorts));
300+
if (portInfo) {
301+
const deviceIndex = savedPorts.findIndex(
302+
(saved: SavedDevice) => saved.deviceName === devicenameref.current
303+
);
307304

305+
if (deviceIndex !== -1) {
306+
savedPorts[deviceIndex].selectedChannels = sortedChannels;
307+
localStorage.setItem('savedDevices', JSON.stringify(savedPorts));
308+
}
308309
}
310+
} catch (e) {
311+
console.warn('Failed to persist selected channels:', e);
309312
}
310313

311314
return sortedChannels;
312315
});
316+
317+
setManuallySelected(true);
313318
};
314319

315320
// Handle right arrow click (reset count and disable button if needed)
@@ -353,15 +358,24 @@ const Connection: React.FC<ConnectionProps> = ({
353358
});
354359
}
355360
};
356-
const setCanvasCountInWorker = (canvasCount: number) => {
361+
const setCanvasCountInWorker = useCallback((canvasCount: number) => {
357362
if (!workerRef.current) {
358363
initializeWorker();
359364
}
360-
setCanvasCount(selectedChannels.length)
365+
// Update parent canvasCount only when it differs to avoid unnecessary rerenders
366+
const newCount = selectedChannels.length;
367+
if (typeof setCanvasCount === 'function' && newCount !== canvasCount) {
368+
setCanvasCount(newCount);
369+
}
370+
361371
// Send canvasCount independently to the worker
362372
workerRef.current?.postMessage({ action: 'setCanvasCount', canvasCount: canvasElementCountRef.current });
363-
};
364-
setCanvasCountInWorker(canvasElementCountRef.current);
373+
}, [selectedChannels, setCanvasCount]);
374+
375+
// Run the canvas count sync after render (and when selectedChannels change)
376+
useEffect(() => {
377+
setCanvasCountInWorker(canvasElementCountRef.current);
378+
}, [setCanvasCountInWorker]);
365379

366380
const setSelectedChannelsInWorker = (selectedChannels: number[]) => {
367381
if (!workerRef.current) {
@@ -412,8 +426,10 @@ const Connection: React.FC<ConnectionProps> = ({
412426

413427
if (zipBlob) {
414428
saveAs(zipBlob, 'ChordsWeb.zip');
429+
toast.success("Data successfully downloaded as ZIP.");
415430
} else if (error) {
416431
console.error(error);
432+
toast.error(`Error while creating ZIP: ${error}`);
417433
}
418434
};
419435
}
@@ -559,7 +575,7 @@ const Connection: React.FC<ConnectionProps> = ({
559575

560576
if (sampling_rate) {
561577
setCurrentSamplingRate(sampling_rate);
562-
sampingrateref.current = sampling_rate;
578+
samplingrateref.current = sampling_rate;
563579
}
564580

565581
return {
@@ -1155,7 +1171,7 @@ const Connection: React.FC<ConnectionProps> = ({
11551171
maxCanvasElementCountRef.current = 3;
11561172
setSelectedChannel(1);
11571173
setCurrentSamplingRate(500);
1158-
sampingrateref.current = 500;
1174+
samplingrateref.current = 500;
11591175
setInterval(() => {
11601176
if (samplesReceivedRef.current === 0) {
11611177
disconnect();
@@ -1287,13 +1303,13 @@ const Connection: React.FC<ConnectionProps> = ({
12871303
const EXGFilters = Array.from({ length: maxCanvasElementCountRef.current }, () => new EXGFilter());
12881304
const pointoneFilter = Array.from({ length: maxCanvasElementCountRef.current }, () => new HighPassFilter());
12891305
notchFilters.forEach((filter) => {
1290-
filter.setbits(sampingrateref.current); // Set the bits value for all instances
1306+
filter.setbits(samplingrateref.current); // Set the bits value for all instances
12911307
});
12921308
pointoneFilter.forEach((filter) => {
1293-
filter.setSamplingRate(sampingrateref.current); // Set the bits value for all instances
1309+
filter.setSamplingRate(samplingrateref.current); // Set the bits value for all instances
12941310
});
12951311
EXGFilters.forEach((filter) => {
1296-
filter.setbits(detectedBitsRef.current.toString(), sampingrateref.current); // Set the bits value for all instances
1312+
filter.setbits(detectedBitsRef.current.toString(), samplingrateref.current); // Set the bits value for all instances
12971313
});
12981314
try {
12991315
while (isDeviceConnectedRef.current) {

0 commit comments

Comments
 (0)