diff --git a/server/src/wled_controller/static/js/features/streams.js b/server/src/wled_controller/static/js/features/streams.js
index f52a4ab..f33949f 100644
--- a/server/src/wled_controller/static/js/features/streams.js
+++ b/server/src/wled_controller/static/js/features/streams.js
@@ -50,6 +50,7 @@ import {
import { wrapCard } from '../core/card-colors.js';
import { IconSelect } from '../core/icon-select.js';
import { EntitySelect } from '../core/entity-palette.js';
+import * as P from '../core/icon-paths.js';
// ── Card section instances ──
const csRawStreams = new CardSection('raw-streams', { titleKey: 'streams.section.streams', gridClass: 'templates-grid', addCardOnclick: "showAddStreamModal('raw')", keyAttr: 'data-stream-id' });
@@ -2005,12 +2006,49 @@ function _getFilterName(filterId) {
return translated;
}
+let _filterIconSelect = null;
+
+const _FILTER_ICONS = {
+ brightness: P.sunDim,
+ saturation: P.palette,
+ gamma: P.sun,
+ downscaler: P.monitor,
+ pixelate: P.layoutDashboard,
+ auto_crop: P.target,
+ flip: P.rotateCw,
+ color_correction: P.palette,
+ filter_template: P.fileText,
+ frame_interpolation: P.fastForward,
+ noise_gate: P.volume2,
+ palette_quantization: P.sparkles,
+};
+
function _populateFilterSelect() {
const select = document.getElementById('pp-add-filter-select');
select.innerHTML = ``;
+ const items = [
+ { value: '', icon: ``, label: t('filters.select_type') },
+ ];
for (const f of _availableFilters) {
const name = _getFilterName(f.filter_id);
select.innerHTML += ``;
+ const pathData = _FILTER_ICONS[f.filter_id] || P.wrench;
+ items.push({
+ value: f.filter_id,
+ icon: ``,
+ label: name,
+ desc: t(`filters.${f.filter_id}.desc`),
+ });
+ }
+ if (_filterIconSelect) {
+ _filterIconSelect.updateItems(items);
+ } else if (items.length > 0) {
+ _filterIconSelect = new IconSelect({
+ target: select,
+ items,
+ columns: 2,
+ onChange: () => addFilterFromSelect(),
+ });
}
}
@@ -2285,6 +2323,7 @@ export function addFilterFromSelect() {
_modalFilters.push({ filter_id: filterId, options, _expanded: true });
select.value = '';
+ if (_filterIconSelect) _filterIconSelect.setValue('');
renderModalFilterList();
_autoGeneratePPTemplateName();
}
diff --git a/server/src/wled_controller/static/locales/en.json b/server/src/wled_controller/static/locales/en.json
index 9016bc5..3394a04 100644
--- a/server/src/wled_controller/static/locales/en.json
+++ b/server/src/wled_controller/static/locales/en.json
@@ -382,17 +382,29 @@
"filters.drag_to_reorder": "Drag to reorder",
"filters.empty": "No filters added. Use the selector below to add filters.",
"filters.brightness": "Brightness",
+ "filters.brightness.desc": "Adjust overall image brightness",
"filters.saturation": "Saturation",
+ "filters.saturation.desc": "Boost or reduce color intensity",
"filters.gamma": "Gamma",
+ "filters.gamma.desc": "Non-linear brightness curve correction",
"filters.downscaler": "Downscaler",
+ "filters.downscaler.desc": "Reduce resolution for faster processing",
"filters.pixelate": "Pixelate",
+ "filters.pixelate.desc": "Mosaic-style block averaging",
"filters.auto_crop": "Auto Crop",
+ "filters.auto_crop.desc": "Remove black bars from letterboxed content",
"filters.flip": "Flip",
+ "filters.flip.desc": "Mirror image horizontally or vertically",
"filters.color_correction": "Color Correction",
+ "filters.color_correction.desc": "White balance and color temperature",
"filters.filter_template": "Filter Template",
+ "filters.filter_template.desc": "Embed another processing template",
"filters.frame_interpolation": "Frame Interpolation",
+ "filters.frame_interpolation.desc": "Blend between frames for smoother output",
"filters.noise_gate": "Noise Gate",
+ "filters.noise_gate.desc": "Suppress small color changes below threshold",
"filters.palette_quantization": "Palette Quantization",
+ "filters.palette_quantization.desc": "Reduce colors to a limited palette",
"postprocessing.description_label": "Description (optional):",
"postprocessing.description_placeholder": "Describe this template...",
"postprocessing.created": "Template created successfully",
diff --git a/server/src/wled_controller/static/locales/ru.json b/server/src/wled_controller/static/locales/ru.json
index ddc9dd4..4c1fb95 100644
--- a/server/src/wled_controller/static/locales/ru.json
+++ b/server/src/wled_controller/static/locales/ru.json
@@ -382,17 +382,29 @@
"filters.drag_to_reorder": "Перетащите для изменения порядка",
"filters.empty": "Фильтры не добавлены. Используйте селектор ниже для добавления.",
"filters.brightness": "Яркость",
+ "filters.brightness.desc": "Регулировка общей яркости изображения",
"filters.saturation": "Насыщенность",
+ "filters.saturation.desc": "Усиление или снижение интенсивности цвета",
"filters.gamma": "Гамма",
+ "filters.gamma.desc": "Нелинейная коррекция кривой яркости",
"filters.downscaler": "Уменьшение",
+ "filters.downscaler.desc": "Снижение разрешения для быстрой обработки",
"filters.pixelate": "Пикселизация",
+ "filters.pixelate.desc": "Мозаичное усреднение блоков",
"filters.auto_crop": "Авто Обрезка",
+ "filters.auto_crop.desc": "Удаление чёрных полос из леттербокса",
"filters.flip": "Отражение",
+ "filters.flip.desc": "Зеркальное отражение по горизонтали или вертикали",
"filters.color_correction": "Цветокоррекция",
+ "filters.color_correction.desc": "Баланс белого и цветовая температура",
"filters.filter_template": "Шаблон фильтров",
+ "filters.filter_template.desc": "Встроить другой шаблон обработки",
"filters.frame_interpolation": "Интерполяция кадров",
+ "filters.frame_interpolation.desc": "Сглаживание между кадрами",
"filters.noise_gate": "Шумоподавление",
+ "filters.noise_gate.desc": "Подавление малых изменений цвета ниже порога",
"filters.palette_quantization": "Квантизация палитры",
+ "filters.palette_quantization.desc": "Сокращение цветов до ограниченной палитры",
"postprocessing.description_label": "Описание (необязательно):",
"postprocessing.description_placeholder": "Опишите этот шаблон...",
"postprocessing.created": "Шаблон успешно создан",
diff --git a/server/src/wled_controller/static/locales/zh.json b/server/src/wled_controller/static/locales/zh.json
index ab68321..e1f6317 100644
--- a/server/src/wled_controller/static/locales/zh.json
+++ b/server/src/wled_controller/static/locales/zh.json
@@ -382,17 +382,29 @@
"filters.drag_to_reorder": "拖动以重新排序",
"filters.empty": "尚未添加滤镜。使用下方选择器添加滤镜。",
"filters.brightness": "亮度",
+ "filters.brightness.desc": "调整整体图像亮度",
"filters.saturation": "饱和度",
+ "filters.saturation.desc": "增强或降低色彩强度",
"filters.gamma": "伽马",
+ "filters.gamma.desc": "非线性亮度曲线校正",
"filters.downscaler": "缩小",
+ "filters.downscaler.desc": "降低分辨率以加快处理",
"filters.pixelate": "像素化",
+ "filters.pixelate.desc": "马赛克式块平均",
"filters.auto_crop": "自动裁剪",
+ "filters.auto_crop.desc": "移除信箱式内容的黑边",
"filters.flip": "翻转",
+ "filters.flip.desc": "水平或垂直镜像翻转",
"filters.color_correction": "色彩校正",
+ "filters.color_correction.desc": "白平衡和色温调整",
"filters.filter_template": "滤镜模板",
+ "filters.filter_template.desc": "嵌入另一个处理模板",
"filters.frame_interpolation": "帧插值",
+ "filters.frame_interpolation.desc": "帧间混合以获得更平滑的输出",
"filters.noise_gate": "噪声门",
+ "filters.noise_gate.desc": "抑制低于阈值的细微色彩变化",
"filters.palette_quantization": "调色板量化",
+ "filters.palette_quantization.desc": "将颜色减少到有限调色板",
"postprocessing.description_label": "描述(可选):",
"postprocessing.description_placeholder": "描述此模板...",
"postprocessing.created": "模板创建成功",
diff --git a/server/src/wled_controller/static/sw.js b/server/src/wled_controller/static/sw.js
index acb4f8b..2604068 100644
--- a/server/src/wled_controller/static/sw.js
+++ b/server/src/wled_controller/static/sw.js
@@ -7,7 +7,7 @@
* - Navigation: network-first with offline fallback
*/
-const CACHE_NAME = 'ledgrab-v19';
+const CACHE_NAME = 'ledgrab-v20';
// Only pre-cache static assets (no auth required).
// Do NOT pre-cache '/' — it requires API key auth and would cache an error page.