From e009fd18234176aff37bddd49b61f33dbda04695 Mon Sep 17 00:00:00 2001 From: Maxim Isaev Date: Sat, 25 Apr 2026 22:36:55 +0300 Subject: [PATCH] fix(settings): make normalization modes exclusive and refine LUFS UI Replace the mixed ReplayGain/Loudness controls with a single exclusive mode selector, hide RG-specific controls when LUFS is active, and align the queue tech badge behavior between RG and LUFS. Also update LUFS targets to -10..-16 ordering and default loudness target to -12. --- src/components/QueuePanel.tsx | 33 +++++++---- src/pages/Settings.tsx | 102 ++++++++++++++++++---------------- src/store/authStore.ts | 6 +- 3 files changed, 81 insertions(+), 60 deletions(-) diff --git a/src/components/QueuePanel.tsx b/src/components/QueuePanel.tsx index 20268c19..bb1edfaf 100644 --- a/src/components/QueuePanel.tsx +++ b/src/components/QueuePanel.tsx @@ -483,16 +483,16 @@ export default function QueuePanel() { const rgParts = formatQueueReplayGainParts(currentTrack, t); const baseLine = baseParts.join(' · '); const rgLine = rgParts.join(' · '); + const isLoudnessActive = normalizationEngine === 'loudness' || normalizationEngineLive === 'loudness'; const liveGainLabel = normalizationNowDb != null ? `${normalizationNowDb >= 0 ? '+' : ''}${normalizationNowDb.toFixed(2)} dB` : '—'; - const targetLabel = normalizationEngineLive === 'loudness' - ? (normalizationTargetLufs != null ? `${normalizationTargetLufs} LUFS` : '-16 LUFS') - : normalizationEngineLive === 'replaygain' - ? `ReplayGain (${replayGainMode})` - : t('queue.normOff', { defaultValue: 'Off' }); + const targetLabel = normalizationTargetLufs != null + ? `${normalizationTargetLufs} LUFS` + : '-16 LUFS'; if (!baseLine && !rgLine && !playbackSource) return null; - const showRgLine = expandReplayGain && !!rgLine; + const showRgLine = !isLoudnessActive && expandReplayGain && !!rgLine; + const showLufsLine = isLoudnessActive && expandReplayGain; return (
@@ -515,7 +515,7 @@ export default function QueuePanel() { )} {baseLine && {baseLine}} - {rgLine && ( + {!isLoudnessActive && rgLine && ( )} + {isLoudnessActive && ( + + )}
{showRgLine && ( @@ -535,12 +548,12 @@ export default function QueuePanel() { {' · '}{rgLine} )} - {(normalizationEngine === 'loudness' || normalizationEngineLive === 'loudness') && ( + {showLufsLine && ( - {t('queue.normNow', { defaultValue: 'Now' })} + Loudness {' · '}{liveGainLabel} {' · '} - {t('queue.normTarget', { defaultValue: 'Target' })} + TGT {' · '}{targetLabel} )} diff --git a/src/pages/Settings.tsx b/src/pages/Settings.tsx index c03a2a0c..b93227a9 100644 --- a/src/pages/Settings.tsx +++ b/src/pages/Settings.tsx @@ -2217,59 +2217,67 @@ export default function Settings() { icon={} >
- {/* Replay Gain */} + {/* Normalization */}
-
{t('settings.replayGain')}
-
{t('settings.replayGainDesc')}
-
- -
- {auth.replayGainEnabled && ( -
-
- Engine: - - +
{t('settings.normalization', { defaultValue: 'Normalization' })}
+
+ {t('settings.normalizationDesc', { defaultValue: 'Choose one normalization mode: ReplayGain or Loudness (LUFS).' })}
+
+
+ + + +
+
+ {auth.normalizationEngine !== 'off' && ( +
{auth.normalizationEngine === 'loudness' && ( <> -
- Apple-like automatic normalization. ReplayGain tags are ignored in this mode. -
Target LUFS: +
@@ -2321,7 +2329,7 @@ export default function Settings() { )}
)} - {auth.replayGainEnabled && auth.normalizationEngine === 'replaygain' && ( + {auth.normalizationEngine === 'replaygain' && (
diff --git a/src/store/authStore.ts b/src/store/authStore.ts index d7afd2c2..b4e58c41 100644 --- a/src/store/authStore.ts +++ b/src/store/authStore.ts @@ -51,7 +51,7 @@ interface AuthState { customGenreBlacklist: string[]; replayGainEnabled: boolean; normalizationEngine: NormalizationEngine; - loudnessTargetLufs: -16 | -14 | -12; + loudnessTargetLufs: -16 | -14 | -12 | -10; replayGainMode: 'track' | 'album' | 'auto'; replayGainPreGainDb: number; // added to RG gain for tagged files (0…+6 dB) replayGainFallbackDb: number; // gain for untagged files / radio (-6…0 dB) @@ -209,7 +209,7 @@ interface AuthState { setCustomGenreBlacklist: (v: string[]) => void; setReplayGainEnabled: (v: boolean) => void; setNormalizationEngine: (v: NormalizationEngine) => void; - setLoudnessTargetLufs: (v: -16 | -14 | -12) => void; + setLoudnessTargetLufs: (v: -16 | -14 | -12 | -10) => void; setReplayGainMode: (v: 'track' | 'album' | 'auto') => void; setReplayGainPreGainDb: (v: number) => void; setReplayGainFallbackDb: (v: number) => void; @@ -321,7 +321,7 @@ export const useAuthStore = create()( customGenreBlacklist: [], replayGainEnabled: false, normalizationEngine: 'off', - loudnessTargetLufs: -14, + loudnessTargetLufs: -12, replayGainMode: 'auto', replayGainPreGainDb: 0, replayGainFallbackDb: 0,