diff --git a/server/src/wled_controller/static/js/app.ts b/server/src/wled_controller/static/js/app.ts index 51a3391..dc474ae 100644 --- a/server/src/wled_controller/static/js/app.ts +++ b/server/src/wled_controller/static/js/app.ts @@ -148,7 +148,7 @@ import { showAudioSourceModal, closeAudioSourceModal, saveAudioSource, editAudioSource, cloneAudioSource, deleteAudioSource, testAudioSource, closeTestAudioSourceModal, - refreshAudioDevices, onBandPresetChange, + refreshAudioDevices, } from './features/audio-sources.ts'; // Layer 5: value sources @@ -474,7 +474,6 @@ Object.assign(window, { testAudioSource, closeTestAudioSourceModal, refreshAudioDevices, - onBandPresetChange, // value sources showValueSourceModal, diff --git a/server/src/wled_controller/static/js/features/audio-sources.ts b/server/src/wled_controller/static/js/features/audio-sources.ts index ec114bb..f73d00f 100644 --- a/server/src/wled_controller/static/js/features/audio-sources.ts +++ b/server/src/wled_controller/static/js/features/audio-sources.ts @@ -18,7 +18,9 @@ import { showToast, showConfirm, lockBody, unlockBody } from '../core/ui.ts'; import { Modal } from '../core/modal.ts'; import { ICON_MUSIC, getAudioSourceIcon, ICON_AUDIO_TEMPLATE, ICON_AUDIO_INPUT, ICON_AUDIO_LOOPBACK } from '../core/icons.ts'; import { EntitySelect } from '../core/entity-palette.ts'; +import { IconSelect } from '../core/icon-select.ts'; import { TagInput } from '../core/tag-input.ts'; +import * as P from '../core/icon-paths.ts'; import { loadPictureSources } from './streams.ts'; let _audioSourceTagsInput: TagInput | null = null; @@ -50,11 +52,23 @@ class AudioSourceModal extends Modal { const audioSourceModal = new AudioSourceModal(); -// ── EntitySelect instances for audio source editor ── +// ── EntitySelect / IconSelect instances for audio source editor ── let _asTemplateEntitySelect: EntitySelect | null = null; let _asDeviceEntitySelect: EntitySelect | null = null; let _asParentEntitySelect: EntitySelect | null = null; let _asBandParentEntitySelect: EntitySelect | null = null; +let _asBandIconSelect: IconSelect | null = null; + +const _svg = (d: string): string => `${d}`; + +function _buildBandItems() { + return [ + { value: 'bass', icon: _svg(P.volume2), label: t('audio_source.band.bass'), desc: '20–250 Hz' }, + { value: 'mid', icon: _svg(P.music), label: t('audio_source.band.mid'), desc: '250–4000 Hz' }, + { value: 'treble', icon: _svg(P.zap), label: t('audio_source.band.treble'), desc: '4k–20k Hz' }, + { value: 'custom', icon: _svg(P.slidersHorizontal), label: t('audio_source.band.custom') }, + ]; +} // ── Modal ───────────────────────────────────────────────────── @@ -94,6 +108,7 @@ export async function showAudioSourceModal(sourceType: any, editData?: any) { } else if (editData.source_type === 'band_extract') { _loadBandParentSources(editData.audio_source_id); (document.getElementById('audio-source-band') as HTMLSelectElement).value = editData.band || 'bass'; + _ensureBandIconSelect(); (document.getElementById('audio-source-freq-low') as HTMLInputElement).value = String(editData.freq_low ?? 20); (document.getElementById('audio-source-freq-high') as HTMLInputElement).value = String(editData.freq_high ?? 20000); onBandPresetChange(); @@ -111,6 +126,7 @@ export async function showAudioSourceModal(sourceType: any, editData?: any) { } else if (sourceType === 'band_extract') { _loadBandParentSources(); (document.getElementById('audio-source-band') as HTMLSelectElement).value = 'bass'; + _ensureBandIconSelect(); (document.getElementById('audio-source-freq-low') as HTMLInputElement).value = '20'; (document.getElementById('audio-source-freq-high') as HTMLInputElement).value = '20000'; onBandPresetChange(); @@ -357,6 +373,21 @@ function _loadMultichannelSources(selectedId?: any) { } } +function _ensureBandIconSelect() { + const sel = document.getElementById('audio-source-band') as HTMLSelectElement | null; + if (!sel) return; + if (_asBandIconSelect) { + _asBandIconSelect.updateItems(_buildBandItems()); + return; + } + _asBandIconSelect = new IconSelect({ + target: sel, + items: _buildBandItems(), + columns: 2, + onChange: () => onBandPresetChange(), + }); +} + function _loadBandParentSources(selectedId?: any) { const select = document.getElementById('audio-source-band-parent') as HTMLSelectElement | null; if (!select) return; diff --git a/server/src/wled_controller/templates/modals/audio-source-editor.html b/server/src/wled_controller/templates/modals/audio-source-editor.html index f1aa0f5..60fd296 100644 --- a/server/src/wled_controller/templates/modals/audio-source-editor.html +++ b/server/src/wled_controller/templates/modals/audio-source-editor.html @@ -99,7 +99,7 @@ -