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) }));