Add CSPT entity, processed CSS source type, reverse filter, and UI improvements

- Add Color Strip Processing Template (CSPT) entity: reusable filter chains
  for 1D LED strip postprocessing (backend, storage, API, frontend CRUD)
- Add "processed" color strip source type that wraps another CSS source and
  applies a CSPT filter chain (dataclass, stream, schema, modal, cards)
- Add Reverse filter for strip LED order reversal
- Add CSPT and processed CSS nodes/edges to visual graph editor
- Add CSPT test preview WS endpoint with input source selection
- Add device settings CSPT template selector (add + edit modals with hints)
- Use icon grids for palette quantization preset selector in filter lists
- Use EntitySelect for template references and test modal source selectors
- Fix filters.css_filter_template.desc missing localization
- Fix icon grid cell height inequality (grid-auto-rows: 1fr)
- Rename "Processed" subtab to "Processing Templates"
- Localize all new strings (en/ru/zh)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-15 02:16:59 +03:00
parent 7e78323c9c
commit 294d704eb0
72 changed files with 2992 additions and 1416 deletions

View File

@@ -169,6 +169,8 @@
"device.led_type.hint": "RGB (3 канала) или RGBW (4 канала с выделенным белым)",
"device.send_latency": "Задержка отправки (мс):",
"device.send_latency.hint": "Имитация сетевой/серийной задержки на кадр в миллисекундах",
"device.css_processing_template": "Шаблон Обработки Полос:",
"device.css_processing_template.hint": "Шаблон обработки по умолчанию, применяемый ко всем цветовым полосам на этом устройстве",
"device.mqtt_topic": "MQTT Топик:",
"device.mqtt_topic.hint": "MQTT топик для публикации пиксельных данных (напр. mqtt://ledgrab/device/name)",
"device.mqtt_topic.placeholder": "mqtt://ledgrab/device/гостиная",
@@ -366,6 +368,7 @@
"streams.description": "Источники определяют конвейер захвата. Сырой источник захватывает экран с помощью шаблона захвата. Обработанный источник применяет постобработку к другому источнику. Назначайте источники устройствам.",
"streams.group.raw": "Захват Экрана",
"streams.group.processed": "Обработанные",
"streams.group.css_processing": "Шаблоны Обработки",
"streams.group.color_strip": "Цветовые Полосы",
"streams.group.audio": "Аудио",
"streams.section.streams": "Источники",
@@ -434,12 +437,16 @@
"filters.color_correction.desc": "Баланс белого и цветовая температура",
"filters.filter_template": "Шаблон фильтров",
"filters.filter_template.desc": "Встроить другой шаблон обработки",
"filters.css_filter_template": "Шаблон Фильтра Полос",
"filters.css_filter_template.desc": "Встроить другой шаблон обработки полос",
"filters.frame_interpolation": "Интерполяция кадров",
"filters.frame_interpolation.desc": "Сглаживание между кадрами",
"filters.noise_gate": "Шумоподавление",
"filters.noise_gate.desc": "Подавление малых изменений цвета ниже порога",
"filters.palette_quantization": "Квантизация палитры",
"filters.palette_quantization.desc": "Сокращение цветов до ограниченной палитры",
"filters.reverse": "Реверс",
"filters.reverse.desc": "Изменить порядок светодиодов на обратный",
"postprocessing.description_label": "Описание (необязательно):",
"postprocessing.description_placeholder": "Опишите этот шаблон...",
"postprocessing.created": "Шаблон успешно создан",
@@ -455,6 +462,21 @@
"postprocessing.test.running": "Тестирование шаблона фильтра...",
"postprocessing.test.error.no_stream": "Пожалуйста, выберите источник",
"postprocessing.test.error.failed": "Тест шаблона фильтра не удался",
"css_processing.title": "Шаблоны Обработки Полос",
"css_processing.add": "Добавить Шаблон Обработки Полос",
"css_processing.edit": "Редактировать Шаблон Обработки Полос",
"css_processing.name": "Имя Шаблона:",
"css_processing.name_placeholder": "Мой Шаблон Обработки Полос",
"css_processing.description_label": "Описание (необязательно):",
"css_processing.description_placeholder": "Опишите этот шаблон...",
"css_processing.created": "Шаблон обработки полос создан",
"css_processing.updated": "Шаблон обработки полос обновлён",
"css_processing.deleted": "Шаблон обработки полос удалён",
"css_processing.delete.confirm": "Вы уверены, что хотите удалить этот шаблон обработки полос?",
"css_processing.error.required": "Заполните все обязательные поля",
"css_processing.error.load": "Ошибка загрузки шаблона обработки полос",
"css_processing.error.delete": "Ошибка удаления шаблона обработки полос",
"css_processing.error.clone_failed": "Не удалось клонировать шаблон обработки полос",
"device.button.stream_selector": "Настройки источника",
"device.stream_settings.title": "Настройки источника",
"device.stream_selector.label": "Источник:",
@@ -976,6 +998,14 @@
"color_strip.candlelight.num_candles.hint": "Сколько независимых источников свечей вдоль ленты. Каждый мерцает по-своему.",
"color_strip.candlelight.speed": "Скорость мерцания:",
"color_strip.candlelight.speed.hint": "Скорость анимации мерцания. Большие значения — более быстрое, беспокойное пламя.",
"color_strip.type.processed": "Обработанный",
"color_strip.type.processed.desc": "Применить шаблон обработки к другому источнику",
"color_strip.type.processed.hint": "Оборачивает существующий источник цветовой полосы и пропускает его вывод через цепочку фильтров.",
"color_strip.processed.input": "Входной источник:",
"color_strip.processed.input.hint": "Источник цветовой полосы, вывод которого будет обработан",
"color_strip.processed.template": "Шаблон обработки:",
"color_strip.processed.template.hint": "Цепочка фильтров для применения к выводу входного источника",
"color_strip.processed.error.no_input": "Выберите входной источник",
"color_strip.composite.layers": "Слои:",
"color_strip.composite.layers.hint": "Наложение нескольких источников. Первый слой — нижний, последний — верхний. Каждый слой может иметь свой режим смешивания и прозрачность.",
"color_strip.composite.add_layer": "+ Добавить слой",
@@ -992,6 +1022,7 @@
"color_strip.composite.opacity": "Непрозрачность",
"color_strip.composite.brightness": "Яркость",
"color_strip.composite.brightness.none": "— Нет —",
"color_strip.composite.processing": "Обработка",
"color_strip.composite.enabled": "Включён",
"color_strip.composite.error.min_layers": "Необходим хотя бы 1 слой",
"color_strip.composite.error.no_source": "Для каждого слоя должен быть выбран источник",
@@ -1131,6 +1162,7 @@
"streams.group.value": "Источники значений",
"streams.group.sync": "Часы синхронизации",
"tree.group.picture": "Изображения",
"tree.group.strip": "Цветовые Полосы",
"tree.group.utility": "Утилиты",
"value_source.group.title": "Источники значений",
"value_source.select_type": "Выберите тип источника значений",