diff --git a/settings/ui/app.js b/settings/ui/app.js index e8b7c35..94a6f8a 100644 --- a/settings/ui/app.js +++ b/settings/ui/app.js @@ -413,12 +413,15 @@ const kt = k.tiles.find((x) => x.id === t.id) || { says: [], holding: "", checks: [] }; const fixOptions = (cur) => `${Object.entries(c.fixes).map(([id, f]) => ``).join("")}`; const short = (text, n) => { text = String(text || ""); return text.length > n ? text.slice(0, n - 1) + "…" : text; }; + let lastQ = null; const checks = (t.checks || []).map((chk, j) => { const spec = state.schema.checks[chk.type] || { fields: [], question: "" }; const sentence = (kt.checks[j] || {}).sentence || chk.type; - const what = chk.conn || chk.peer || chk.name || chk.msg || (chk.params || {}).process || chk.host || chk.label || ""; - const summary = `${esc(spec.question || chk.type)} ${esc(short(what || sentence, 40))}${hint(sentence)}`; - if (!editing()) return `
${summary}

${esc(sentence)}

`; + const what = chk.type === "midi_peer" ? `${chk.peer || "?"} in ${esc(chk.session || "?")}` : esc(chk.conn || chk.name || (chk.params || {}).process || chk.msg || chk.host || chk.label || chk.url || chk.session || short(sentence, 40)); + const q = spec.question || chk.type; + const header = q !== lastQ ? `
${esc(q)}
` : ""; lastQ = q; + const summary = `${what}${hint(sentence)}`; + if (!editing()) return `${header}
${summary}

${esc(sentence)}

`; const base = `tiles.${i}.checks.${j}.`; let fields = (spec.fields || []).filter((f) => !["fix", "type", "template", "params"].includes(f)).map((f) => inputHtml(base + f, F("tiles[].checks[]." + f), chk[f])).join(""); if (chk.type === "remote") { @@ -430,7 +433,7 @@ const fixSel = typeof chk.fix === "object" && chk.fix ? `
fix per device${hint('A table: device → fix, "*" for everything else')}
` : `
fix${hint("What holding the key runs for this check")}
`; const run = typeof chk.fix === "string" && chk.fix && canRunNow(chk.fix) ? `` : ""; - return `
${summary}
${fields}${fixSel} + return `${header}
${summary}
${fields}${fixSel}
more${["tag", "service_only", "debounce_seconds"].filter((f) => !(spec.fields || []).includes(f)).map((f) => inputHtml(base + f, F("tiles[].checks[]." + f), chk[f])).join("")}

type ${esc(chk.type)}

${run}
`; }).join(""); @@ -444,7 +447,7 @@ return `

${esc(t.label)} ${t.pos ? `row ${t.pos[0]}, col ${t.pos[1]}` : "in a group"}

${label}${members}${holdAlways} ${holdList.length ? `
Hold ${esc(hold)}: ${esc(short(holdList[0], 48))}${holdList.length > 1 ? ` +${holdList.length - 1}` : ""}${t.hold_always ? " also when green" : ""}
    ${holdList.map((h) => `
  1. ${esc(h)}
  2. `).join("")}
` : ""} - ${kt.says && kt.says.length ? `
Can say ${kt.says.length} things

${esc(kt.says.join(" · "))}

` : ""} + ${kt.says && kt.says.length ? `
Words it can show ${kt.says.length}

${esc(kt.says.join(" · "))}

` : ""} ${checks ? `
${checks}
` : ""}${addMenu}${more}
`; } function groupBy(obj, fn) { const out = {}; for (const [k, v] of Object.entries(obj)) (out[fn(v)] = out[fn(v)] || []).push(k); return out; } diff --git a/settings/ui/style.css b/settings/ui/style.css index fd51f06..44f8102 100644 --- a/settings/ui/style.css +++ b/settings/ui/style.css @@ -135,3 +135,5 @@ details.script textarea { width: 100%; font-size: .8rem; } .chkbody { margin-top: 6px; } .chkbody .field { grid-template-columns: 1fr; gap: 2px; margin: 4px 0; } .fold { margin: 4px 0; } .fold > summary { color: var(--fg); } .checks { margin-top: 8px; } +.chkgroup { margin: 10px 0 2px; font-size: .78rem; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); } +.chk { margin: 3px 0; }