feat: asset-based image/video sources, notification sounds, UI improvements
Lint & Test / test (push) Has been cancelled

- Replace URL-based image_source/url fields with image_asset_id/video_asset_id
  on StaticImagePictureSource and VideoCaptureSource (clean break, no migration)
- Resolve asset IDs to file paths at runtime via AssetStore.get_file_path()
- Add EntitySelect asset pickers for image/video in stream editor modal
- Add notification sound configuration (global sound + per-app overrides)
- Unify per-app color and sound overrides into single "Per-App Overrides" section
- Persist notification history between server restarts
- Add asset management system (upload, edit, delete, soft-delete)
- Replace emoji buttons with SVG icons throughout UI
- Various backend improvements: SQLite stores, auth, backup, MQTT, webhooks
This commit is contained in:
2026-03-26 20:40:25 +03:00
parent c0853ce184
commit e2e1107df7
100 changed files with 2935 additions and 992 deletions
@@ -593,22 +593,19 @@
"streams.add.video": "添加视频源",
"streams.edit.video": "编辑视频源",
"picture_source.type.video": "视频",
"picture_source.type.video.desc": "从视频文件、URL或YouTube流式传输帧",
"picture_source.video.url": "视频URL",
"picture_source.video.url.hint": "本地文件路径、HTTP URL或YouTube URL",
"picture_source.video.url.placeholder": "https://example.com/video.mp4",
"picture_source.type.video.desc": "从上传的视频素材中流式传输帧",
"picture_source.video.loop": "循环:",
"picture_source.video.speed": "播放速度:",
"picture_source.video.start_time": "开始时间(秒):",
"picture_source.video.end_time": "结束时间(秒):",
"picture_source.video.resolution_limit": "最大宽度(像素):",
"picture_source.video.resolution_limit.hint": "解码时缩小视频以提高性能",
"streams.image_source": "图片",
"streams.image_source.placeholder": "https://example.com/image.jpg 或 C:\\path\\to\\image.png",
"streams.image_source.hint": "输入图片的 URLhttp/https)或本地文件路径",
"streams.validate_image.validating": "正在验证...",
"streams.validate_image.valid": "图片可访问",
"streams.validate_image.invalid": "图片不可访问",
"streams.image_asset": "图片素材",
"streams.image_asset.select": "选择图片素材…",
"streams.image_asset.search": "搜索图片素材…",
"streams.video_asset": "视频素材:",
"streams.video_asset.select": "选择视频素材…",
"streams.video_asset.search": "搜索视频素材…",
"targets.title": "目标",
"targets.description": "目标将色带源桥接到输出设备。每个目标引用一个设备和一个色带源。",
"targets.subtab.wled": "LED",
@@ -1084,6 +1081,22 @@
"color_strip.notification.app_colors.label": "颜色映射:",
"color_strip.notification.app_colors.hint": "每个应用的自定义通知颜色。每行将一个应用名称映射到特定颜色。",
"color_strip.notification.app_colors.add": "+ 添加映射",
"color_strip.notification.app_overrides": "按应用覆盖",
"color_strip.notification.app_overrides.label": "应用覆盖:",
"color_strip.notification.app_overrides.hint": "为特定应用自定义颜色和声音。每行可设置颜色、声音资源和音量。",
"color_strip.notification.app_overrides.add": "+ 添加覆盖",
"color_strip.notification.app_overrides.app_placeholder": "应用名称",
"color_strip.notification.sound": "声音",
"color_strip.notification.sound.asset": "声音资源:",
"color_strip.notification.sound.asset.hint": "选择通知触发时播放的声音资源。留空表示静音。",
"color_strip.notification.sound.none": "无(静音)",
"color_strip.notification.sound.search": "搜索声音…",
"color_strip.notification.sound.volume": "音量:",
"color_strip.notification.sound.volume.hint": "通知声音的全局音量(0100%)。",
"color_strip.notification.sound.app_sounds": "按应用声音:",
"color_strip.notification.sound.app_sounds.hint": "为特定应用覆盖声音和音量。空声音 = 静音该应用。",
"color_strip.notification.sound.app_sounds.add": "+ 添加覆盖",
"color_strip.notification.sound.app_name_placeholder": "应用名称",
"color_strip.notification.endpoint": "Webhook 端点:",
"color_strip.notification.endpoint.hint": "使用此 URL 从外部系统触发通知。POST 请求可选 JSON{\"app\": \"AppName\", \"color\": \"#FF0000\"}。",
"color_strip.notification.save_first": "请先保存源以查看 Webhook 端点 URL。",
@@ -1890,9 +1903,35 @@
"update.install_type.docker": "Docker",
"update.install_type.dev": "开发环境",
"color_strip": {
"notification": {
"search_apps": "搜索通知应用…"
}
}
"color_strip.notification.search_apps": "搜索通知应用…",
"asset.group.title": "资源",
"asset.upload": "上传资源",
"asset.edit": "编辑资源",
"asset.name": "名称:",
"asset.name.hint": "资源的显示名称。",
"asset.description": "描述:",
"asset.description.hint": "资源的可选描述。",
"asset.file": "文件:",
"asset.file.hint": "选择要上传的文件(声音、图片、视频或其他)。",
"asset.drop_or_browse": "拖放文件到此处或点击浏览",
"asset.uploaded": "资源已上传",
"asset.updated": "资源已更新",
"asset.deleted": "资源已删除",
"asset.confirm_delete": "删除此资源?",
"asset.error.name_required": "名称为必填项",
"asset.error.no_file": "请选择要上传的文件",
"asset.error.delete_failed": "删除资源失败",
"asset.play": "播放",
"asset.download": "下载",
"asset.prebuilt": "内置",
"asset.prebuilt_restored": "已恢复 {count} 个内置资源",
"asset.prebuilt_none_to_restore": "所有内置资源均已可用",
"asset.restore_prebuilt": "恢复内置声音",
"asset.type.sound": "声音",
"asset.type.image": "图片",
"asset.type.video": "视频",
"asset.type.other": "其他",
"streams.group.assets": "资源",
"section.empty.assets": "暂无资源。点击 + 上传一个。"
}