From 9a3746e6a59fd75c80f261882df918cece5b6a76 Mon Sep 17 00:00:00 2001 From: christian Date: Wed, 14 Oct 2026 18:09:18 -0400 Subject: [PATCH] Auto-fix: Sunday first on the calendar; any fix can be ticked (ticking one that closes a program marks it 'may close') Co-Authored-By: Claude Fable 5.1 --- settings/ui/app.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/settings/ui/app.js b/settings/ui/app.js index 25c77d4..9ba7ac4 100644 --- a/settings/ui/app.js +++ b/settings/ui/app.js @@ -746,9 +746,9 @@
name${hint("As the keys say it")}

` + fieldsHtml("Spotify"); } function autofixHtml(c) { - const fixes = Object.entries(c.fixes).map(([id, f]) => { const cl = closes(f); const on = (c.auto_fix.fixes || []).includes(id); return ``; }).join(" "); + const fixes = Object.entries(c.fixes).map(([id, f]) => { const cl = closes(f); const on = (c.auto_fix.fixes || []).includes(id); return ``; }).join(" "); return `
${calendarHtml("auto_fix.windows", c.auto_fix.windows)}
-

Fixes it may run${hint("Gentle ones only: a fix that closes a program is never run by itself")}

${fixes}
` + fieldsHtml("Schedules"); +

Fixes it may run${hint("Ticked fixes run by themselves inside the painted hours. ⚠ = it closes a running program to do its job; ticking it allows that without a hold.")}

${fixes}
` + fieldsHtml("Schedules"); } // --- the weekly calendar: half-hour cells; click or drag to paint --- const DAYS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]; @@ -776,10 +776,11 @@ } function calendarHtml(path, windows) { const on = cellsOf(windows); - let grid = `
` + DAYS.map((d) => `
${d[0].toUpperCase() + d.slice(1)}
`).join(""); + const SHOW = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"]; + let grid = `
` + SHOW.map((d) => `
${d[0].toUpperCase() + d.slice(1)}
`).join(""); for (let m = 0; m < 1440; m += 30) { grid += `
${m % 120 === 0 ? toHHMM(m) : ""}
`; - for (let d = 0; d < 7; d++) grid += `
`; + for (const name of SHOW) { const d = DAYS.indexOf(name); grid += `
`; } } const words = (windows || []).length ? (windows || []).map((w) => `${(w.days || []).map((d) => d[0].toUpperCase() + d.slice(1)).join(", ")} ${esc(w.start)}–${esc(w.end)}`).join(" · ") : "never"; return `
${grid}
${words}${editing() ? "
Click or drag to paint; drag over painted cells to clear." : ""}
`; @@ -889,7 +890,7 @@ for (const b of main.querySelectorAll("[data-job]")) b.onclick = () => job(b.dataset.job); for (const m of main.querySelectorAll("[data-map]")) m.onchange = () => { if (!m.value || !ensureDraft()) return; const [kind, name] = m.dataset.map.split("|"); (kind === "conn" ? renameConn : renameDante)(name, m.value); saveDraft(); route(); }; for (const b of main.querySelectorAll("[data-addconn]")) b.onclick = () => { const conn = b.dataset.addconn; if (!ensureDraft()) return; const d = state.draft.config; let id = slug(conn) || "key", n = 2; while (d.tiles.some((t) => t.id === id)) id = slug(conn) + "_" + n++; const t = { id, label: conn.toUpperCase().replace(/[_-]+/g, " ").slice(0, 10).trim(), checks: [{ type: "conn", conn, fix: "restart-connection" }] }; const pos = firstEmpty(d, "status"); if (pos) t.pos = pos; d.tiles.push(t); saveDraft(); location.hash = "#keys/" + id; }; - for (const cb of main.querySelectorAll("[data-autofix]")) cb.onchange = () => { if (!ensureDraft()) return; const set = new Set(state.draft.config.auto_fix.fixes || []); cb.checked ? set.add(cb.dataset.autofix) : set.delete(cb.dataset.autofix); setPath("auto_fix.fixes", [...set]); }; + for (const cb of main.querySelectorAll("[data-autofix]")) cb.onchange = () => { if (!ensureDraft()) return; const d = state.draft.config, id = cb.dataset.autofix, f = d.fixes[id]; const set = new Set(d.auto_fix.fixes || []); if (cb.checked) { set.add(id); if (closes(f)) f.restart_ok = true; if (f.never_auto) delete f.never_auto; } else set.delete(id); setPath("auto_fix.fixes", [...set]); }; for (const b of main.querySelectorAll("[data-rmcheck]")) b.onclick = () => confirmBox("Remove this MIDI link from its key?", "Remove", () => { if (!ensureDraft()) return; const [tid, j] = b.dataset.rmcheck.split("|"); const t = state.draft.config.tiles.find((x) => x.id === tid); t.checks.splice(+j, 1); saveDraft(); route(); }); const ds = q("#decksave"); if (ds) ds.onclick = () => applyDecks(main); const dc = () => danteCheck(state.draft.config);