diff --git a/server/src/wled_controller/static/js/features/kc-targets.js b/server/src/wled_controller/static/js/features/kc-targets.js
index 5a13349..c35d9bd 100644
--- a/server/src/wled_controller/static/js/features/kc-targets.js
+++ b/server/src/wled_controller/static/js/features/kc-targets.js
@@ -14,6 +14,7 @@ import { API_BASE, getHeaders, fetchWithAuth, escapeHtml } from '../core/api.js'
import { t } from '../core/i18n.js';
import { lockBody, showToast, showConfirm, formatUptime } from '../core/ui.js';
import { Modal } from '../core/modal.js';
+import { getValueSourceIcon } from './value-sources.js';
class KCEditorModal extends Modal {
constructor() {
@@ -81,7 +82,7 @@ export function createKCTargetCard(target, sourceMap, patternTemplateMap, valueS
📄 ${escapeHtml(patternName)}
▭ ${rectCount} rect${rectCount !== 1 ? 's' : ''}
⚡ ${kcSettings.fps ?? 10}
- ${bvs ? `🔆 ${escapeHtml(bvs.name)}` : ''}
+ ${bvs ? `${getValueSourceIcon(bvs.source_type)} ${escapeHtml(bvs.name)}` : ''}
1) sel.remove(1);
_cachedValueSources.forEach(vs => {
+ const icon = getValueSourceIcon(vs.source_type);
const opt = document.createElement('option');
opt.value = vs.id;
- opt.textContent = `🔢 ${vs.name}`;
+ opt.textContent = `${icon} ${vs.name}`;
sel.appendChild(opt);
});
sel.value = selectedId || '';
diff --git a/server/src/wled_controller/static/js/features/targets.js b/server/src/wled_controller/static/js/features/targets.js
index 2924061..d7ca6ed 100644
--- a/server/src/wled_controller/static/js/features/targets.js
+++ b/server/src/wled_controller/static/js/features/targets.js
@@ -17,6 +17,7 @@ import { Modal } from '../core/modal.js';
import { createDeviceCard, attachDeviceListeners, fetchDeviceBrightness, _computeMaxFps } from './devices.js';
import { createKCTargetCard, connectKCWebSocket, disconnectKCWebSocket } from './kc-targets.js';
import { createColorStripCard } from './color-strips.js';
+import { getValueSourceIcon } from './value-sources.js';
import { CardSection } from '../core/card-sections.js';
// createPatternTemplateCard is imported via window.* to avoid circular deps
@@ -184,7 +185,8 @@ function _populateBrightnessVsDropdown(selectedId = '') {
const select = document.getElementById('target-editor-brightness-vs');
let html = ``;
_cachedValueSources.forEach(vs => {
- html += ``;
+ const icon = getValueSourceIcon(vs.source_type);
+ html += ``;
});
select.innerHTML = html;
}
@@ -677,7 +679,7 @@ export function createTargetCard(target, deviceMap, colorStripSourceMap, valueSo
💡 ${escapeHtml(deviceName)}
⚡ ${target.fps || 30}
🎞️ ${cssSummary}
- ${bvs ? `🔆 ${escapeHtml(bvs.name)}` : ''}
+ ${bvs ? `${getValueSourceIcon(bvs.source_type)} ${escapeHtml(bvs.name)}` : ''}
${isProcessing ? `
diff --git a/server/src/wled_controller/static/js/features/value-sources.js b/server/src/wled_controller/static/js/features/value-sources.js
index 6e63fd6..907671a 100644
--- a/server/src/wled_controller/static/js/features/value-sources.js
+++ b/server/src/wled_controller/static/js/features/value-sources.js
@@ -255,9 +255,15 @@ export async function deleteValueSource(sourceId) {
// ── Card rendering (used by streams.js) ───────────────────────
+const _vsTypeIcons = { static: '📊', animated: '🔄', audio: '🎵', adaptive_time: '🕐', adaptive_scene: '🌤️' };
+
+/** Return the emoji icon for a given value source type. */
+export function getValueSourceIcon(sourceType) {
+ return _vsTypeIcons[sourceType] || '🎚️';
+}
+
export function createValueSourceCard(src) {
- const typeIcons = { static: '📊', animated: '🔄', audio: '🎵', adaptive_time: '🕐', adaptive_scene: '🌤️' };
- const icon = typeIcons[src.source_type] || '🎚️';
+ const icon = getValueSourceIcon(src.source_type);
let propsHtml = '';
if (src.source_type === 'static') {