From 705179f73fa9babd955346cfa8e9102c82a36a69 Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Wed, 11 Feb 2026 20:18:45 +0300 Subject: [PATCH] Refactor stream and template cards: collapsible groups, icon pills, compact layout - Make picture stream groups expandable/collapsible with localStorage persistence - Replace text labels with icon pill badges on stream and capture template cards - Remove section description text from all tabs - Add auto-validation on edit for static image streams - Show full URL on static image cards instead of truncating at 50 chars Co-Authored-By: Claude Opus 4.6 --- server/src/wled_controller/static/app.js | 200 +++++++------------ server/src/wled_controller/static/index.html | 23 --- server/src/wled_controller/static/style.css | 56 +++++- 3 files changed, 120 insertions(+), 159 deletions(-) diff --git a/server/src/wled_controller/static/app.js b/server/src/wled_controller/static/app.js index 54a28d3..79e1f3d 100644 --- a/server/src/wled_controller/static/app.js +++ b/server/src/wled_controller/static/app.js @@ -2448,6 +2448,7 @@ function renderTemplatesList(templates) { const renderCard = (template) => { const engineIcon = getEngineIcon(template.engine_type); + const configEntries = Object.entries(template.engine_config); return `
@@ -2457,14 +2458,15 @@ function renderTemplatesList(templates) { ${engineIcon} ${escapeHtml(template.name)}
-
- ${t('templates.engine')} ${template.engine_type.toUpperCase()} +
+ โš™๏ธ ${template.engine_type.toUpperCase()} + ${configEntries.length > 0 ? `๐Ÿ”ง ${configEntries.length}` : ''}
- ${Object.keys(template.engine_config).length > 0 ? ` + ${configEntries.length > 0 ? `
${t('templates.config.show')} - ${Object.entries(template.engine_config).map(([key, val]) => ` + ${configEntries.map(([key, val]) => ` @@ -2472,9 +2474,7 @@ function renderTemplatesList(templates) { `).join('')}
${escapeHtml(key)} ${escapeHtml(String(val))}
- ` : ` -
${t('templates.config.none')}
- `} + ` : ''}
-

- WLED Configuration: Configure your WLED device (effects, segments, color order, power limits, etc.) using the - official WLED app - or the built-in - WLED Web UI - (open your device's IP in a browser). - This controller sends pixel color data and controls brightness per device. -

@@ -57,33 +49,18 @@
-

- - Picture streams define the capture pipeline. A raw stream captures from a display using a capture template. A processed stream applies postprocessing to another stream. Assign streams to devices. - -

-

- - Capture templates define how the screen is captured. Each template uses a specific capture engine (MSS, DXcam, WGC) with custom settings. Assign templates to devices for optimal performance. - -

-

- - Processing templates define image filters and color correction. Assign them to processed picture streams for consistent postprocessing across devices. - -

diff --git a/server/src/wled_controller/static/style.css b/server/src/wled_controller/static/style.css index 71ab557..2625b18 100644 --- a/server/src/wled_controller/static/style.css +++ b/server/src/wled_controller/static/style.css @@ -2192,6 +2192,30 @@ input:-webkit-autofill:focus { margin-bottom: 12px; padding-bottom: 8px; border-bottom: 2px solid var(--border-color); + cursor: pointer; + user-select: none; + transition: opacity 0.2s; +} + +.stream-group-header:hover { + opacity: 0.8; +} + +.stream-group-chevron { + font-size: 10px; + color: var(--text-secondary); + flex-shrink: 0; + width: 12px; + transition: transform 0.2s; +} + +.stream-group.collapsed .stream-group-header { + margin-bottom: 0; + border-bottom-color: transparent; +} + +.stream-group.collapsed .templates-grid { + display: none; } .stream-group-icon { @@ -2395,10 +2419,32 @@ input:-webkit-autofill:focus { .validation-status.loading { color: var(--text-muted); } -.stream-card-image-source { - font-size: 0.7rem; - color: var(--text-muted); - word-break: break-all; - margin-top: 4px; +.stream-card-props { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin-bottom: 8px; +} + +.stream-card-prop { + display: inline-flex; + align-items: center; + gap: 3px; + font-size: 0.75rem; + color: var(--text-secondary); + background: var(--border-color); + padding: 2px 8px; + border-radius: 10px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 180px; +} + +.stream-card-prop-full { + max-width: 100%; + word-break: break-all; + white-space: normal; + font-size: 0.7rem; }