async function post(action) { try { await fetch(`/api/music/${action}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: "{}", }); } catch { // the next poll shows the real state } } function button(label, action) { const b = document.createElement("button"); b.textContent = label; b.onclick = () => post(action); return b; } export default { title: "Music", interval: 2, mount(el) { const box = document.createElement("div"); box.className = "music"; box.innerHTML = `
—
`; box.querySelector(".controls").append( button("⏮", "prev"), button("⏯", "play"), button("⏭", "next")); box.querySelector(".vol").append( button("Vol−", "voldown"), button("Mute", "mute"), button("Vol+", "volup")); el.append(box); }, update(st, el) { const box = el.querySelector(".music"); box.querySelector(".title").textContent = st.title || "Nothing playing"; box.querySelector(".artist").textContent = st.artist || ""; box.querySelector(".controls button:nth-child(2)").textContent = st.status === "Playing" ? "⏸" : "▶"; const mute = box.querySelector(".vol button:nth-child(2)"); mute.classList.toggle("on", Boolean(st.volume?.muted)); mute.textContent = st.volume?.muted ? "Unmute" : "Mute"; }, };