Compare commits
2
Commits
b74857d7f6
...
4aae47cd27
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4aae47cd27 | ||
|
|
61f821c3e9 |
@@ -16,7 +16,7 @@ import { Channel, PEQBand, PEQFilter, PEQ, Crossover } from '../../types';
|
|||||||
import { DSP408 as DSP } from '../../../../types';
|
import { DSP408 as DSP } from '../../../../types';
|
||||||
import { CrossoverFilter } from '../../types';
|
import { CrossoverFilter } from '../../types';
|
||||||
import { LinearGraph, LinearGraphHandle } from '../../../../components/LinearGraph/LinearGraph';
|
import { LinearGraph, LinearGraphHandle } from '../../../../components/LinearGraph/LinearGraph';
|
||||||
import { useRef, useState } from 'react';
|
import { useRef, useState, useEffect } from 'react';
|
||||||
import './ChannelSection.css';
|
import './ChannelSection.css';
|
||||||
import ChannelGroup from '../../../../components/ChannelGroup/ChannelGroup';
|
import ChannelGroup from '../../../../components/ChannelGroup/ChannelGroup';
|
||||||
import Button from '../../../../components/Button/Button';
|
import Button from '../../../../components/Button/Button';
|
||||||
@@ -441,6 +441,7 @@ function ChannelSection({
|
|||||||
const [activeBand, setActiveBand] = useState<PEQBand>(PEQBand.B1);
|
const [activeBand, setActiveBand] = useState<PEQBand>(PEQBand.B1);
|
||||||
const [graphView, setGraphView] = useState<GraphView>('both');
|
const [graphView, setGraphView] = useState<GraphView>('both');
|
||||||
const [resetting, setResetting] = useState(false);
|
const [resetting, setResetting] = useState(false);
|
||||||
|
const [isResetConfirmOpen, setIsResetConfirmOpen] = useState(false);
|
||||||
|
|
||||||
// Live values
|
// Live values
|
||||||
const [liveHpFreq, setLiveHpFreq] = useState<number>(FREQUENCY_MIN);
|
const [liveHpFreq, setLiveHpFreq] = useState<number>(FREQUENCY_MIN);
|
||||||
@@ -461,6 +462,23 @@ function ChannelSection({
|
|||||||
|
|
||||||
const bandsOrder = isInput ? PEQ_BANDS_ORDER.slice(0, -1) : PEQ_BANDS_ORDER;
|
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 () => {
|
const handleResetPeq = async () => {
|
||||||
if (resetting) return;
|
if (resetting) return;
|
||||||
setResetting(true);
|
setResetting(true);
|
||||||
@@ -476,6 +494,11 @@ function ChannelSection({
|
|||||||
setResetting(false);
|
setResetting(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const confirmResetPeq = async () => {
|
||||||
|
setIsResetConfirmOpen(false);
|
||||||
|
await handleResetPeq();
|
||||||
|
};
|
||||||
|
|
||||||
const handleBypassClick = () => {
|
const handleBypassClick = () => {
|
||||||
setPeqBypass(channel, !ActivePeq.bypass);
|
setPeqBypass(channel, !ActivePeq.bypass);
|
||||||
};
|
};
|
||||||
@@ -681,11 +704,32 @@ function ChannelSection({
|
|||||||
bypass={ActivePeq.bypass}
|
bypass={ActivePeq.bypass}
|
||||||
resetting={resetting}
|
resetting={resetting}
|
||||||
onBypass={handleBypassClick}
|
onBypass={handleBypassClick}
|
||||||
onReset={handleResetPeq}
|
onReset={handleResetClick}
|
||||||
/>
|
/>
|
||||||
</ChannelGroup>
|
</ChannelGroup>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{isResetConfirmOpen && (
|
||||||
|
<div className="confirm-modal-overlay" onClick={() => setIsResetConfirmOpen(false)}>
|
||||||
|
<div className="confirm-modal" onClick={(e) => e.stopPropagation()}>
|
||||||
|
<h3>Reset {activeChannelState.name} PEQ?</h3>
|
||||||
|
<p>
|
||||||
|
This will set all PEQ bands on {activeChannelState.name} back to flat (0 dB,
|
||||||
|
Peak). This action cannot be undone.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="confirm-modal__actions">
|
||||||
|
<Button variant="outline" onClick={() => setIsResetConfirmOpen(false)}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button variant="primary" onClick={confirmResetPeq}>
|
||||||
|
Reset
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
GEQ_BANDS_LABEL,
|
GEQ_BANDS_LABEL,
|
||||||
GEQ_CURVE_Q,
|
GEQ_CURVE_Q,
|
||||||
} from '../../constants';
|
} from '../../constants';
|
||||||
import { useState } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import './GeqSection.css';
|
import './GeqSection.css';
|
||||||
import { getGeqCurvePoints } from '../../utils/graph/geq';
|
import { getGeqCurvePoints } from '../../utils/graph/geq';
|
||||||
import { logSpace } from '../../utils/graph/curve';
|
import { logSpace } from '../../utils/graph/curve';
|
||||||
@@ -201,7 +201,7 @@ function GeqActions({
|
|||||||
minHeight: 0,
|
minHeight: 0,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{resetting ? 'Resetting…' : 'Reset'} {/* NEW */}
|
{resetting ? 'Resetting…' : 'Reset'}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -219,6 +219,20 @@ function GeqSection({
|
|||||||
const [activeChannel, setActiveChannel] = useState<InputChannel>(INPUT_ORDER[0]);
|
const [activeChannel, setActiveChannel] = useState<InputChannel>(INPUT_ORDER[0]);
|
||||||
const [liveGeq, setLiveGeq] = useState<Partial<Record<InputChannel, LiveBands>>>({});
|
const [liveGeq, setLiveGeq] = useState<Partial<Record<InputChannel, LiveBands>>>({});
|
||||||
const [resetting, setResetting] = useState(false);
|
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) => {
|
const handleLiveValue = (channel: InputChannel, band: DiscreteFrequency, value: number) => {
|
||||||
setLiveGeq((prev) => ({
|
setLiveGeq((prev) => ({
|
||||||
@@ -245,6 +259,10 @@ function GeqSection({
|
|||||||
setGeqBypass(activeChannel, !activeGeq.bypass);
|
setGeqBypass(activeChannel, !activeGeq.bypass);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleResetClick = () => {
|
||||||
|
setIsResetConfirmOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
// Sequential per-band reset, since hardware has no bulk reset command.
|
// Sequential per-band reset, since hardware has no bulk reset command.
|
||||||
const handleReset = async (channel: InputChannel) => {
|
const handleReset = async (channel: InputChannel) => {
|
||||||
if (resetting) return;
|
if (resetting) return;
|
||||||
@@ -261,6 +279,11 @@ function GeqSection({
|
|||||||
setResetting(false);
|
setResetting(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const confirmReset = async () => {
|
||||||
|
setIsResetConfirmOpen(false);
|
||||||
|
await handleReset(activeChannel);
|
||||||
|
};
|
||||||
|
|
||||||
const activeInputState = dsp.state.current_config.input_states[activeChannel];
|
const activeInputState = dsp.state.current_config.input_states[activeChannel];
|
||||||
const activeGeq = activeInputState.geq;
|
const activeGeq = activeInputState.geq;
|
||||||
const activeLiveBands = liveGeq[activeChannel];
|
const activeLiveBands = liveGeq[activeChannel];
|
||||||
@@ -306,12 +329,33 @@ function GeqSection({
|
|||||||
bypass={activeGeq.bypass}
|
bypass={activeGeq.bypass}
|
||||||
resetting={resetting}
|
resetting={resetting}
|
||||||
onBypass={handleBypassClick}
|
onBypass={handleBypassClick}
|
||||||
onReset={() => handleReset(activeChannel)}
|
onReset={handleResetClick}
|
||||||
/>
|
/>
|
||||||
</ChannelGroup>
|
</ChannelGroup>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{isResetConfirmOpen && (
|
||||||
|
<div className="confirm-modal-overlay" onClick={() => setIsResetConfirmOpen(false)}>
|
||||||
|
<div className="confirm-modal" onClick={(e) => e.stopPropagation()}>
|
||||||
|
<h3>Reset {activeInputState.name} GEQ?</h3>
|
||||||
|
<p>
|
||||||
|
This will set all GEQ bands on {activeInputState.name} back to 0 dB. This action
|
||||||
|
cannot be undone.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="confirm-modal__actions">
|
||||||
|
<Button variant="outline" onClick={() => setIsResetConfirmOpen(false)}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button variant="primary" onClick={confirmReset}>
|
||||||
|
Reset
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user