diff --git a/README.md b/README.md index 28fbd0a..b0986be 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,5 @@ This template should help get you started developing with Tauri, React and Types - Check render to improve perfoormances - Dont draw geq/peq on gain if bypass - Diplay windows on reset geq, peq -- Preset change dont reset - Check end to end behavioour \ No newline at end of file diff --git a/src/features/dsp408/components/GeqSection/GeqSection.tsx b/src/features/dsp408/components/GeqSection/GeqSection.tsx index d832eff..fcacadf 100644 --- a/src/features/dsp408/components/GeqSection/GeqSection.tsx +++ b/src/features/dsp408/components/GeqSection/GeqSection.tsx @@ -17,7 +17,7 @@ import { GEQ_BANDS_LABEL, GEQ_CURVE_Q, } from '../../constants'; -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import './GeqSection.css'; import { getGeqCurvePoints } from '../../utils/graph/geq'; import { logSpace } from '../../utils/graph/curve'; @@ -201,7 +201,7 @@ function GeqActions({ minHeight: 0, }} > - {resetting ? 'Resetting…' : 'Reset'} {/* NEW */} + {resetting ? 'Resetting…' : 'Reset'} ); @@ -219,6 +219,20 @@ function GeqSection({ const [activeChannel, setActiveChannel] = useState(INPUT_ORDER[0]); const [liveGeq, setLiveGeq] = useState>>({}); const [resetting, setResetting] = useState(false); + const [isResetConfirmOpen, setIsResetConfirmOpen] = useState(false); + + useEffect(() => { + if (!isResetConfirmOpen) return; + + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === 'Escape') { + setIsResetConfirmOpen(false); + } + }; + + window.addEventListener('keydown', handleKeyDown); + return () => window.removeEventListener('keydown', handleKeyDown); + }, [isResetConfirmOpen]); const handleLiveValue = (channel: InputChannel, band: DiscreteFrequency, value: number) => { setLiveGeq((prev) => ({ @@ -245,6 +259,10 @@ function GeqSection({ setGeqBypass(activeChannel, !activeGeq.bypass); }; + const handleResetClick = () => { + setIsResetConfirmOpen(true); + }; + // Sequential per-band reset, since hardware has no bulk reset command. const handleReset = async (channel: InputChannel) => { if (resetting) return; @@ -261,6 +279,11 @@ function GeqSection({ setResetting(false); }; + const confirmReset = async () => { + setIsResetConfirmOpen(false); + await handleReset(activeChannel); + }; + const activeInputState = dsp.state.current_config.input_states[activeChannel]; const activeGeq = activeInputState.geq; const activeLiveBands = liveGeq[activeChannel]; @@ -306,12 +329,33 @@ function GeqSection({ bypass={activeGeq.bypass} resetting={resetting} onBypass={handleBypassClick} - onReset={() => handleReset(activeChannel)} + onReset={handleResetClick} /> + + {isResetConfirmOpen && ( +
setIsResetConfirmOpen(false)}> +
e.stopPropagation()}> +

Reset {activeInputState.name} GEQ?

+

+ This will set all GEQ bands on {activeInputState.name} back to 0 dB. This action + cannot be undone. +

+ +
+ + +
+
+
+ )} ); } diff --git a/src/features/dsp408/components/InputSection/ChannelSection.tsx b/src/features/dsp408/components/InputSection/ChannelSection.tsx index 19179a9..6e0225c 100644 --- a/src/features/dsp408/components/InputSection/ChannelSection.tsx +++ b/src/features/dsp408/components/InputSection/ChannelSection.tsx @@ -16,7 +16,7 @@ import { Channel, PEQBand, PEQFilter, PEQ, Crossover } from '../../types'; import { DSP408 as DSP } from '../../../../types'; import { CrossoverFilter } from '../../types'; import { LinearGraph, LinearGraphHandle } from '../../../../components/LinearGraph/LinearGraph'; -import { useRef, useState } from 'react'; +import { useRef, useState, useEffect } from 'react'; import './ChannelSection.css'; import ChannelGroup from '../../../../components/ChannelGroup/ChannelGroup'; import Button from '../../../../components/Button/Button'; @@ -441,6 +441,7 @@ function ChannelSection({ const [activeBand, setActiveBand] = useState(PEQBand.B1); const [graphView, setGraphView] = useState('both'); const [resetting, setResetting] = useState(false); + const [isResetConfirmOpen, setIsResetConfirmOpen] = useState(false); // Live values const [liveHpFreq, setLiveHpFreq] = useState(FREQUENCY_MIN); @@ -461,6 +462,23 @@ function ChannelSection({ const bandsOrder = isInput ? PEQ_BANDS_ORDER.slice(0, -1) : PEQ_BANDS_ORDER; + useEffect(() => { + if (!isResetConfirmOpen) return; + + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === 'Escape') { + setIsResetConfirmOpen(false); + } + }; + + window.addEventListener('keydown', handleKeyDown); + return () => window.removeEventListener('keydown', handleKeyDown); + }, [isResetConfirmOpen]); + + const handleResetClick = () => { + setIsResetConfirmOpen(true); + }; + const handleResetPeq = async () => { if (resetting) return; setResetting(true); @@ -476,6 +494,11 @@ function ChannelSection({ setResetting(false); }; + const confirmResetPeq = async () => { + setIsResetConfirmOpen(false); + await handleResetPeq(); + }; + const handleBypassClick = () => { setPeqBypass(channel, !ActivePeq.bypass); }; @@ -681,11 +704,32 @@ function ChannelSection({ bypass={ActivePeq.bypass} resetting={resetting} onBypass={handleBypassClick} - onReset={handleResetPeq} + onReset={handleResetClick} /> + + {isResetConfirmOpen && ( +
setIsResetConfirmOpen(false)}> +
e.stopPropagation()}> +

Reset {activeChannelState.name} PEQ?

+

+ This will set all PEQ bands on {activeChannelState.name} back to flat (0 dB, + Peak). This action cannot be undone. +

+ +
+ + +
+
+
+ )} ); }