fix: add nullish coalescing to parameter dialogs

Fixed "Cannot read properties of undefined (reading 'toFixed')" errors
in TimeBasedParameterDialog and DynamicsParameterDialog by adding
nullish coalescing operators with default values to all parameter
accesses. This prevents errors when loading presets that have partial
parameter sets.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-17 20:50:48 +01:00
parent 8a0bd46593
commit 2fc1620495
2 changed files with 45 additions and 45 deletions

View File

@@ -371,11 +371,11 @@ export function DynamicsParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Threshold</span>
<span className="text-muted-foreground font-mono">
{parameters.threshold.toFixed(1)} dB
{(parameters.threshold ?? -20).toFixed(1)} dB
</span>
</label>
<Slider
value={[parameters.threshold]}
value={[(parameters.threshold ?? -20)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, threshold: value }))
}
@@ -396,11 +396,11 @@ export function DynamicsParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Ratio</span>
<span className="text-muted-foreground font-mono">
{(parameters as CompressorParameters | GateParameters).ratio.toFixed(1)}:1
{((parameters as CompressorParameters | GateParameters).ratio ?? 4).toFixed(1)}:1
</span>
</label>
<Slider
value={[(parameters as CompressorParameters | GateParameters).ratio]}
value={[((parameters as CompressorParameters | GateParameters).ratio ?? 4)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, ratio: value }))
}
@@ -421,11 +421,11 @@ export function DynamicsParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Attack</span>
<span className="text-muted-foreground font-mono">
{parameters.attack.toFixed(2)} ms
{(parameters.attack ?? 5).toFixed(2)} ms
</span>
</label>
<Slider
value={[Math.log10(parameters.attack)]}
value={[Math.log10(parameters.attack ?? 5)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, attack: Math.pow(10, value) }))
}
@@ -445,11 +445,11 @@ export function DynamicsParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Release</span>
<span className="text-muted-foreground font-mono">
{parameters.release.toFixed(1)} ms
{(parameters.release ?? 50).toFixed(1)} ms
</span>
</label>
<Slider
value={[Math.log10(parameters.release)]}
value={[Math.log10(parameters.release ?? 50)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, release: Math.pow(10, value) }))
}
@@ -470,11 +470,11 @@ export function DynamicsParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Knee</span>
<span className="text-muted-foreground font-mono">
{(parameters as CompressorParameters | GateParameters).knee.toFixed(1)} dB
{((parameters as CompressorParameters | GateParameters).knee ?? 3).toFixed(1)} dB
</span>
</label>
<Slider
value={[(parameters as CompressorParameters | GateParameters).knee]}
value={[((parameters as CompressorParameters | GateParameters).knee ?? 3)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, knee: value }))
}
@@ -496,12 +496,12 @@ export function DynamicsParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Makeup Gain</span>
<span className="text-muted-foreground font-mono">
{(parameters as CompressorParameters | LimiterParameters).makeupGain > 0 ? '+' : ''}
{(parameters as CompressorParameters | LimiterParameters).makeupGain.toFixed(1)} dB
{((parameters as CompressorParameters | LimiterParameters).makeupGain ?? 0) > 0 ? '+' : ''}
{((parameters as CompressorParameters | LimiterParameters).makeupGain ?? 0).toFixed(1)} dB
</span>
</label>
<Slider
value={[(parameters as CompressorParameters | LimiterParameters).makeupGain]}
value={[((parameters as CompressorParameters | LimiterParameters).makeupGain ?? 0)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, makeupGain: value }))
}

View File

