Mercurial > code > home > repos > light9
diff web/ascoltami/main.ts @ 2376:4556eebe5d73
topdir reorgs; let pdm have its src/ dir; separate vite area from light9/
author | drewp@bigasterisk.com |
---|---|
date | Sun, 12 May 2024 19:02:10 -0700 |
parents | light9/web/ascoltami/main.ts@06bf6dae8e64 |
children | cc69faa87c27 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/ascoltami/main.ts Sun May 12 19:02:10 2024 -0700 @@ -0,0 +1,100 @@ +function byId(id: string): HTMLElement { + return document.getElementById(id)!; +} + +export interface TimingUpdate { + // GET /ascoltami/time response + duration: number; + next: string; // e.g. 'play' + playing: boolean; + song: string; + started: number; // unix sec + t: number; // seconds into song + state: { current: { name: string }; pending: { name: string } }; +} + +(window as any).finishOldStyleSetup = async (times: { intro: number; post: number }, timingUpdate: (data: TimingUpdate) => void) => { + let currentHighlightedSong = ""; + // let lastPlaying = false; + + + const events = new EventSource("../service/ascoltami/time/stream"); + events.addEventListener("message", (m)=>{ + const update = JSON.parse(m.data) as TimingUpdate + updateCurrent(update) + markUpdateTiming(); + }) + + async function updateCurrent(data:TimingUpdate) { + byId("currentSong").innerText = data.song; + if (data.song != currentHighlightedSong) { + showCurrentSong(data.song); + } + byId("currentTime").innerText = data.t.toFixed(1); + byId("leftTime").innerText = (data.duration - data.t).toFixed(1); + byId("leftAutoStopTime").innerText = Math.max(0, data.duration - times.post - data.t).toFixed(1); + byId("states").innerText = JSON.stringify(data.state); + // document.querySelector("#timeSlider").slider({ value: data.t, max: data.duration }); + timingUpdate(data); + } + let recentUpdates: Array<number> = []; + function markUpdateTiming() { + recentUpdates.push(+new Date()); + recentUpdates = recentUpdates.slice(Math.max(recentUpdates.length - 5, 0)); + } + + function refreshUpdateFreqs() { + if (recentUpdates.length > 1) { + if (+new Date() - recentUpdates[recentUpdates.length - 1] > 1000) { + byId("updateActual").innerText = "(stalled)"; + return; + } + + var avgMs = (recentUpdates[recentUpdates.length - 1] - recentUpdates[0]) / (recentUpdates.length - 1); + byId("updateActual").innerText = "" + Math.round(1000 / avgMs); + } + } + setInterval(refreshUpdateFreqs, 2000); + + function showCurrentSong(uri: string) { + document.querySelectorAll(".songs div").forEach((row: Element, i: number) => { + if (row.querySelector("button")!.dataset.uri == uri) { + row.classList.add("currentSong"); + } else { + row.classList.remove("currentSong"); + } + }); + currentHighlightedSong = uri; + } + + const data = await (await fetch("api/songs")).json(); + data.songs.forEach((song: { uri: string; label: string }) => { + const button = document.createElement("button"); + // link is just for dragging, not clicking + const link = document.createElement("a"); + const n = document.createElement("span"); + n.classList.add("num"); + n.innerText = song.label.slice(0, 2); + link.appendChild(n); + + const sn = document.createElement("span"); + sn.classList.add("song-name"); + sn.innerText = song.label.slice(2).trim(); + link.appendChild(sn); + link.setAttribute("href", song.uri); + link.addEventListener("click", (ev) => { + ev.stopPropagation(); + button.click(); + }); + button.appendChild(link); + button.dataset.uri = song.uri; + button.addEventListener("click", async (ev) => { + await fetch("api/song", { method: "POST", body: song.uri }); + showCurrentSong(song.uri); + }); + const dv = document.createElement("div"); + dv.appendChild(button); + document.querySelector(".songs")!.appendChild(dv); + }); + +};