From be91e74c6ee644641a8b86a4bed52b78a7b658c0 Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Mon, 9 Mar 2026 00:45:43 +0300 Subject: [PATCH] Add visual IconSelect grid for filter type picker in PP template editor Replace plain filter type dropdown with icon grid showing each filter with its icon and description. Selecting a filter immediately adds it to the template (no separate "+" click needed). Co-Authored-By: Claude Opus 4.6 --- .../static/js/features/streams.js | 39 +++++++++++++++++++ .../wled_controller/static/locales/en.json | 12 ++++++ .../wled_controller/static/locales/ru.json | 12 ++++++ .../wled_controller/static/locales/zh.json | 12 ++++++ server/src/wled_controller/static/sw.js | 2 +- 5 files changed, 76 insertions(+), 1 deletion(-) 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: `${P.wrench}`, 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: `${pathData}`, + 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.