@@ -331,11 +331,11 @@ export function TimeBasedParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Delay Time</span>
<span className="text-muted-foreground font-mono">
{(parameters as DelayParameters).time.toFixed(0)} ms
{((parameters as DelayParameters).time ?? 250).toFixed(0)} ms
</span>
</label>
<Slider
value={[(parameters as DelayParameters).time]}
value={[((parameters as DelayParameters).time ?? 250)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, time: value }))
}
@@ -351,11 +351,11 @@ export function TimeBasedParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Feedback</span>
<span className="text-muted-foreground font-mono">
{((parameters as DelayParameters).feedback * 100).toFixed(0)}%
{(((parameters as DelayParameters).feedback ?? 0.4) * 100).toFixed(0)}%
</span>
</label>
<Slider
value={[(parameters as DelayParameters).feedback]}
value={[((parameters as DelayParameters).feedback ?? 0.4)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, feedback: value }))
}
@@ -375,11 +375,11 @@ export function TimeBasedParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Room Size</span>
<span className="text-muted-foreground font-mono">
{((parameters as ReverbParameters).roomSize * 100).toFixed(0)}%
{(((parameters as ReverbParameters).roomSize ?? 0.6) * 100).toFixed(0)}%
</span>
</label>
<Slider
value={[(parameters as ReverbParameters).roomSize]}
value={[((parameters as ReverbParameters).roomSize ?? 0.6)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, roomSize: value }))
}
@@ -395,11 +395,11 @@ export function TimeBasedParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Damping</span>
<span className="text-muted-foreground font-mono">
{((parameters as ReverbParameters).damping * 100).toFixed(0)}%
{(((parameters as ReverbParameters).damping ?? 0.3) * 100).toFixed(0)}%
</span>
</label>
<Slider
value={[(parameters as ReverbParameters).damping]}
value={[((parameters as ReverbParameters).damping ?? 0.3)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, damping: value }))
}
@@ -419,11 +419,11 @@ export function TimeBasedParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Rate</span>
<span className="text-muted-foreground font-mono">
{(parameters as ChorusParameters).rate.toFixed(2)} Hz
{((parameters as ChorusParameters).rate ?? 1.0).toFixed(2)} Hz
</span>
</label>
<Slider
value={[(parameters as ChorusParameters).rate]}
value={[((parameters as ChorusParameters).rate ?? 1.0)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, rate: value }))
}
@@ -439,11 +439,11 @@ export function TimeBasedParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Depth</span>
<span className="text-muted-foreground font-mono">
{((parameters as ChorusParameters).depth * 100).toFixed(0)}%
{(((parameters as ChorusParameters).depth ?? 0.5) * 100).toFixed(0)}%
</span>
</label>
<Slider
value={[(parameters as ChorusParameters).depth]}
value={[((parameters as ChorusParameters).depth ?? 0.5)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, depth: value }))
}
@@ -459,11 +459,11 @@ export function TimeBasedParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Base Delay</span>
<span className="text-muted-foreground font-mono">
{(parameters as ChorusParameters).delay.toFixed(1)} ms
{((parameters as ChorusParameters).delay ?? 25).toFixed(1)} ms
</span>
</label>
<Slider
value={[(parameters as ChorusParameters).delay]}
value={[((parameters as ChorusParameters).delay ?? 25)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, delay: value }))
}
@@ -483,11 +483,11 @@ export function TimeBasedParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Rate</span>
<span className="text-muted-foreground font-mono">
{(parameters as FlangerParameters).rate.toFixed(2)} Hz
{((parameters as FlangerParameters).rate ?? 0.5).toFixed(2)} Hz
</span>
</label>
<Slider
value={[(parameters as FlangerParameters).rate]}
value={[((parameters as FlangerParameters).rate ?? 0.5)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, rate: value }))
}
@@ -503,11 +503,11 @@ export function TimeBasedParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Depth</span>
<span className="text-muted-foreground font-mono">
{((parameters as FlangerParameters).depth * 100).toFixed(0)}%
{(((parameters as FlangerParameters).depth ?? 0.5) * 100).toFixed(0)}%
</span>
</label>
<Slider
value={[(parameters as FlangerParameters).depth]}
value={[((parameters as FlangerParameters).depth ?? 0.5)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, depth: value }))
}
@@ -523,11 +523,11 @@ export function TimeBasedParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Feedback</span>
<span className="text-muted-foreground font-mono">
{((parameters as FlangerParameters).feedback * 100).toFixed(0)}%
{(((parameters as FlangerParameters).feedback ?? 0.4) * 100).toFixed(0)}%
</span>
</label>
<Slider
value={[(parameters as FlangerParameters).feedback]}
value={[((parameters as FlangerParameters).feedback ?? 0.4)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, feedback: value }))
}
@@ -543,11 +543,11 @@ export function TimeBasedParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Base Delay</span>
<span className="text-muted-foreground font-mono">
{(parameters as FlangerParameters).delay.toFixed(1)} ms
{((parameters as FlangerParameters).delay ?? 3).toFixed(1)} ms
</span>
</label>
<Slider
value={[(parameters as FlangerParameters).delay]}
value={[((parameters as FlangerParameters).delay ?? 3)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, delay: value }))
}
@@ -567,11 +567,11 @@ export function TimeBasedParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Rate</span>
<span className="text-muted-foreground font-mono">
{(parameters as PhaserParameters).rate.toFixed(2)} Hz
{((parameters as PhaserParameters).rate ?? 0.6).toFixed(2)} Hz
</span>
</label>
<Slider
value={[(parameters as PhaserParameters).rate]}
value={[((parameters as PhaserParameters).rate ?? 0.6)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, rate: value }))
}
@@ -587,11 +587,11 @@ export function TimeBasedParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Depth</span>
<span className="text-muted-foreground font-mono">
{((parameters as PhaserParameters).depth * 100).toFixed(0)}%
{(((parameters as PhaserParameters).depth ?? 0.5) * 100).toFixed(0)}%
</span>
</label>
<Slider
value={[(parameters as PhaserParameters).depth]}
value={[((parameters as PhaserParameters).depth ?? 0.5)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, depth: value }))
}
@@ -607,11 +607,11 @@ export function TimeBasedParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Feedback</span>
<span className="text-muted-foreground font-mono">
{((parameters as PhaserParameters).feedback * 100).toFixed(0)}%
{(((parameters as PhaserParameters).feedback ?? 0.4) * 100).toFixed(0)}%
</span>
</label>
<Slider
value={[(parameters as PhaserParameters).feedback]}
value={[((parameters as PhaserParameters).feedback ?? 0.4)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, feedback: value }))
}
@@ -627,11 +627,11 @@ export function TimeBasedParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Stages</span>
<span className="text-muted-foreground font-mono">
{(parameters as PhaserParameters).stages.toFixed(0)}
{((parameters as PhaserParameters).stages ?? 6).toFixed(0)}
</span>
</label>
<Slider
value={[(parameters as PhaserParameters).stages]}
value={[((parameters as PhaserParameters).stages ?? 6)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, stages: Math.floor(value) }))
}
@@ -649,11 +649,11 @@ export function TimeBasedParameterDialog({
<label className="text-sm font-medium text-foreground flex justify-between">
<span>Mix (Dry/Wet)</span>
<span className="text-muted-foreground font-mono">
{(parameters.mix * 100).toFixed(0)}%
{((parameters.mix ?? 0.5) * 100).toFixed(0)}%
</span>
</label>
<Slider
value={[parameters.mix]}
value={[(parameters.mix ?? 0.5)]}
onValueChange={([value]) =>
setParameters((prev) => ({ ...prev, mix: value }))
}