async function post(action, body = {}) { try { await fetch(`/api/windows/${action}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }); } catch { // the next poll shows the real state } } function button(label, onclick) { const b = document.createElement("button"); b.textContent = label; b.onclick = onclick; return b; } export default { title: "Windows", interval: 1, mount(el) { const box = document.createElement("div"); box.className = "windows"; box.innerHTML = `
`; el.append(box); }, update(st, el) { const box = el.querySelector(".windows"); const ws = box.querySelector(".ws"); ws.textContent = ""; for (const id of st.workspaces ?? []) { const b = button(String(id), () => post("workspace", { n: id })); b.classList.toggle("on", (st.windows ?? []).some((w) => w.workspace === id)); ws.append(b); } const list = box.querySelector(".winlist"); list.textContent = ""; for (const w of (st.windows ?? []).slice(0, 12)) { const row = document.createElement("div"); row.className = "row"; row.classList.toggle("on", Boolean(w.active)); const title = document.createElement("span"); title.className = "wt"; title.textContent = w.title || w.class; title.onclick = () => post("focus", { address: w.address }); row.append(title, button("×", () => post("close", { address: w.address }))); list.append(row); } const launches = box.querySelector(".launches"); launches.textContent = ""; for (const key of st.launches ?? []) { launches.append(button(key, () => post("launch", { key }))); } }, };