diff --git a/crates/aster-webui/src/ui.rs b/crates/aster-webui/src/ui.rs index 6d67216..09368ca 100644 --- a/crates/aster-webui/src/ui.rs +++ b/crates/aster-webui/src/ui.rs @@ -26,166 +26,428 @@ const INDEX_HTML: &str = r##" aster-webui
-
-
-

aoostar-rs fork

-

aster-webui

-

Eigene Rust-WebUI mit nativer Display-Logik. Bilder werden auf 960x376 normalisiert, GIFs als animierte Frame-Sets importiert; die Rotation laeuft direkt ueber `aoostar-rs` ohne Vendor-Binary.

-
- - -
- - - +
+
+
A
+
+

aster-webui

+

AOOSTAR display control

+
+
+
+ + +
+
+ +
+
+
+
+

Rotation Setup

+ /config/Monitor3.json +
+
+ + +
+ +
+
+
+ + +
-
- - - + +
+
CPU--
+
Memory--
+
Storage--
+
Swap--
+
Load Avg--
+
Temperatures--
+
+
+ + +
+ +
+
+
+

Available Images

+ 960 x 376
-
-
-
Custom Panel-
-
Active Images-
-
Display Status-
-
Current Frame-
-
Display Target-
-
Config Path-
-
-
-
-
CPU--
-
Memory--
-
Storage--
-
Swap--
-
Load Avg--
-
Temperatures--
-
-
-
-

Available Images

-
-

Rotation Order

+
+
+

Rotation Order

+ Live queue +

@@ -251,6 +513,15 @@ const INDEX_HTML: &str = r##" return (n / 1024 / 1024).toFixed(1) + " MB"; } + function escapeHtml(value) { + return String(value) + .replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll(">", ">") + .replaceAll('"', """) + .replaceAll("'", "'"); + } + function move(index, delta) { const target = index + delta; if (target < 0 || target >= state.activeImages.length) return; @@ -406,14 +677,17 @@ const INDEX_HTML: &str = r##" for (const image of state.images) { const selected = state.activeImages.includes(image.name); const tile = document.createElement("article"); + const safeLabel = escapeHtml(image.label); + const safeName = escapeHtml(image.name); + const safeUrl = escapeHtml(image.url); tile.className = "tile" + (selected ? " selected" : ""); tile.innerHTML = ` - ${image.name} + ${safeName}
-
${image.label}
-
${bytes(image.size)}${image.animated ? ` • GIF • ${image.frame_count} Frames` : ""}
+
${safeLabel}
+
${bytes(image.size)}${image.animated ? ` • GIF • ${image.frame_count} Frames` : ""}
- +
@@ -427,14 +701,14 @@ const INDEX_HTML: &str = r##" el.order.innerHTML = ""; if (state.setup.specs_enabled && !state.activeImages.length) { const row = document.createElement("div"); - row.className = "order-item"; + row.className = "order-item" + (state.display.current_image === "System Specs" ? " current" : ""); row.innerHTML = `
S
System Specs
-
${state.display.current_image === "System Specs" ? "Currently shown" : "Fixed first frame when enabled"}
+
${state.display.current_image === "System Specs" ? "Currently shown" : "Enabled"}
-
Toggle above
+
Specs
`; el.order.appendChild(row); } @@ -446,9 +720,9 @@ const INDEX_HTML: &str = r##"
S
System Specs Overlay
-
Live stats are drawn over every meme while enabled.
+
Overlay active
-
Toggle above
+
Specs
`; el.order.appendChild(row); } @@ -460,19 +734,20 @@ const INDEX_HTML: &str = r##" state.activeImages.forEach((name, index) => { const image = imageMap.get(name); const label = image ? image.label : name; + const safeLabel = escapeHtml(label); const row = document.createElement("div"); - row.className = "order-item"; const isCurrent = state.display.current_image === name || state.display.current_image === label; + row.className = "order-item" + (isCurrent ? " current" : ""); row.innerHTML = `
${index + 1}
-
${label}
+
${safeLabel}
${isCurrent ? "Currently shown" : (image && image.animated ? `Animated • ${image.frame_count} Frames` : "")}
- - - + + +
`; const [up, down, remove] = row.querySelectorAll("button");