Improve vacuum controls, slider gestures and per-tile settings discovery

This commit is contained in:
Max Gramser
2026-09-12 16:07:17 +02:00
parent 96962399a3
commit a8b945fe3b
15 changed files with 256 additions and 38 deletions
+8
View File
@@ -1,3 +1,11 @@
## 0.2.1
- Algemene instellingen en Inspector direct bovenaan bereikbaar.
- Tegel selecteren: klikactie, grote waarde, kleine slider (ja/nee) en historieperiode.
- Inspectie per tegel met actuele HA-status en eigenschappen.
- Firmware: schuifgebaren correct verwerken, brede mini-slider zonder handvat, concrete historie-as.
- Nieuwe vacuumkaart met robotweergave, actieve zuigkracht en druk-/opdrachtfeedback.
# 0.2.0
- ESPHome CLI in de app: bestaande profielen controleren, bouwen en via USB/OTA installeren.
+68 -11
View File
@@ -6,7 +6,8 @@ let inventory = { screens: [], entities: [] },
dirty = false,
filter = "",
dragIndex = -1,
busy = false;
busy = false,
selectedTile = null;
const node = (tag, text, cls) => {
const n = document.createElement(tag);
if (text !== undefined) n.textContent = text;
@@ -256,7 +257,22 @@ function renderTiles() {
actions.append(b);
}
const options = node("details", undefined, "tile-options");
options.append(node("summary", "Tegelinstellingen"));
options.append(node("summary", "Bediening & weergave instellen"));
options.open = selectedTile === tile.entity;
options.ontoggle = () => {
li.classList.toggle("selected-tile", options.open);
if (options.open) {
selectedTile = tile.entity;
document.querySelectorAll(".tile-options").forEach((other) => {
if (other !== options) other.open = false;
});
}
};
li.onclick = (e) => {
if (!e.target.closest("input, select, button, summary, .tile-options"))
options.open = !options.open;
};
const controls = {};
const domain = tile.entity.split(".")[0];
const fields = [
[
@@ -295,10 +311,10 @@ function renderTiles() {
)
fields.push([
"inline",
"Op de tegel",
"Kleine slider op deze tegel?",
[
["none", "Geen extra bediening"],
["slider", "Mini-schuif"],
["none", "Nee"],
["slider", "Ja, direct bedienen"],
],
]);
if (domain === "sensor")
@@ -328,6 +344,7 @@ function renderTiles() {
: key === "history_hours"
? 24
: "none");
controls[key] = input;
input.onchange = () => {
tile.options = {
...tile.options,
@@ -337,11 +354,18 @@ function renderTiles() {
tile.options.inline = "none";
if (key === "inline" && input.value === "slider")
tile.options.display = "standard";
for (const [field, control] of Object.entries(controls)) {
if (tile.options[field] !== undefined)
control.value = tile.options[field];
}
markDirty();
};
label.append(input);
options.append(label);
}
const inspectTile = node("button", "Inspecteer deze tegel", "quiet");
inspectTile.onclick = () => inspect(tile.entity);
options.append(inspectTile);
content.append(options);
li.append(node("span", "⠿", "grip"), content, actions);
$("#tiles").append(li);
@@ -430,7 +454,7 @@ $("#save").onclick = async () => {
} catch (e) {
toast(e.message);
} finally {
busy = false;
((busy = false), (selectedTile = null));
$("#save").disabled = false;
}
};
@@ -625,17 +649,50 @@ $("#create-profile").onclick = async () => {
toast(e.message);
}
};
$("#inspect").onclick = async () => {
function openSection(id) {
const section = $(id);
if (section.tagName === "DETAILS") section.open = true;
section.scrollIntoView({ behavior: "smooth", block: "start" });
}
$("#nav-tiles").onclick = () => openSection("#tile-section");
$("#nav-settings").onclick = () => openSection("#general-settings");
$("#nav-inspector").onclick = () => inspect();
async function inspect(entity) {
if (!selected) return;
openSection("#inspector-section");
$("#inspection-summary").textContent = "Actuele HA-status ophalen...";
try {
const data = await (
await api(`screens/${encodeURIComponent(selected)}/inspect`)
).json();
const tiles = entity
? data.tiles.filter((t) => t.entity === entity)
: data.tiles;
$("#inspection-summary").replaceChildren();
for (const tile of tiles) {
const card = node("article", undefined, "inspection-tile");
card.append(
node("strong", tile.entity),
node("p", `Status: ${tile.state}`),
);
const options =
layout.tiles.find((t) => t.entity === tile.entity)?.options || {};
card.append(
node(
"small",
`Kleine slider: ${options.inline === "slider" ? "ja" : "nee"} · Weergave: ${options.display === "watch" ? "grote waarde" : "standaard"}`,
),
);
$("#inspection-summary").append(card);
}
$("#inspection").textContent = JSON.stringify(
await (
await api(`screens/${encodeURIComponent(selected)}/inspect`)
).json(),
entity ? tiles[0] : data,
null,
2,
);
} catch (e) {
$("#inspection-summary").textContent = e.message;
toast(e.message);
}
};
}
$("#inspect").onclick = () => inspect();
+13 -5
View File
@@ -60,15 +60,22 @@
maxlength="60"
placeholder="Bijvoorbeeld: Woonkamer"
/></label>
<div class="columns">
<nav class="editor-nav" aria-label="Scherm beheren">
<button id="nav-tiles" class="quiet">Tegels instellen</button>
<button id="nav-settings" class="quiet">
Algemene instellingen
</button>
<button id="nav-inspector" class="quiet">Inspector</button>
</nav>
<div class="columns" id="tile-section">
<div class="tile-editor">
<div class="section-title">
<h3>Je tegels</h3>
<span id="count">0 / 10</span>
</div>
<p class="hint">
Sleep om te ordenen of gebruik de pijltjes. Zes tegels per
pagina.
Klik op een tegel om bediening en weergave te kiezen. Sleep om
te ordenen. Zes tegels per pagina.
</p>
<ol id="tiles"></ol>
<p id="no-tiles" class="hint">
@@ -87,7 +94,7 @@
<div id="results" aria-live="polite"></div>
</div>
</div>
<details class="screen-settings" open>
<details class="screen-settings" id="general-settings" open>
<summary>
Scherminstellingen
<span class="hint">Helderheid, rustmomenten en weergave</span>
@@ -100,7 +107,7 @@
Gelijke begin- en eindtijd schakelen het nachtvenster uit.
</p>
</details>
<details class="screen-settings">
<details class="screen-settings" id="inspector-section">
<summary>
Inspector
<span class="hint"
@@ -108,6 +115,7 @@
>
</summary>
<button id="inspect" class="quiet">Lees actuele gegevens</button>
<div id="inspection-summary"></div>
<pre id="inspection">Selecteer een scherm en lees de gegevens.</pre>
</details>
<footer class="savebar">
+39
View File
@@ -655,3 +655,42 @@ pre {
.tile .tile-options select {
cursor: auto;
}
.editor-nav {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin: 20px 0;
padding: 12px;
background: #eaf3fc;
border-radius: 14px;
}
.editor-nav button {
background: white;
border: 1px solid #c7d9ea;
}
.tile.selected-tile {
border-color: #009fe3;
background: #f0f9ff;
}
.tile-options summary {
cursor: pointer;
color: #007fb6;
font-weight: 650;
padding: 10px 0;
}
.tile-options > button {
margin-top: 12px;
}
.inspection-tile {
padding: 14px;
margin: 10px 0;
border: 1px solid #d8e3ed;
border-radius: 12px;
overflow-wrap: anywhere;
}
#general-settings,
#inspector-section,
#tile-section {
scroll-margin-top: 16px;
}
+1 -1
View File
@@ -1,5 +1,5 @@
name: ESP Screen Manager
version: "0.2.0"
version: "0.2.1"
slug: esp_screen_manager
description: Kies tegels voor je CYD en Guition touchscreen, zonder opnieuw flashen.
url: https://github.com/MaxGramser/homeassistant_espscreen