Comprehensive WebUI review: 41 UX/feature/CSS improvements
Safety & Correctness: - Add confirmation dialogs to Stop All, turnOffDevice - i18n confirm dialog (title, yes, no buttons) - Fix duplicate tutorial-overlay ID - Define missing CSS variables (--radius, --text-primary, --hover-bg, --input-bg) - Fix toast z-index conflict with confirm dialog (2500 → 3000) UX Consistency: - Add backdrop-close to test modals - Add device clone feature (only entity without it) - Add sync clocks to command palette - Replace 20+ hardcoded accent colors with CSS vars/color-mix() - Remove dead .badge duplicate from components.css - Make calibration elements keyboard-accessible (div → button) - Add aria-labels to color picker swatches - Fix pattern canvas mobile horizontal scroll - Fix graph editor mobile bottom clipping Polish: - Add empty-state messages to all CardSection instances - Convert 21 px font-sizes to rem - Add scroll-behavior: smooth with reduced-motion override - Add @media print styles - Add :focus-visible to 4 missing interactive elements - Fix settings modal close label (Cancel → Close) - Fix api-key submit button i18n New Features: - Command palette actions: start/stop targets, activate scenes, enable/disable - Bulk start/stop API endpoints (POST /output-targets/bulk/start|stop) - OS notification history viewer modal - Scene "used by" automation reference count on cards - Clock elapsed time display on Streams tab cards - Device "last seen" relative timestamp on cards - Audio device refresh button in edit modal - Composite layer drag-to-reorder - MQTT settings panel (broker config with JSON persistence) - WebSocket log viewer with level filtering and ring buffer - Runtime log-level adjustment (GET/PUT endpoints + settings UI) - Animated value source waveform canvas preview - Gradient custom preset save/delete (localStorage) - API key read-only display in settings - Backup metadata (file size, auto/manual badges) - Server restart button with confirm + overlay - Partial config export/import per entity type - Progressive disclosure in target editor (Advanced section) CSS Architecture: - Define radius scale tokens (--radius-sm/md/lg/pill) - Scope .cs-filter selectors to remove 7 !important overrides - Consolidate duplicate toggle switch (filter-list → settings-toggle) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
"auth.prompt_update": "Current API key is set. Enter new key to update or leave blank to remove:",
|
||||
"auth.prompt_enter": "Enter your API key:",
|
||||
"auth.toggle_password": "Toggle password visibility",
|
||||
"api_key.login": "Login",
|
||||
"displays.title": "Available Displays",
|
||||
"displays.layout": "Displays",
|
||||
"displays.information": "Display Information",
|
||||
@@ -291,6 +292,12 @@
|
||||
"device.health.offline": "Offline",
|
||||
"device.health.streaming_unreachable": "Unreachable during streaming",
|
||||
"device.health.checking": "Checking...",
|
||||
"device.last_seen.label": "Last seen",
|
||||
"device.last_seen.just_now": "just now",
|
||||
"device.last_seen.seconds": "%ds ago",
|
||||
"device.last_seen.minutes": "%dm ago",
|
||||
"device.last_seen.hours": "%dh ago",
|
||||
"device.last_seen.days": "%dd ago",
|
||||
"device.tutorial.start": "Start tutorial",
|
||||
"device.tip.metadata": "Device info (LED count, type, color channels) is auto-detected from the device",
|
||||
"device.tip.brightness": "Slide to adjust device brightness",
|
||||
@@ -405,6 +412,8 @@
|
||||
"confirm.title": "Confirm Action",
|
||||
"confirm.yes": "Yes",
|
||||
"confirm.no": "No",
|
||||
"confirm.stop_all": "Stop all running targets?",
|
||||
"confirm.turn_off_device": "Turn off this device?",
|
||||
"common.loading": "Loading...",
|
||||
"common.delete": "Delete",
|
||||
"common.edit": "Edit",
|
||||
@@ -584,6 +593,7 @@
|
||||
"targets.section.color_strips": "Color Strip Sources",
|
||||
"targets.section.targets": "Targets",
|
||||
"targets.section.specific_settings": "Specific Settings",
|
||||
"targets.section.advanced": "Advanced",
|
||||
"targets.add": "Add Target",
|
||||
"targets.edit": "Edit Target",
|
||||
"targets.loading": "Loading targets...",
|
||||
@@ -953,6 +963,11 @@
|
||||
"color_strip.gradient.preset.cool": "Cool",
|
||||
"color_strip.gradient.preset.neon": "Neon",
|
||||
"color_strip.gradient.preset.pastel": "Pastel",
|
||||
"color_strip.gradient.preset.save_button": "Save as preset…",
|
||||
"color_strip.gradient.preset.save_prompt": "Enter a name for this preset:",
|
||||
"color_strip.gradient.preset.saved": "Preset saved",
|
||||
"color_strip.gradient.preset.deleted": "Preset deleted",
|
||||
"color_strip.gradient.preset.apply": "Apply",
|
||||
"color_strip.animation": "Animation",
|
||||
"color_strip.animation.type": "Effect:",
|
||||
"color_strip.animation.type.hint": "Animation effect to apply.",
|
||||
@@ -1043,6 +1058,15 @@
|
||||
"color_strip.notification.test.ok": "Notification sent",
|
||||
"color_strip.notification.test.no_streams": "No running streams for this source",
|
||||
"color_strip.notification.test.error": "Failed to send notification",
|
||||
"color_strip.notification.history.title": "Notification History",
|
||||
"color_strip.notification.history.hint": "Recent OS notifications captured by the listener (newest first). Up to 50 entries.",
|
||||
"color_strip.notification.history.empty": "No notifications captured yet",
|
||||
"color_strip.notification.history.unavailable": "OS notification listener is not available on this platform",
|
||||
"color_strip.notification.history.error": "Failed to load notification history",
|
||||
"color_strip.notification.history.refresh": "Refresh",
|
||||
"color_strip.notification.history.unknown_app": "Unknown app",
|
||||
"color_strip.notification.history.fired": "Streams triggered",
|
||||
"color_strip.notification.history.filtered": "Streams filtered",
|
||||
"color_strip.test.title": "Test Preview",
|
||||
"color_strip.test.connecting": "Connecting...",
|
||||
"color_strip.test.error": "Failed to connect to preview stream",
|
||||
@@ -1188,6 +1212,7 @@
|
||||
"audio_source.type.mono": "Mono",
|
||||
"audio_source.device": "Audio Device:",
|
||||
"audio_source.device.hint": "Audio input source. Loopback devices capture system audio output; input devices capture microphone or line-in.",
|
||||
"audio_source.refresh_devices": "Refresh devices",
|
||||
"audio_source.parent": "Parent Source:",
|
||||
"audio_source.parent.hint": "Multichannel source to extract a channel from",
|
||||
"audio_source.channel": "Channel:",
|
||||
@@ -1375,6 +1400,13 @@
|
||||
"search.group.value": "Value Sources",
|
||||
"search.group.scenes": "Scene Presets",
|
||||
"search.group.cspt": "Strip Processing Templates",
|
||||
"search.group.sync_clocks": "Sync Clocks",
|
||||
"search.group.actions": "Actions",
|
||||
"search.action.start": "Start",
|
||||
"search.action.stop": "Stop",
|
||||
"search.action.activate": "Activate",
|
||||
"search.action.enable": "Enable",
|
||||
"search.action.disable": "Disable",
|
||||
"settings.backup.label": "Backup Configuration",
|
||||
"settings.backup.hint": "Download all configuration (devices, targets, streams, templates, automations) as a single JSON file.",
|
||||
"settings.backup.button": "Download Backup",
|
||||
@@ -1388,7 +1420,15 @@
|
||||
"settings.restore.error": "Restore failed",
|
||||
"settings.restore.restarting": "Server is restarting...",
|
||||
"settings.restore.restart_timeout": "Server did not respond. Please refresh the page manually.",
|
||||
"settings.restart_server": "Restart Server",
|
||||
"settings.restart_confirm": "Restart the server? Active targets will be stopped.",
|
||||
"settings.restarting": "Restarting server...",
|
||||
"settings.button.close": "Close",
|
||||
"settings.log_level.label": "Log Level",
|
||||
"settings.log_level.hint": "Change the server log verbosity at runtime. DEBUG shows the most detail; CRITICAL shows only fatal errors.",
|
||||
"settings.log_level.save": "Apply",
|
||||
"settings.log_level.saved": "Log level changed",
|
||||
"settings.log_level.save_error": "Failed to change log level",
|
||||
"settings.auto_backup.label": "Auto-Backup",
|
||||
"settings.auto_backup.hint": "Automatically create periodic backups of all configuration. Old backups are pruned when the maximum count is reached.",
|
||||
"settings.auto_backup.enable": "Enable auto-backup",
|
||||
@@ -1407,6 +1447,32 @@
|
||||
"settings.saved_backups.delete": "Delete",
|
||||
"settings.saved_backups.delete_confirm": "Delete this backup file?",
|
||||
"settings.saved_backups.delete_error": "Failed to delete backup",
|
||||
"settings.saved_backups.type.auto": "auto",
|
||||
"settings.saved_backups.type.manual": "manual",
|
||||
"settings.mqtt.label": "MQTT",
|
||||
"settings.mqtt.hint": "Configure MQTT broker connection for automation conditions and triggers.",
|
||||
"settings.mqtt.enabled": "Enable MQTT",
|
||||
"settings.mqtt.host_label": "Broker Host",
|
||||
"settings.mqtt.port_label": "Port",
|
||||
"settings.mqtt.username_label": "Username",
|
||||
"settings.mqtt.password_label": "Password",
|
||||
"settings.mqtt.password_set_hint": "Password is set — leave blank to keep",
|
||||
"settings.mqtt.client_id_label": "Client ID",
|
||||
"settings.mqtt.base_topic_label": "Base Topic",
|
||||
"settings.mqtt.save": "Save MQTT Settings",
|
||||
"settings.mqtt.saved": "MQTT settings saved",
|
||||
"settings.mqtt.save_error": "Failed to save MQTT settings",
|
||||
"settings.mqtt.error_host_required": "Broker host is required",
|
||||
"settings.logs.label": "Server Logs",
|
||||
"settings.logs.hint": "Stream live server log output. Use the filter to show only relevant log levels.",
|
||||
"settings.logs.connect": "Connect",
|
||||
"settings.logs.disconnect": "Disconnect",
|
||||
"settings.logs.clear": "Clear",
|
||||
"settings.logs.error": "Log viewer connection failed",
|
||||
"settings.logs.filter.all": "All levels",
|
||||
"settings.logs.filter.info": "Info+",
|
||||
"settings.logs.filter.warning": "Warning+",
|
||||
"settings.logs.filter.error": "Error only",
|
||||
"device.error.power_off_failed": "Failed to turn off device",
|
||||
"device.removed": "Device removed",
|
||||
"device.error.remove_failed": "Failed to remove device",
|
||||
@@ -1415,6 +1481,7 @@
|
||||
"device.error.required": "Please fill in all fields correctly",
|
||||
"device.error.update": "Failed to update device",
|
||||
"device.error.save": "Failed to save settings",
|
||||
"device.error.clone_failed": "Failed to clone device",
|
||||
"device_discovery.error.fill_all_fields": "Please fill in all fields",
|
||||
"device_discovery.added": "Device added successfully",
|
||||
"device_discovery.error.add_failed": "Failed to add device",
|
||||
@@ -1506,6 +1573,7 @@
|
||||
"sync_clock.resumed": "Clock resumed",
|
||||
"sync_clock.reset_done": "Clock reset to zero",
|
||||
"sync_clock.delete.confirm": "Delete this sync clock? Linked sources will lose synchronization and run at default speed.",
|
||||
"sync_clock.elapsed": "Elapsed time",
|
||||
"color_strip.clock": "Sync Clock:",
|
||||
"color_strip.clock.hint": "Link to a sync clock to synchronize animation timing across sources. Speed is controlled on the clock.",
|
||||
"graph.title": "Graph",
|
||||
@@ -1570,5 +1638,50 @@
|
||||
"graph.help.right_click_desc": "Detach connection",
|
||||
"automation.enabled": "Automation enabled",
|
||||
"automation.disabled": "Automation disabled",
|
||||
"scene_preset.activated": "Preset activated"
|
||||
"scene_preset.activated": "Preset activated",
|
||||
"scene_preset.used_by": "Used by %d automation(s)",
|
||||
"settings.api_keys.label": "API Keys",
|
||||
"settings.api_keys.hint": "API keys are defined in the server config file (config.yaml). Edit the file and restart the server to apply changes.",
|
||||
"settings.api_keys.empty": "No API keys configured",
|
||||
"settings.api_keys.load_error": "Failed to load API keys",
|
||||
"settings.partial.label": "Partial Export / Import",
|
||||
"settings.partial.hint": "Export or import a single entity type. Import replaces or merges existing data and restarts the server.",
|
||||
"settings.partial.store.devices": "Devices",
|
||||
"settings.partial.store.output_targets": "LED Targets",
|
||||
"settings.partial.store.color_strip_sources": "Color Strips",
|
||||
"settings.partial.store.picture_sources": "Picture Sources",
|
||||
"settings.partial.store.audio_sources": "Audio Sources",
|
||||
"settings.partial.store.audio_templates": "Audio Templates",
|
||||
"settings.partial.store.capture_templates": "Capture Templates",
|
||||
"settings.partial.store.postprocessing_templates": "Post-processing Templates",
|
||||
"settings.partial.store.color_strip_processing_templates": "CSS Processing Templates",
|
||||
"settings.partial.store.pattern_templates": "Pattern Templates",
|
||||
"settings.partial.store.value_sources": "Value Sources",
|
||||
"settings.partial.store.sync_clocks": "Sync Clocks",
|
||||
"settings.partial.store.automations": "Automations",
|
||||
"settings.partial.store.scene_presets": "Scene Presets",
|
||||
"settings.partial.export_button": "Export",
|
||||
"settings.partial.import_button": "Import from File",
|
||||
"settings.partial.merge_label": "Merge (add/overwrite, keep existing)",
|
||||
"settings.partial.export_success": "Exported successfully",
|
||||
"settings.partial.export_error": "Export failed",
|
||||
"settings.partial.import_success": "Imported successfully",
|
||||
"settings.partial.import_error": "Import failed",
|
||||
"settings.partial.import_confirm_replace": "This will REPLACE all {store} data and restart the server. Continue?",
|
||||
"settings.partial.import_confirm_merge": "This will MERGE into existing {store} data and restart the server. Continue?",
|
||||
"section.empty.devices": "No devices yet. Click + to add one.",
|
||||
"section.empty.targets": "No LED targets yet. Click + to add one.",
|
||||
"section.empty.kc_targets": "No key color targets yet. Click + to add one.",
|
||||
"section.empty.pattern_templates": "No pattern templates yet. Click + to add one.",
|
||||
"section.empty.picture_sources": "No sources yet. Click + to add one.",
|
||||
"section.empty.capture_templates": "No capture templates yet. Click + to add one.",
|
||||
"section.empty.pp_templates": "No post-processing templates yet. Click + to add one.",
|
||||
"section.empty.audio_sources": "No audio sources yet. Click + to add one.",
|
||||
"section.empty.audio_templates": "No audio templates yet. Click + to add one.",
|
||||
"section.empty.color_strips": "No color strips yet. Click + to add one.",
|
||||
"section.empty.value_sources": "No value sources yet. Click + to add one.",
|
||||
"section.empty.sync_clocks": "No sync clocks yet. Click + to add one.",
|
||||
"section.empty.cspt": "No CSS processing templates yet. Click + to add one.",
|
||||
"section.empty.automations": "No automations yet. Click + to add one.",
|
||||
"section.empty.scenes": "No scene presets yet. Click + to add one."
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"auth.toggle_password": "Показать/скрыть пароль",
|
||||
"auth.prompt_enter": "Enter your API key:",
|
||||
"auth.prompt_update": "Current API key is set. Enter new key to update or leave blank to remove:",
|
||||
"api_key.login": "Войти",
|
||||
"displays.title": "Доступные Дисплеи",
|
||||
"displays.layout": "Дисплеи",
|
||||
"displays.information": "Информация о Дисплеях",
|
||||
@@ -291,6 +292,12 @@
|
||||
"device.health.offline": "Недоступен",
|
||||
"device.health.streaming_unreachable": "Недоступен во время стриминга",
|
||||
"device.health.checking": "Проверка...",
|
||||
"device.last_seen.label": "Последний раз",
|
||||
"device.last_seen.just_now": "только что",
|
||||
"device.last_seen.seconds": "%d с назад",
|
||||
"device.last_seen.minutes": "%d мин назад",
|
||||
"device.last_seen.hours": "%d ч назад",
|
||||
"device.last_seen.days": "%d д назад",
|
||||
"device.tutorial.start": "Начать обучение",
|
||||
"device.tip.metadata": "Информация об устройстве (кол-во LED, тип, цветовые каналы) определяется автоматически",
|
||||
"device.tip.brightness": "Перетащите для регулировки яркости",
|
||||
@@ -402,9 +409,11 @@
|
||||
"error.network": "Сетевая ошибка",
|
||||
"error.unknown": "Произошла ошибка",
|
||||
"modal.discard_changes": "У вас есть несохранённые изменения. Отменить их?",
|
||||
"confirm.title": "Подтверждение Действия",
|
||||
"confirm.title": "Подтверждение",
|
||||
"confirm.yes": "Да",
|
||||
"confirm.no": "Нет",
|
||||
"confirm.stop_all": "Остановить все запущенные цели?",
|
||||
"confirm.turn_off_device": "Выключить это устройство?",
|
||||
"common.loading": "Загрузка...",
|
||||
"common.delete": "Удалить",
|
||||
"common.edit": "Редактировать",
|
||||
@@ -584,6 +593,7 @@
|
||||
"targets.section.color_strips": "Источники цветовых полос",
|
||||
"targets.section.targets": "Цели",
|
||||
"targets.section.specific_settings": "Специальные настройки",
|
||||
"targets.section.advanced": "Расширенные",
|
||||
"targets.add": "Добавить Цель",
|
||||
"targets.edit": "Редактировать Цель",
|
||||
"targets.loading": "Загрузка целей...",
|
||||
@@ -953,6 +963,11 @@
|
||||
"color_strip.gradient.preset.cool": "Холодный",
|
||||
"color_strip.gradient.preset.neon": "Неон",
|
||||
"color_strip.gradient.preset.pastel": "Пастельный",
|
||||
"color_strip.gradient.preset.save_button": "Сохранить как пресет…",
|
||||
"color_strip.gradient.preset.save_prompt": "Введите название пресета:",
|
||||
"color_strip.gradient.preset.saved": "Пресет сохранён",
|
||||
"color_strip.gradient.preset.deleted": "Пресет удалён",
|
||||
"color_strip.gradient.preset.apply": "Применить",
|
||||
"color_strip.animation": "Анимация",
|
||||
"color_strip.animation.type": "Эффект:",
|
||||
"color_strip.animation.type.hint": "Эффект анимации.",
|
||||
@@ -1043,6 +1058,15 @@
|
||||
"color_strip.notification.test.ok": "Уведомление отправлено",
|
||||
"color_strip.notification.test.no_streams": "Нет запущенных потоков для этого источника",
|
||||
"color_strip.notification.test.error": "Не удалось отправить уведомление",
|
||||
"color_strip.notification.history.title": "История уведомлений",
|
||||
"color_strip.notification.history.hint": "Последние ОС-уведомления, захваченные слушателем (новейшие сверху). До 50 записей.",
|
||||
"color_strip.notification.history.empty": "Уведомления ещё не захвачены",
|
||||
"color_strip.notification.history.unavailable": "Слушатель уведомлений ОС недоступен на этой платформе",
|
||||
"color_strip.notification.history.error": "Не удалось загрузить историю уведомлений",
|
||||
"color_strip.notification.history.refresh": "Обновить",
|
||||
"color_strip.notification.history.unknown_app": "Неизвестное приложение",
|
||||
"color_strip.notification.history.fired": "Потоков запущено",
|
||||
"color_strip.notification.history.filtered": "Потоков отфильтровано",
|
||||
"color_strip.test.title": "Предпросмотр",
|
||||
"color_strip.test.connecting": "Подключение...",
|
||||
"color_strip.test.error": "Не удалось подключиться к потоку предпросмотра",
|
||||
@@ -1188,6 +1212,7 @@
|
||||
"audio_source.type.mono": "Моно",
|
||||
"audio_source.device": "Аудиоустройство:",
|
||||
"audio_source.device.hint": "Источник аудиосигнала. Устройства обратной петли захватывают системный звук; устройства ввода — микрофон или линейный вход.",
|
||||
"audio_source.refresh_devices": "Обновить устройства",
|
||||
"audio_source.parent": "Родительский источник:",
|
||||
"audio_source.parent.hint": "Многоканальный источник для извлечения канала",
|
||||
"audio_source.channel": "Канал:",
|
||||
@@ -1375,6 +1400,13 @@
|
||||
"search.group.value": "Источники значений",
|
||||
"search.group.scenes": "Пресеты сцен",
|
||||
"search.group.cspt": "Шаблоны обработки полос",
|
||||
"search.group.sync_clocks": "Синхронные часы",
|
||||
"search.group.actions": "Действия",
|
||||
"search.action.start": "Запустить",
|
||||
"search.action.stop": "Остановить",
|
||||
"search.action.activate": "Активировать",
|
||||
"search.action.enable": "Включить",
|
||||
"search.action.disable": "Отключить",
|
||||
"settings.backup.label": "Резервное копирование",
|
||||
"settings.backup.hint": "Скачать всю конфигурацию (устройства, цели, потоки, шаблоны, автоматизации) в виде одного JSON-файла.",
|
||||
"settings.backup.button": "Скачать резервную копию",
|
||||
@@ -1388,7 +1420,15 @@
|
||||
"settings.restore.error": "Ошибка восстановления",
|
||||
"settings.restore.restarting": "Сервер перезапускается...",
|
||||
"settings.restore.restart_timeout": "Сервер не отвечает. Обновите страницу вручную.",
|
||||
"settings.restart_server": "Перезапустить сервер",
|
||||
"settings.restart_confirm": "Перезапустить сервер? Активные цели будут остановлены.",
|
||||
"settings.restarting": "Перезапуск сервера...",
|
||||
"settings.button.close": "Закрыть",
|
||||
"settings.log_level.label": "Уровень логирования",
|
||||
"settings.log_level.hint": "Изменить подробность логов сервера в реальном времени. DEBUG — максимум деталей, CRITICAL — только критические ошибки.",
|
||||
"settings.log_level.save": "Применить",
|
||||
"settings.log_level.saved": "Уровень логирования изменён",
|
||||
"settings.log_level.save_error": "Не удалось изменить уровень логирования",
|
||||
"settings.auto_backup.label": "Авто-бэкап",
|
||||
"settings.auto_backup.hint": "Автоматическое создание периодических резервных копий конфигурации. Старые копии удаляются при превышении максимального количества.",
|
||||
"settings.auto_backup.enable": "Включить авто-бэкап",
|
||||
@@ -1407,6 +1447,32 @@
|
||||
"settings.saved_backups.delete": "Удалить",
|
||||
"settings.saved_backups.delete_confirm": "Удалить эту резервную копию?",
|
||||
"settings.saved_backups.delete_error": "Не удалось удалить копию",
|
||||
"settings.saved_backups.type.auto": "авто",
|
||||
"settings.saved_backups.type.manual": "ручной",
|
||||
"settings.mqtt.label": "MQTT",
|
||||
"settings.mqtt.hint": "Настройте подключение к MQTT-брокеру для условий и триггеров автоматизации.",
|
||||
"settings.mqtt.enabled": "Включить MQTT",
|
||||
"settings.mqtt.host_label": "Хост брокера",
|
||||
"settings.mqtt.port_label": "Порт",
|
||||
"settings.mqtt.username_label": "Имя пользователя",
|
||||
"settings.mqtt.password_label": "Пароль",
|
||||
"settings.mqtt.password_set_hint": "Пароль задан — оставьте пустым, чтобы сохранить",
|
||||
"settings.mqtt.client_id_label": "Идентификатор клиента",
|
||||
"settings.mqtt.base_topic_label": "Базовый топик",
|
||||
"settings.mqtt.save": "Сохранить настройки MQTT",
|
||||
"settings.mqtt.saved": "Настройки MQTT сохранены",
|
||||
"settings.mqtt.save_error": "Не удалось сохранить настройки MQTT",
|
||||
"settings.mqtt.error_host_required": "Требуется указать хост брокера",
|
||||
"settings.logs.label": "Журнал сервера",
|
||||
"settings.logs.hint": "Просмотр журнала сервера в реальном времени. Используйте фильтр для отображения нужных уровней.",
|
||||
"settings.logs.connect": "Подключить",
|
||||
"settings.logs.disconnect": "Отключить",
|
||||
"settings.logs.clear": "Очистить",
|
||||
"settings.logs.error": "Ошибка подключения к журналу",
|
||||
"settings.logs.filter.all": "Все уровни",
|
||||
"settings.logs.filter.info": "Info+",
|
||||
"settings.logs.filter.warning": "Warning+",
|
||||
"settings.logs.filter.error": "Только ошибки",
|
||||
"device.error.power_off_failed": "Не удалось выключить устройство",
|
||||
"device.removed": "Устройство удалено",
|
||||
"device.error.remove_failed": "Не удалось удалить устройство",
|
||||
@@ -1415,6 +1481,7 @@
|
||||
"device.error.required": "Пожалуйста, заполните все поля",
|
||||
"device.error.update": "Не удалось обновить устройство",
|
||||
"device.error.save": "Не удалось сохранить настройки",
|
||||
"device.error.clone_failed": "Не удалось клонировать устройство",
|
||||
"device_discovery.error.fill_all_fields": "Пожалуйста, заполните все поля",
|
||||
"device_discovery.added": "Устройство успешно добавлено",
|
||||
"device_discovery.error.add_failed": "Не удалось добавить устройство",
|
||||
@@ -1506,6 +1573,7 @@
|
||||
"sync_clock.resumed": "Часы возобновлены",
|
||||
"sync_clock.reset_done": "Часы сброшены на ноль",
|
||||
"sync_clock.delete.confirm": "Удалить эти часы синхронизации? Привязанные источники потеряют синхронизацию и будут работать на скорости по умолчанию.",
|
||||
"sync_clock.elapsed": "Прошло времени",
|
||||
"color_strip.clock": "Часы синхронизации:",
|
||||
"color_strip.clock.hint": "Привязка к часам для синхронизации анимации между источниками. Скорость управляется на часах.",
|
||||
"graph.title": "Граф",
|
||||
@@ -1570,5 +1638,50 @@
|
||||
"graph.help.right_click_desc": "Отсоединить связь",
|
||||
"automation.enabled": "Автоматизация включена",
|
||||
"automation.disabled": "Автоматизация выключена",
|
||||
"scene_preset.activated": "Пресет активирован"
|
||||
"scene_preset.activated": "Пресет активирован",
|
||||
"scene_preset.used_by": "Используется в %d автоматизации(ях)",
|
||||
"settings.api_keys.label": "API-ключи",
|
||||
"settings.api_keys.hint": "API-ключи определяются в конфигурационном файле сервера (config.yaml). Отредактируйте файл и перезапустите сервер для применения изменений.",
|
||||
"settings.api_keys.empty": "API-ключи не настроены",
|
||||
"settings.api_keys.load_error": "Не удалось загрузить API-ключи",
|
||||
"settings.partial.label": "Частичный экспорт / импорт",
|
||||
"settings.partial.hint": "Экспортировать или импортировать один тип объектов. Импорт заменяет или объединяет данные и перезапускает сервер.",
|
||||
"settings.partial.store.devices": "Устройства",
|
||||
"settings.partial.store.output_targets": "LED-цели",
|
||||
"settings.partial.store.color_strip_sources": "Цветные полосы",
|
||||
"settings.partial.store.picture_sources": "Источники изображений",
|
||||
"settings.partial.store.audio_sources": "Аудио-источники",
|
||||
"settings.partial.store.audio_templates": "Аудио-шаблоны",
|
||||
"settings.partial.store.capture_templates": "Шаблоны захвата",
|
||||
"settings.partial.store.postprocessing_templates": "Шаблоны постобработки",
|
||||
"settings.partial.store.color_strip_processing_templates": "Шаблоны обработки полос",
|
||||
"settings.partial.store.pattern_templates": "Шаблоны паттернов",
|
||||
"settings.partial.store.value_sources": "Источники значений",
|
||||
"settings.partial.store.sync_clocks": "Синхронные часы",
|
||||
"settings.partial.store.automations": "Автоматизации",
|
||||
"settings.partial.store.scene_presets": "Пресеты сцен",
|
||||
"settings.partial.export_button": "Экспорт",
|
||||
"settings.partial.import_button": "Импорт из файла",
|
||||
"settings.partial.merge_label": "Объединить (добавить/перезаписать, сохранить существующие)",
|
||||
"settings.partial.export_success": "Экспорт выполнен",
|
||||
"settings.partial.export_error": "Ошибка экспорта",
|
||||
"settings.partial.import_success": "Импорт выполнен",
|
||||
"settings.partial.import_error": "Ошибка импорта",
|
||||
"settings.partial.import_confirm_replace": "Это ЗАМЕНИТ все данные {store} и перезапустит сервер. Продолжить?",
|
||||
"settings.partial.import_confirm_merge": "Это ОБЪЕДИНИТ данные {store} и перезапустит сервер. Продолжить?",
|
||||
"section.empty.devices": "Устройств пока нет. Нажмите + для добавления.",
|
||||
"section.empty.targets": "LED-целей пока нет. Нажмите + для добавления.",
|
||||
"section.empty.kc_targets": "Целей ключевых цветов пока нет. Нажмите + для добавления.",
|
||||
"section.empty.pattern_templates": "Шаблонов паттернов пока нет. Нажмите + для добавления.",
|
||||
"section.empty.picture_sources": "Источников пока нет. Нажмите + для добавления.",
|
||||
"section.empty.capture_templates": "Шаблонов захвата пока нет. Нажмите + для добавления.",
|
||||
"section.empty.pp_templates": "Шаблонов постобработки пока нет. Нажмите + для добавления.",
|
||||
"section.empty.audio_sources": "Аудио-источников пока нет. Нажмите + для добавления.",
|
||||
"section.empty.audio_templates": "Аудио-шаблонов пока нет. Нажмите + для добавления.",
|
||||
"section.empty.color_strips": "Цветных полос пока нет. Нажмите + для добавления.",
|
||||
"section.empty.value_sources": "Источников значений пока нет. Нажмите + для добавления.",
|
||||
"section.empty.sync_clocks": "Синхронных часов пока нет. Нажмите + для добавления.",
|
||||
"section.empty.cspt": "Шаблонов обработки полос пока нет. Нажмите + для добавления.",
|
||||
"section.empty.automations": "Автоматизаций пока нет. Нажмите + для добавления.",
|
||||
"section.empty.scenes": "Пресетов сцен пока нет. Нажмите + для добавления."
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"auth.toggle_password": "切换密码可见性",
|
||||
"auth.prompt_enter": "Enter your API key:",
|
||||
"auth.prompt_update": "Current API key is set. Enter new key to update or leave blank to remove:",
|
||||
"api_key.login": "登录",
|
||||
"displays.title": "可用显示器",
|
||||
"displays.layout": "显示器",
|
||||
"displays.information": "显示器信息",
|
||||
@@ -291,6 +292,12 @@
|
||||
"device.health.offline": "离线",
|
||||
"device.health.streaming_unreachable": "流传输期间不可达",
|
||||
"device.health.checking": "检测中...",
|
||||
"device.last_seen.label": "最近检测",
|
||||
"device.last_seen.just_now": "刚刚",
|
||||
"device.last_seen.seconds": "%d秒前",
|
||||
"device.last_seen.minutes": "%d分钟前",
|
||||
"device.last_seen.hours": "%d小时前",
|
||||
"device.last_seen.days": "%d天前",
|
||||
"device.tutorial.start": "开始教程",
|
||||
"device.tip.metadata": "设备信息(LED 数量、类型、颜色通道)从设备自动检测",
|
||||
"device.tip.brightness": "滑动调节设备亮度",
|
||||
@@ -405,6 +412,8 @@
|
||||
"confirm.title": "确认操作",
|
||||
"confirm.yes": "是",
|
||||
"confirm.no": "否",
|
||||
"confirm.stop_all": "停止所有运行中的目标?",
|
||||
"confirm.turn_off_device": "关闭此设备?",
|
||||
"common.loading": "加载中...",
|
||||
"common.delete": "删除",
|
||||
"common.edit": "编辑",
|
||||
@@ -584,6 +593,7 @@
|
||||
"targets.section.color_strips": "色带源",
|
||||
"targets.section.targets": "目标",
|
||||
"targets.section.specific_settings": "特定设置",
|
||||
"targets.section.advanced": "高级",
|
||||
"targets.add": "添加目标",
|
||||
"targets.edit": "编辑目标",
|
||||
"targets.loading": "正在加载目标...",
|
||||
@@ -953,6 +963,11 @@
|
||||
"color_strip.gradient.preset.cool": "冷色",
|
||||
"color_strip.gradient.preset.neon": "霓虹",
|
||||
"color_strip.gradient.preset.pastel": "柔和",
|
||||
"color_strip.gradient.preset.save_button": "保存为预设…",
|
||||
"color_strip.gradient.preset.save_prompt": "输入预设名称:",
|
||||
"color_strip.gradient.preset.saved": "预设已保存",
|
||||
"color_strip.gradient.preset.deleted": "预设已删除",
|
||||
"color_strip.gradient.preset.apply": "应用",
|
||||
"color_strip.animation": "动画",
|
||||
"color_strip.animation.type": "效果:",
|
||||
"color_strip.animation.type.hint": "要应用的动画效果。",
|
||||
@@ -1043,6 +1058,15 @@
|
||||
"color_strip.notification.test.ok": "通知已发送",
|
||||
"color_strip.notification.test.no_streams": "此源没有运行中的流",
|
||||
"color_strip.notification.test.error": "发送通知失败",
|
||||
"color_strip.notification.history.title": "通知历史",
|
||||
"color_strip.notification.history.hint": "监听器捕获的最近OS通知(最新在前),最多50条。",
|
||||
"color_strip.notification.history.empty": "尚未捕获任何通知",
|
||||
"color_strip.notification.history.unavailable": "此平台不支持OS通知监听器",
|
||||
"color_strip.notification.history.error": "加载通知历史失败",
|
||||
"color_strip.notification.history.refresh": "刷新",
|
||||
"color_strip.notification.history.unknown_app": "未知应用",
|
||||
"color_strip.notification.history.fired": "触发的流数量",
|
||||
"color_strip.notification.history.filtered": "过滤的流数量",
|
||||
"color_strip.test.title": "预览测试",
|
||||
"color_strip.test.connecting": "连接中...",
|
||||
"color_strip.test.error": "无法连接到预览流",
|
||||
@@ -1188,6 +1212,7 @@
|
||||
"audio_source.type.mono": "单声道",
|
||||
"audio_source.device": "音频设备:",
|
||||
"audio_source.device.hint": "音频输入源。回环设备采集系统音频输出;输入设备采集麦克风或线路输入。",
|
||||
"audio_source.refresh_devices": "刷新设备",
|
||||
"audio_source.parent": "父源:",
|
||||
"audio_source.parent.hint": "要从中提取通道的多声道源",
|
||||
"audio_source.channel": "通道:",
|
||||
@@ -1375,6 +1400,13 @@
|
||||
"search.group.value": "值源",
|
||||
"search.group.scenes": "场景预设",
|
||||
"search.group.cspt": "色带处理模板",
|
||||
"search.group.sync_clocks": "同步时钟",
|
||||
"search.group.actions": "操作",
|
||||
"search.action.start": "启动",
|
||||
"search.action.stop": "停止",
|
||||
"search.action.activate": "激活",
|
||||
"search.action.enable": "启用",
|
||||
"search.action.disable": "禁用",
|
||||
"settings.backup.label": "备份配置",
|
||||
"settings.backup.hint": "将所有配置(设备、目标、流、模板、自动化)下载为单个 JSON 文件。",
|
||||
"settings.backup.button": "下载备份",
|
||||
@@ -1388,7 +1420,15 @@
|
||||
"settings.restore.error": "恢复失败",
|
||||
"settings.restore.restarting": "服务器正在重启...",
|
||||
"settings.restore.restart_timeout": "服务器未响应。请手动刷新页面。",
|
||||
"settings.restart_server": "重启服务器",
|
||||
"settings.restart_confirm": "重启服务器?活跃的目标将被停止。",
|
||||
"settings.restarting": "正在重启服务器...",
|
||||
"settings.button.close": "关闭",
|
||||
"settings.log_level.label": "日志级别",
|
||||
"settings.log_level.hint": "实时更改服务器日志详细程度。DEBUG 显示最多细节;CRITICAL 仅显示致命错误。",
|
||||
"settings.log_level.save": "应用",
|
||||
"settings.log_level.saved": "日志级别已更改",
|
||||
"settings.log_level.save_error": "更改日志级别失败",
|
||||
"settings.auto_backup.label": "自动备份",
|
||||
"settings.auto_backup.hint": "自动定期创建所有配置的备份。当达到最大数量时,旧备份会被自动清理。",
|
||||
"settings.auto_backup.enable": "启用自动备份",
|
||||
@@ -1407,6 +1447,32 @@
|
||||
"settings.saved_backups.delete": "删除",
|
||||
"settings.saved_backups.delete_confirm": "删除此备份文件?",
|
||||
"settings.saved_backups.delete_error": "删除备份失败",
|
||||
"settings.saved_backups.type.auto": "自动",
|
||||
"settings.saved_backups.type.manual": "手动",
|
||||
"settings.mqtt.label": "MQTT",
|
||||
"settings.mqtt.hint": "配置 MQTT 代理连接,用于自动化条件和触发器。",
|
||||
"settings.mqtt.enabled": "启用 MQTT",
|
||||
"settings.mqtt.host_label": "代理主机",
|
||||
"settings.mqtt.port_label": "端口",
|
||||
"settings.mqtt.username_label": "用户名",
|
||||
"settings.mqtt.password_label": "密码",
|
||||
"settings.mqtt.password_set_hint": "已设置密码 — 留空以保留",
|
||||
"settings.mqtt.client_id_label": "客户端 ID",
|
||||
"settings.mqtt.base_topic_label": "基础主题",
|
||||
"settings.mqtt.save": "保存 MQTT 设置",
|
||||
"settings.mqtt.saved": "MQTT 设置已保存",
|
||||
"settings.mqtt.save_error": "保存 MQTT 设置失败",
|
||||
"settings.mqtt.error_host_required": "代理主机不能为空",
|
||||
"settings.logs.label": "服务器日志",
|
||||
"settings.logs.hint": "实时查看服务器日志。使用过滤器显示所需的日志级别。",
|
||||
"settings.logs.connect": "连接",
|
||||
"settings.logs.disconnect": "断开",
|
||||
"settings.logs.clear": "清除",
|
||||
"settings.logs.error": "日志查看器连接失败",
|
||||
"settings.logs.filter.all": "所有级别",
|
||||
"settings.logs.filter.info": "Info+",
|
||||
"settings.logs.filter.warning": "Warning+",
|
||||
"settings.logs.filter.error": "仅错误",
|
||||
"device.error.power_off_failed": "关闭设备失败",
|
||||
"device.removed": "设备已移除",
|
||||
"device.error.remove_failed": "移除设备失败",
|
||||
@@ -1415,6 +1481,7 @@
|
||||
"device.error.required": "请填写所有字段",
|
||||
"device.error.update": "更新设备失败",
|
||||
"device.error.save": "保存设置失败",
|
||||
"device.error.clone_failed": "克隆设备失败",
|
||||
"device_discovery.error.fill_all_fields": "请填写所有字段",
|
||||
"device_discovery.added": "设备添加成功",
|
||||
"device_discovery.error.add_failed": "添加设备失败",
|
||||
@@ -1506,6 +1573,7 @@
|
||||
"sync_clock.resumed": "时钟已恢复",
|
||||
"sync_clock.reset_done": "时钟已重置为零",
|
||||
"sync_clock.delete.confirm": "删除此同步时钟?关联的源将失去同步并以默认速度运行。",
|
||||
"sync_clock.elapsed": "已用时间",
|
||||
"color_strip.clock": "同步时钟:",
|
||||
"color_strip.clock.hint": "关联同步时钟以在多个源之间同步动画。速度在时钟上控制。",
|
||||
"graph.title": "图表",
|
||||
@@ -1570,5 +1638,50 @@
|
||||
"graph.help.right_click_desc": "断开连接",
|
||||
"automation.enabled": "自动化已启用",
|
||||
"automation.disabled": "自动化已禁用",
|
||||
"scene_preset.activated": "预设已激活"
|
||||
"scene_preset.activated": "预设已激活",
|
||||
"scene_preset.used_by": "被 %d 个自动化使用",
|
||||
"settings.api_keys.label": "API 密钥",
|
||||
"settings.api_keys.hint": "API 密钥在服务器配置文件 (config.yaml) 中定义。编辑文件并重启服务器以应用更改。",
|
||||
"settings.api_keys.empty": "未配置 API 密钥",
|
||||
"settings.api_keys.load_error": "加载 API 密钥失败",
|
||||
"settings.partial.label": "部分导出 / 导入",
|
||||
"settings.partial.hint": "导出或导入单个实体类型。导入会替换或合并现有数据并重启服务器。",
|
||||
"settings.partial.store.devices": "设备",
|
||||
"settings.partial.store.output_targets": "LED 目标",
|
||||
"settings.partial.store.color_strip_sources": "色带",
|
||||
"settings.partial.store.picture_sources": "图像源",
|
||||
"settings.partial.store.audio_sources": "音频源",
|
||||
"settings.partial.store.audio_templates": "音频模板",
|
||||
"settings.partial.store.capture_templates": "捕获模板",
|
||||
"settings.partial.store.postprocessing_templates": "后处理模板",
|
||||
"settings.partial.store.color_strip_processing_templates": "CSS 处理模板",
|
||||
"settings.partial.store.pattern_templates": "图案模板",
|
||||
"settings.partial.store.value_sources": "值源",
|
||||
"settings.partial.store.sync_clocks": "同步时钟",
|
||||
"settings.partial.store.automations": "自动化",
|
||||
"settings.partial.store.scene_presets": "场景预设",
|
||||
"settings.partial.export_button": "导出",
|
||||
"settings.partial.import_button": "从文件导入",
|
||||
"settings.partial.merge_label": "合并(添加/覆盖,保留现有)",
|
||||
"settings.partial.export_success": "导出成功",
|
||||
"settings.partial.export_error": "导出失败",
|
||||
"settings.partial.import_success": "导入成功",
|
||||
"settings.partial.import_error": "导入失败",
|
||||
"settings.partial.import_confirm_replace": "这将替换所有 {store} 数据并重启服务器。继续吗?",
|
||||
"settings.partial.import_confirm_merge": "这将合并 {store} 数据并重启服务器。继续吗?",
|
||||
"section.empty.devices": "暂无设备。点击 + 添加。",
|
||||
"section.empty.targets": "暂无 LED 目标。点击 + 添加。",
|
||||
"section.empty.kc_targets": "暂无键色目标。点击 + 添加。",
|
||||
"section.empty.pattern_templates": "暂无图案模板。点击 + 添加。",
|
||||
"section.empty.picture_sources": "暂无源。点击 + 添加。",
|
||||
"section.empty.capture_templates": "暂无捕获模板。点击 + 添加。",
|
||||
"section.empty.pp_templates": "暂无后处理模板。点击 + 添加。",
|
||||
"section.empty.audio_sources": "暂无音频源。点击 + 添加。",
|
||||
"section.empty.audio_templates": "暂无音频模板。点击 + 添加。",
|
||||
"section.empty.color_strips": "暂无色带。点击 + 添加。",
|
||||
"section.empty.value_sources": "暂无值源。点击 + 添加。",
|
||||
"section.empty.sync_clocks": "暂无同步时钟。点击 + 添加。",
|
||||
"section.empty.cspt": "暂无 CSS 处理模板。点击 + 添加。",
|
||||
"section.empty.automations": "暂无自动化。点击 + 添加。",
|
||||
"section.empty.scenes": "暂无场景预设。点击 + 添加。"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user