Add save/delete custom presets for legacy graphic EQ

Save button prompts for a name and stores the current 16-band gains
as a custom preset in localStorage. Custom presets appear in an
optgroup at the bottom of the preset dropdown. Delete button shows
when a custom preset is selected.

https://claude.ai/code/session_01AgSx7SP1dH5KFmpGXCAUvU
This commit is contained in:
tryptz 2026-04-06 03:48:49 +00:00 committed by edideaur
parent ae9446cbd1
commit 79a5e8cf71
2 changed files with 126 additions and 0 deletions

View file

@ -4323,6 +4323,21 @@
<option value="acoustic">Acoustic</option> <option value="acoustic">Acoustic</option>
<option value="podcast">Speech</option> <option value="podcast">Speech</option>
</select> </select>
<button
id="legacy-geq-save-preset-btn"
class="btn-secondary"
title="Save current EQ as a preset"
>
Save
</button>
<button
id="legacy-geq-delete-preset-btn"
class="btn-secondary"
title="Delete selected custom preset"
style="display: none"
>
Delete
</button>
</div> </div>
<div class="graphic-eq-bands" id="legacy-graphic-eq-bands"> <div class="graphic-eq-bands" id="legacy-graphic-eq-bands">
<!-- 16 vertical sliders generated by JS --> <!-- 16 vertical sliders generated by JS -->

View file

@ -1479,6 +1479,117 @@ export async function initializeSettings(scrobbler, player, api, ui) {
}); });
} }
// Legacy EQ Custom Presets (Save / Delete)
const LEGACY_GEQ_CUSTOM_PRESETS_KEY = 'legacy-geq-custom-presets';
const legacyGeqSavePresetBtn = document.getElementById('legacy-geq-save-preset-btn');
const legacyGeqDeletePresetBtn = document.getElementById('legacy-geq-delete-preset-btn');
const getLegacyGeqCustomPresets = () => {
try {
const stored = localStorage.getItem(LEGACY_GEQ_CUSTOM_PRESETS_KEY);
return stored ? JSON.parse(stored) : {};
} catch {
return {};
}
};
const saveLegacyGeqCustomPresets = (presets) => {
localStorage.setItem(LEGACY_GEQ_CUSTOM_PRESETS_KEY, JSON.stringify(presets));
};
/** Rebuild custom preset options in all legacy GEQ preset dropdowns */
const refreshLegacyGeqCustomPresetOptions = () => {
const presets = getLegacyGeqCustomPresets();
geqPresetSelects.forEach((select) => {
// Remove existing custom options
select.querySelectorAll('option[data-custom]').forEach((opt) => opt.remove());
// Remove existing separator
select.querySelectorAll('optgroup[data-custom-group]').forEach((g) => g.remove());
const entries = Object.entries(presets);
if (entries.length === 0) return;
const group = document.createElement('optgroup');
group.label = 'Custom Presets';
group.setAttribute('data-custom-group', '');
entries.forEach(([id, preset]) => {
const opt = document.createElement('option');
opt.value = id;
opt.textContent = preset.name;
opt.setAttribute('data-custom', '');
group.appendChild(opt);
});
select.appendChild(group);
});
};
// Populate custom presets on load
refreshLegacyGeqCustomPresetOptions();
/** Show/hide delete button based on whether a custom preset is selected */
const updateDeleteBtnVisibility = () => {
const val = legacyGeqPresetSelect?.value || '';
const isCustom = val.startsWith('geq_custom_');
if (legacyGeqDeletePresetBtn) {
legacyGeqDeletePresetBtn.style.display = isCustom ? '' : 'none';
}
};
// Update the preset change handler to also handle custom presets
geqPresetSelects.forEach((select) => {
select.addEventListener('change', () => {
updateDeleteBtnVisibility();
const key = select.value;
if (!key) return;
// Check custom presets first
const customPresets = getLegacyGeqCustomPresets();
if (customPresets[key]) {
geqGains = [...customPresets[key].gains];
equalizerSettings.setGraphicEqGains(geqGains);
audioContextManager.setGraphicEqAllGains(geqGains);
geqSyncAllSliders();
geqPresetSelects.forEach((s) => {
if (s !== select) s.value = key;
});
return;
}
});
});
if (legacyGeqSavePresetBtn) {
legacyGeqSavePresetBtn.addEventListener('click', () => {
const name = prompt('Preset name:');
if (!name || !name.trim()) return;
const sanitized = name.trim().substring(0, 50);
const presets = getLegacyGeqCustomPresets();
const id = 'geq_custom_' + Date.now();
presets[id] = {
name: sanitized,
gains: geqGains.map((g) => Math.round(g * 10) / 10),
};
saveLegacyGeqCustomPresets(presets);
refreshLegacyGeqCustomPresetOptions();
geqPresetSelects.forEach((s) => (s.value = id));
updateDeleteBtnVisibility();
});
}
if (legacyGeqDeletePresetBtn) {
legacyGeqDeletePresetBtn.addEventListener('click', () => {
const selected = legacyGeqPresetSelect?.value || '';
if (!selected.startsWith('geq_custom_')) return;
const presets = getLegacyGeqCustomPresets();
const presetName = presets[selected]?.name || selected;
if (!confirm(`Delete preset "${presetName}"?`)) return;
delete presets[selected];
saveLegacyGeqCustomPresets(presets);
refreshLegacyGeqCustomPresetOptions();
geqPresetSelects.forEach((s) => (s.value = ''));
updateDeleteBtnVisibility();
});
}
// ======================================== // ========================================
// Precision AutoEQ - Redesigned Equalizer // Precision AutoEQ - Redesigned Equalizer
// ======================================== // ========================================