From 1b85903a49f6ec31f10a1d2b250946b0b7d2a364 Mon Sep 17 00:00:00 2001 From: stevejcl Date: Tue, 14 May 2024 08:37:35 +0200 Subject: [PATCH 1/4] Add Effect for Long Camera Process --- src/components/imaging/CameraAddOn.tsx | 165 ++++++++++--------------- src/lib/photo_utils.ts | 31 ++++- src/locales/de.ts | 2 +- src/locales/en.ts | 2 +- src/locales/es.ts | 2 +- src/locales/nl.ts | 2 +- 6 files changed, 97 insertions(+), 107 deletions(-) diff --git a/src/components/imaging/CameraAddOn.tsx b/src/components/imaging/CameraAddOn.tsx index df473bcc..40449020 100644 --- a/src/components/imaging/CameraAddOn.tsx +++ b/src/components/imaging/CameraAddOn.tsx @@ -81,6 +81,7 @@ export default function CameraAddOn(props: PropTypes) { let WidthSlidePane = useRef("1500px"); let WidthCircularSlider = useRef(150); let trackSize = useRef(24); + let intervalTimer = useRef(0); let gLastTimeMotorCmd = Date.now(); let gMotorState = false; @@ -89,9 +90,9 @@ export default function CameraAddOn(props: PropTypes) { let PhotoMode = !connectionCtx.imagingSession.isRecording && !connectionCtx.imagingSession.endRecording; - setShowModal((prev) => prev && PhotoMode); useEffect(() => { + setShowModal((prev) => prev && PhotoMode); const handleResize = () => { //setWindowWidth(window.innerWidth); update_control(); @@ -162,6 +163,19 @@ export default function CameraAddOn(props: PropTypes) { setActiveBtnSettings(buttonName); }; + function changeColorButton (ImgID, Force = false) + { + const imgElementButton = document.getElementById(ImgID) as HTMLImageElement; + if (imgElementButton) { + if (Force) + imgElementButton.src = "/images/photo-camera-red.png"; + else if (imgElementButton.src.includes("photo-camera-white")) + imgElementButton.src = "/images/photo-camera-red.png"; + else + imgElementButton.src = "/images/photo-camera-white.png"; + }; + } + // action Click Photo const handleClickActionPhoto: GenericMouseEventHandler< HTMLImageElement @@ -172,15 +186,15 @@ export default function CameraAddOn(props: PropTypes) { await startPhoto(CameraType[activeBtnPhoto], connectionCtx, setErrorTxt); // Change the image source using the ID const imgElement = document.getElementById("TakePhoto") as HTMLImageElement; - if (imgElement) { + if (imgElement) { imgElement.src = "/images/photo-camera-red.png"; } - // Reset the image source back to its original source after a delay (3000 milliseconds) + // Reset the image source back to its original source after a delay setTimeout(() => { if (imgElement) { imgElement.src = "/images/photo-camera-white.png"; } - }, 3000); + }, 2000); // Reset the active action after the photo is taken setActiveAction(undefined); }; @@ -195,16 +209,8 @@ export default function CameraAddOn(props: PropTypes) { // Wait for startVideo() to finish before continuing await startVideo(CameraType[activeBtnVideo], connectionCtx, setErrorTxt); // Change the image source using the ID - const imgElement = document.getElementById("TakeVideo") as HTMLImageElement; - if (imgElement) { - imgElement.src = "/images/photo-camera-red.png"; - } - // Reset the image source back to its original source after a delay (3000 milliseconds) - setTimeout(() => { - if (imgElement) { - imgElement.src = "/images/photo-camera-white.png"; - } - }, 3000); + changeColorButton("TakeVideo", true); + intervalTimer.current = setInterval(changeColorButton, 2000, "TakeVideo"); }; // action Click Stop Video @@ -214,16 +220,9 @@ export default function CameraAddOn(props: PropTypes) { // Wait for stopVideo() to finish before continuing await stopVideo(CameraType[activeBtnVideo], connectionCtx, setErrorTxt); // Change the image source using the ID - const imgElement = document.getElementById("TakeVideo") as HTMLImageElement; - if (imgElement) { - imgElement.src = "/images/photo-camera-red.png"; - } - // Reset the image source back to its original source after a delay (3000 milliseconds) - setTimeout(() => { - if (imgElement) { - imgElement.src = "/images/photo-camera-white.png"; - } - }, 3000); + clearInterval(intervalTimer.current); + changeColorButton("TakeVideo", true); + setTimeout(changeColorButton, 2000, "TakeVideo"); // Reset the active action after the photo is taken setActiveAction(undefined); }; @@ -242,18 +241,12 @@ export default function CameraAddOn(props: PropTypes) { colValue, connectionCtx, setErrorTxt, - setActiveAction + setActiveAction, + stopPanoAuto ); - const imgElement = document.getElementById("TakePano") as HTMLImageElement; - if (imgElement) { - imgElement.src = "/images/photo-camera-red.png"; - } - // Reset the image source back to its original source after a delay (3000 milliseconds) - setTimeout(() => { - if (imgElement) { - imgElement.src = "/images/photo-camera-white.png"; - } - }, 3000); + // Change the image source using the ID + changeColorButton("TakePano", true); + intervalTimer.current = setInterval(changeColorButton, 2000, "TakePano"); }; // action Click Stop Pano @@ -262,16 +255,19 @@ export default function CameraAddOn(props: PropTypes) { > = async () => { // Wait for stopPano() to finish before continuing await stopPano(CameraType[activeBtnPano], connectionCtx, setErrorTxt); - const imgElement = document.getElementById("TakePano") as HTMLImageElement; - if (imgElement) { - imgElement.src = "/images/photo-camera-red.png"; - } - // Reset the image source back to its original source after a delay (3000 milliseconds) - setTimeout(() => { - if (imgElement) { - imgElement.src = "/images/photo-camera-white.png"; - } - }, 3000); + // Change the image source using the ID + clearInterval(intervalTimer.current); + changeColorButton("TakePano", true); + setTimeout(changeColorButton, 2000, "TakePano"); + // Reset the active action after the photo is taken + setActiveAction(undefined); + }; + + const stopPanoAuto = () => { + // Change the image source using the ID + clearInterval(intervalTimer.current); + changeColorButton("TakePano", true); + setTimeout(changeColorButton, 2000, "TakePano"); // Reset the active action after the photo is taken setActiveAction(undefined); }; @@ -290,21 +286,12 @@ export default function CameraAddOn(props: PropTypes) { intervalBurstValue, connectionCtx, setErrorTxt, - setActiveAction + setActiveAction, + stopBurstAuto ); // Change the image source using the ID - const imgElement = document.getElementById( - "TakeBurstPhoto" - ) as HTMLImageElement; - if (imgElement) { - imgElement.src = "/images/photo-camera-red.png"; - } - // Reset the image source back to its original source after a delay (3000 milliseconds) - setTimeout(() => { - if (imgElement) { - imgElement.src = "/images/photo-camera-white.png"; - } - }, 3000); + changeColorButton("TakeBurstPhoto", true); + intervalTimer.current = setInterval(changeColorButton, 2000, "TakeBurstPhoto"); }; // action Click Stop Burst @@ -314,20 +301,18 @@ export default function CameraAddOn(props: PropTypes) { // Wait for stopBurst() to finish before continuing await stopBurst(CameraType[activeBtnBurst], connectionCtx, setErrorTxt); // Change the image source using the ID - const imgElement = document.getElementById( - "TakeBurstPhoto" - ) as HTMLImageElement; - if (imgElement) { - imgElement.src = "/images/photo-camera-red.png"; - } - // Reset the image source back to its original source after a delay (3000 milliseconds) - setTimeout(() => { - if (imgElement) { - imgElement.src = "/images/photo-camera-white.png"; - } - }, 3000); + clearInterval(intervalTimer.current); + changeColorButton("TakeBurstPhoto", true); + setTimeout(changeColorButton, 2000, "TakeBurstPhoto"); // Reset the active action after the photo is taken setActiveAction(undefined); + }; + + const stopBurstAuto = () => { + // Change the image source using the ID + clearInterval(intervalTimer.current); + changeColorButton("TakeBurstPhoto", true); + setTimeout(changeColorButton, 2000, "TakeBurstPhoto"); // Reset the active action after the photo is taken setActiveAction(undefined); }; @@ -339,28 +324,19 @@ export default function CameraAddOn(props: PropTypes) { // Update state to set the active button setActiveAction(PhotosModeActions[4].toString()); - // Wait for startBurst() to finish before continuing + // Wait for startTimeLapse() to finish before continuing await startTimeLapse( - CameraType[activeBtnBurst], + CameraType[activeBtnTimeLapse], intervalIndexValue, totalTimeIndexValue, connectionCtx, setErrorTxt, - setActiveAction + setActiveAction, + stopTimeLapseAuto ); // Change the image source using the ID - const imgElement = document.getElementById( - "TakeTimeLapse" - ) as HTMLImageElement; - if (imgElement) { - imgElement.src = "/images/photo-camera-red.png"; - } - // Reset the image source back to its original source after a delay (3000 milliseconds) - setTimeout(() => { - if (imgElement) { - imgElement.src = "/images/photo-camera-white.png"; - } - }, 3000); + changeColorButton("TakeTimeLapse", true); + intervalTimer.current = setInterval(changeColorButton, 2000, "TakeTimeLapse"); }; // action Click Stop Time Lapse @@ -369,19 +345,14 @@ export default function CameraAddOn(props: PropTypes) { > = async () => { // Wait for stopTimeLapse() to finish before continuing await stopTimeLapse(CameraType[activeBtnBurst], connectionCtx, setErrorTxt); + // stopTimeLapseAuto is called + }; + + const stopTimeLapseAuto = () => { // Change the image source using the ID - const imgElement = document.getElementById( - "TakeTimeLapse" - ) as HTMLImageElement; - if (imgElement) { - imgElement.src = "/images/photo-camera-red.png"; - } - // Reset the image source back to its original source after a delay (3000 milliseconds) - setTimeout(() => { - if (imgElement) { - imgElement.src = "/images/photo-camera-white.png"; - } - }, 3000); + clearInterval(intervalTimer.current); + changeColorButton("TakeTimeLapse", true); + setTimeout(changeColorButton, 2000, "TakeTimeLapse"); // Reset the active action after the photo is taken setActiveAction(undefined); }; diff --git a/src/lib/photo_utils.ts b/src/lib/photo_utils.ts index 3bb0fbf6..cd624a23 100644 --- a/src/lib/photo_utils.ts +++ b/src/lib/photo_utils.ts @@ -335,7 +335,8 @@ export async function startPano( cols: number, connectionCtx: ConnectionContextType, setErrorTxt: Function, - setActiveAction: Function + setActiveAction: Function, + stopAction: Function ) { if (connectionCtx.IPDwarf === undefined) { return; @@ -350,6 +351,15 @@ export async function startPano( callback("Panorama Success"); } } else get_error(result_data, setErrorTxt); + } else if ( + result_data.cmd == Dwarfii_Api.DwarfCMD.CMD_PANORAMA_START_EULER_RANGE + ) { + if (result_data.data.code == Dwarfii_Api.DwarfErrorCode.OK) { + setErrorTxt("Panorama Success"); + if (callback) { + callback("Panorama Success"); + } + } else get_error(result_data, setErrorTxt); } else if ( result_data.cmd == Dwarfii_Api.DwarfCMD.CMD_NOTIFY_PANORAMA_PROGRESS ) { @@ -373,7 +383,10 @@ export async function startPano( ) { setErrorTxt("Stopping Panorama"); // End of Action - setActiveAction(undefined); + if (stopAction) + stopAction(); + else setActiveAction(undefined); + if (callback) { callback("Stopping Panorama"); } @@ -545,7 +558,8 @@ export async function startBurst( interval: number, connectionCtx: ConnectionContextType, setErrorTxt: Function, - setActiveAction: Function + setActiveAction: Function, + stopAction: Function ) { if (connectionCtx.IPDwarf === undefined) { return; @@ -598,7 +612,9 @@ export async function startBurst( ) { setErrorTxt("Stopping Burst "); // End of Action - setActiveAction(undefined); + if (stopAction) + stopAction(); + else setActiveAction(undefined); if (callback) { callback("Stopping Burst"); } @@ -804,7 +820,8 @@ export async function startTimeLapse( totalTime_index: number, connectionCtx: ConnectionContextType, setErrorTxt: Function, - setActiveAction: Function + setActiveAction: Function, + stopAction: Function ) { if (connectionCtx.IPDwarf === undefined) { return; @@ -864,7 +881,9 @@ export async function startTimeLapse( ) { setErrorTxt("Stopping TimeLapse "); // End of Action - setActiveAction(undefined); + if (stopAction) + stopAction(); + else setActiveAction(undefined); if (callback) { callback("Stopping TimeLapse"); } diff --git a/src/locales/de.ts b/src/locales/de.ts index 03545b7e..bb7d3f3d 100644 --- a/src/locales/de.ts +++ b/src/locales/de.ts @@ -145,7 +145,7 @@ const translations = { cCameraAddOnPhoto: "Foto", cCameraAddOnVideo: "Video", cCameraAddOnPanorama: "Panorama", - cCameraAddonTimeLapse: "Zeitraffer", + cCameraAddOnTimeLapse: "Zeitraffer", cCameraBurstSettingsCount: "Anzahl", cCameraBurstSettingsinterval: "Intervall", cCameraTitle: "Astro Photos", diff --git a/src/locales/en.ts b/src/locales/en.ts index 1217940c..3b2a3fba 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -145,7 +145,7 @@ const translations = { cCameraAddOnPhoto: "Photo", cCameraAddOnVideo: "Video", cCameraAddOnPanorama: "Panorama", - cCameraAddonTimeLapse: "Time Lapse", + cCameraAddOnTimeLapse: "Time Lapse", cCameraBurstSettingsCount: "Count", cCameraBurstSettingsinterval: "Interval", cCameraTitle: "Astro Photos", diff --git a/src/locales/es.ts b/src/locales/es.ts index d0e073b5..b4915602 100644 --- a/src/locales/es.ts +++ b/src/locales/es.ts @@ -146,7 +146,7 @@ const translations = { cCameraAddOnPhoto: "Foto", cCameraAddOnVideo: "Video", cCameraAddOnPanorama: "Panorama", - cCameraAddonTimeLapse: "Lapso de tiempo", + cCameraAddOnTimeLapse: "Lapso de tiempo", cCameraBurstSettingsCount: "Contar", cCameraBurstSettingsinterval: "Intervalo", cCameraTitle: "Astro Photos", diff --git a/src/locales/nl.ts b/src/locales/nl.ts index 6f2b97f3..84a1b6d2 100644 --- a/src/locales/nl.ts +++ b/src/locales/nl.ts @@ -147,7 +147,7 @@ const translations = { cCameraAddOnPhoto: "Foto", cCameraAddOnVideo: "Video", cCameraAddOnPanorama: "Panorama", - cCameraAddonTimeLapse: "Timelapse", + cCameraAddOnTimeLapse: "Timelapse", cCameraBurstSettingsCount: "Tellen", cCameraBurstSettingsinterval: "Interval", cCameraTitle: "Astro Photos", From ffc1c5bb47901ec2907269667eabc85d6895932c Mon Sep 17 00:00:00 2001 From: stevejcl Date: Tue, 14 May 2024 16:37:03 +0200 Subject: [PATCH 2/4] Correction Timer Camera --- src/components/imaging/CameraAddOn.tsx | 12 ++-- src/components/imaging/ImagingMenu.tsx | 79 ++++++++++++++-------- src/components/shared/CalibrationDwarf.tsx | 22 +++--- src/db/db_utils.ts | 10 ++- src/stores/ConnectionContext.tsx | 8 ++- src/types.d.ts | 9 ++- 6 files changed, 89 insertions(+), 51 deletions(-) diff --git a/src/components/imaging/CameraAddOn.tsx b/src/components/imaging/CameraAddOn.tsx index 3530ffbe..142fa26a 100644 --- a/src/components/imaging/CameraAddOn.tsx +++ b/src/components/imaging/CameraAddOn.tsx @@ -81,7 +81,7 @@ export default function CameraAddOn(props: PropTypes) { let WidthSlidePane = useRef("1500px"); let WidthCircularSlider = useRef(150); let trackSize = useRef(24); - let intervalTimer = useRef(0); + let intervalTimer = useRef | undefined>(undefined); let gLastTimeMotorCmd = Date.now(); let gMotorState = false; @@ -102,9 +102,13 @@ export default function CameraAddOn(props: PropTypes) { return () => { window.removeEventListener("resize", handleResize); + if (intervalTimer.current) { + clearInterval(intervalTimer.current); + } }; - }, []); + }, []); // Empty dependency array means this effect runs only once on mount + const PhotosModeActions = [ "Photo", "Video", @@ -210,7 +214,7 @@ export default function CameraAddOn(props: PropTypes) { await startVideo(CameraType[activeBtnVideo], connectionCtx, setErrorTxt); // Change the image source using the ID changeColorButton("TakeVideo", true); - intervalTimer.current = setInterval(changeColorButton, 2000, "TakeVideo"); + intervalTimer.current = setInterval(changeColorButton, 2000, "TakeVideo"); }; // action Click Stop Video @@ -927,7 +931,7 @@ export default function CameraAddOn(props: PropTypes) {
-
{t("cCameraAddonTimeLapse")}
+
{t("cCameraAddOnTimeLapse")}
>(); let timerSession: ReturnType; - let timerSessionInit: boolean = false; + let timerSessionInit: boolean = (connectionCtx.timerGlobal !== undefined); useEffect(() => { let testTimer: string | any = ""; - if (timerGlobal) testTimer = timerGlobal.toString(); + if (connectionCtx.timerGlobal) testTimer = connectionCtx.timerGlobal.toString(); console.debug(" TG --- Global Timer:", testTimer, connectionCtx); if (connectionCtx.imagingSession.isRecording) console.debug("TG isRecording True:", testTimer, connectionCtx); @@ -61,19 +59,28 @@ export default function ImagingMenu(props: PropType) { if (connectionCtx.imagingSession.endRecording) console.debug("TG endRecording True:", testTimer, connectionCtx); else console.debug("TG endRecording False:", testTimer, connectionCtx); - }, [timerGlobal]); // eslint-disable-line react-hooks/exhaustive-deps + }, [connectionCtx.timerGlobal]); // eslint-disable-line react-hooks/exhaustive-deps useEffect(() => { let testTimer: string | any = ""; - if (timerGlobal) testTimer = timerGlobal.toString(); - if (connectionCtx.imagingSession.isRecording) + if (connectionCtx.timerGlobal) testTimer = connectionCtx.timerGlobal.toString(); + if (connectionCtx.imagingSession.isRecording) { console.debug("setIsRecording True:", testTimer, connectionCtx); - else console.debug("setIsRecording False:", testTimer, connectionCtx); + if (!timerSessionInit) { + timerSession = startTimer(); + if (timerSession) { + timerSessionInit = true; + testTimer = timerSession.toString(); + console.debug("startTimer timer:", testTimer, connectionCtx); + connectionCtx.setTimerGlobal(timerSession); + } else timerSessionInit = false; + } + } else console.debug("setIsRecording False:", testTimer, connectionCtx); }, [connectionCtx.imagingSession.isRecording]); // eslint-disable-line react-hooks/exhaustive-deps useEffect(() => { let testTimer: string | any = ""; - if (timerGlobal) testTimer = timerGlobal.toString(); + if (connectionCtx.timerGlobal) testTimer = connectionCtx.timerGlobal.toString(); if (connectionCtx.imagingSession.endRecording) console.debug("endRecording True:", testTimer, connectionCtx); else console.debug("endRecording false:", testTimer, connectionCtx); @@ -81,7 +88,7 @@ export default function ImagingMenu(props: PropType) { useEffect(() => { let testTimer: string | any = ""; - if (timerGlobal) testTimer = timerGlobal.toString(); + if (connectionCtx.timerGlobal) testTimer = connectionCtx.timerGlobal.toString(); if (connectionCtx.imagingSession.isStackedCountStart) console.debug("isStackedCountStart True:", testTimer, connectionCtx); else console.debug("isStackedCountStart false:", testTimer, connectionCtx); @@ -89,11 +96,17 @@ export default function ImagingMenu(props: PropType) { useEffect(() => { let testTimer: string | any = ""; - if (timerGlobal) testTimer = timerGlobal.toString(); + if (connectionCtx.timerGlobal) testTimer = connectionCtx.timerGlobal.toString(); + else if (timerSession) testTimer = timerSession.toString(); if (connectionCtx.imagingSession.isGoLive) { console.debug("isGoLive True:", testTimer, connectionCtx); - endImagingSession(); + stopTimer(); } else console.debug("isGoLive false:", testTimer, connectionCtx); + return () => { + if (connectionCtx.imagingSession.isGoLive) { + stopTimer(); + } + }; }, [connectionCtx.imagingSession.isGoLive]); // eslint-disable-line react-hooks/exhaustive-deps function isValid() { @@ -106,7 +119,7 @@ export default function ImagingMenu(props: PropType) { function startTimer() { let timer: string | any = ""; - if (!timerSessionInit) { + if (!connectionCtx.timerGlobal) { timer = setInterval(() => { let time = calculateSessionTime(connectionCtx); if (time) { @@ -114,9 +127,10 @@ export default function ImagingMenu(props: PropType) { prev["sessionElaspsedTime"] = time as string; return { ...prev }; }); + saveImagingSessionDb("sessionElaspsedTime", time.toString()); } }, 2000); - } else timer = timerSession; + } else timer = connectionCtx.timerGlobal; return timer; } @@ -136,7 +150,7 @@ export default function ImagingMenu(props: PropType) { timerSessionInit = true; testTimer = timerSession.toString(); console.debug("startTimer timer:", testTimer, connectionCtx); - setTimerGlobal(timerSession); + connectionCtx.setTimerGlobal(timerSession); } else timerSessionInit = false; } @@ -281,15 +295,15 @@ export default function ImagingMenu(props: PropType) { } const customMessageHandler = (txt_info, result_data) => { - // CMD_ASTRO_GO_LIVE -> Stop Capture + // + // -> Stop Capture if (result_data.cmd == Dwarfii_Api.DwarfCMD.CMD_ASTRO_GO_LIVE) { if (result_data.data.code != Dwarfii_Api.DwarfErrorCode.OK) { console.debug("Go Live error", {}, connectionCtx); } else { console.debug("Go Live ok", {}, connectionCtx); } - saveImagingSessionDb("goLive", false.toString()); - saveImagingSessionDb("endRecording", false.toString()); + endPreview(); } else { console.debug("", result_data, connectionCtx); } @@ -317,7 +331,7 @@ export default function ImagingMenu(props: PropType) { } } - function endImagingSession() { + function stopTimer() { let testTimer: string | any = ""; if (timerSession) { testTimer = timerSession.toString(); @@ -327,32 +341,40 @@ export default function ImagingMenu(props: PropType) { connectionCtx ); } - if (timerGlobal) { - testTimer = timerGlobal.toString(); + + // use connectionContext + if (connectionCtx.timerGlobal) { + testTimer = connectionCtx.timerGlobal.toString(); console.debug( "ImagingSession tG clearInterval:", testTimer, connectionCtx ); } - // timerSession if Photos Session is completed ! + if (connectionCtx.timerGlobal) clearInterval(connectionCtx.timerGlobal); + connectionCtx.setTimerGlobal(undefined); + if (timerSession) clearInterval(timerSession); - if (timerGlobal) clearInterval(timerGlobal); + timerSessionInit = false; + } + + function endImagingSession() { + stopTimer(); if (connectionCtx.imagingSession.isRecording) { connectionCtx.setImagingSession((prev) => { prev["isRecording"] = false; return { ...prev }; }); + saveImagingSessionDb("isRecording", false.toString()); } - if (connectionCtx.imagingSession.endRecording) { + if (!connectionCtx.imagingSession.endRecording) { connectionCtx.setImagingSession((prev) => { prev["endRecording"] = true; return { ...prev }; }); + saveImagingSessionDb("endRecording", true.toString()); } - saveImagingSessionDb("isRecording", false.toString()); - saveImagingSessionDb("endRecording", true.toString()); } function endPreview() { @@ -568,7 +590,6 @@ export default function ImagingMenu(props: PropType) { { goLiveHandler(); - endPreview(); }} title="End Current Session" /> @@ -579,7 +600,6 @@ export default function ImagingMenu(props: PropType) { { goLiveHandler(); - endPreview(); }} color_stroke={"currentColor"} title="Wait till the End of Stacking" @@ -715,7 +735,7 @@ export default function ImagingMenu(props: PropType) { ); } - return ""; + return (""); } return ( @@ -828,7 +848,6 @@ export default function ImagingMenu(props: PropType) { className="" onClick={() => { goLiveHandler(); - endPreview(); }} title="End Current Session" > diff --git a/src/components/shared/CalibrationDwarf.tsx b/src/components/shared/CalibrationDwarf.tsx index 9580e51c..402928d9 100644 --- a/src/components/shared/CalibrationDwarf.tsx +++ b/src/components/shared/CalibrationDwarf.tsx @@ -204,7 +204,7 @@ export default function CalibrationDwarf() {