diff --git a/server/src/wled_controller/static/js/features/color-strips.js b/server/src/wled_controller/static/js/features/color-strips.js index ecef2d3..7f68583 100644 --- a/server/src/wled_controller/static/js/features/color-strips.js +++ b/server/src/wled_controller/static/js/features/color-strips.js @@ -575,7 +575,7 @@ function _resetAudioState() { /* ── Card ─────────────────────────────────────────────────────── */ -export function createColorStripCard(source, pictureSourceMap) { +export function createColorStripCard(source, pictureSourceMap, audioSourceMap) { const isStatic = source.source_type === 'static'; const isGradient = source.source_type === 'gradient'; const isColorCycle = source.source_type === 'color_cycle'; @@ -665,7 +665,12 @@ export function createColorStripCard(source, pictureSourceMap) { 🎵 ${escapeHtml(vizLabel)} ${audioPaletteLabel ? `🎨 ${escapeHtml(audioPaletteLabel)}` : ''} 📶 ${sensitivityVal} - ${source.audio_source_id ? `🔊` : ''} + ${source.audio_source_id ? (() => { + const as = audioSourceMap && audioSourceMap[source.audio_source_id]; + const asName = as ? as.name : source.audio_source_id; + const asSection = as && as.source_type === 'mono' ? 'audio-mono' : 'audio-multi'; + return `🔊 ${escapeHtml(asName)}`; + })() : ''} ${source.mirror ? `🪞` : ''} `; } else if (isApiInput) { @@ -678,14 +683,18 @@ export function createColorStripCard(source, pictureSourceMap) { ⏱️ ${timeoutVal}s `; } else { - const srcName = (pictureSourceMap && pictureSourceMap[source.picture_source_id]) - ? pictureSourceMap[source.picture_source_id].name - : source.picture_source_id || '—'; + const ps = pictureSourceMap && pictureSourceMap[source.picture_source_id]; + const srcName = ps ? ps.name : source.picture_source_id || '—'; const cal = source.calibration || {}; const calLeds = (cal.leds_top || 0) + (cal.leds_right || 0) + (cal.leds_bottom || 0) + (cal.leds_left || 0); const ledCount = (source.led_count > 0) ? source.led_count : calLeds; + let psSubTab = 'raw', psSection = 'raw-streams'; + if (ps) { + if (ps.stream_type === 'static_image') { psSubTab = 'static_image'; psSection = 'static-streams'; } + else if (ps.stream_type === 'processed') { psSubTab = 'processed'; psSection = 'proc-streams'; } + } propsHtml = ` - 📺 ${escapeHtml(srcName)} + 📺 ${escapeHtml(srcName)} ${ledCount ? `💡 ${ledCount}` : ''} `; } diff --git a/server/src/wled_controller/static/js/features/targets.js b/server/src/wled_controller/static/js/features/targets.js index b4b069e..f20b55a 100644 --- a/server/src/wled_controller/static/js/features/targets.js +++ b/server/src/wled_controller/static/js/features/targets.js @@ -430,13 +430,14 @@ export async function loadTargetsTab() { try { // Fetch devices, targets, CSS sources, picture sources, pattern templates, and value sources in parallel - const [devicesResp, targetsResp, cssResp, psResp, patResp, vsResp] = await Promise.all([ + const [devicesResp, targetsResp, cssResp, psResp, patResp, vsResp, asResp] = await Promise.all([ fetchWithAuth('/devices'), fetchWithAuth('/picture-targets'), fetchWithAuth('/color-strip-sources').catch(() => null), fetchWithAuth('/picture-sources').catch(() => null), fetchWithAuth('/pattern-templates').catch(() => null), fetchWithAuth('/value-sources').catch(() => null), + fetchWithAuth('/audio-sources').catch(() => null), ]); const devicesData = await devicesResp.json(); @@ -471,6 +472,12 @@ export async function loadTargetsTab() { (vsData.sources || []).forEach(s => { valueSourceMap[s.id] = s; }); } + let audioSourceMap = {}; + if (asResp && asResp.ok) { + const asData = await asResp.json(); + (asData.sources || []).forEach(s => { audioSourceMap[s.id] = s; }); + } + // Fetch all device states, target states, and target metrics in batch const [batchDevStatesResp, batchTgtStatesResp, batchTgtMetricsResp] = await Promise.all([ fetchWithAuth('/devices/batch/states'), @@ -530,7 +537,7 @@ export async function loadTargetsTab() { // Build items arrays for each section const deviceItems = ledDevices.map(d => ({ key: d.id, html: createDeviceCard(d) })); - const cssItems = Object.values(colorStripSourceMap).map(s => ({ key: s.id, html: createColorStripCard(s, pictureSourceMap) })); + const cssItems = Object.values(colorStripSourceMap).map(s => ({ key: s.id, html: createColorStripCard(s, pictureSourceMap, audioSourceMap) })); const ledTargetItems = ledTargets.map(t => ({ key: t.id, html: createTargetCard(t, deviceMap, colorStripSourceMap, valueSourceMap) })); const kcTargetItems = kcTargets.map(t => ({ key: t.id, html: createKCTargetCard(t, pictureSourceMap, patternTemplateMap, valueSourceMap) })); const patternItems = patternTemplates.map(pt => ({ key: pt.id, html: createPatternTemplateCard(pt) }));