annotate web/ascoltami/main.ts @ 2427:cc69faa87c27

tear up and rewrite ascoltami to emit player state into the graph. web ui works but displays nothing but songs
author drewp@bigasterisk.com
date Sat, 25 May 2024 15:44:11 -0700
parents 4556eebe5d73
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2053
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
1 function byId(id: string): HTMLElement {
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
2 return document.getElementById(id)!;
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
3 }
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
4
2427
cc69faa87c27 tear up and rewrite ascoltami to emit player state into the graph. web ui works but displays nothing but songs
drewp@bigasterisk.com
parents: 2376
diff changeset
5 // obsolete: watch the graph instead
2124
eb5d8349c871 pass timing updates in a simpler way
drewp@bigasterisk.com
parents: 2123
diff changeset
6 export interface TimingUpdate {
eb5d8349c871 pass timing updates in a simpler way
drewp@bigasterisk.com
parents: 2123
diff changeset
7 // GET /ascoltami/time response
eb5d8349c871 pass timing updates in a simpler way
drewp@bigasterisk.com
parents: 2123
diff changeset
8 duration: number;
eb5d8349c871 pass timing updates in a simpler way
drewp@bigasterisk.com
parents: 2123
diff changeset
9 next: string; // e.g. 'play'
eb5d8349c871 pass timing updates in a simpler way
drewp@bigasterisk.com
parents: 2123
diff changeset
10 playing: boolean;
eb5d8349c871 pass timing updates in a simpler way
drewp@bigasterisk.com
parents: 2123
diff changeset
11 song: string;
eb5d8349c871 pass timing updates in a simpler way
drewp@bigasterisk.com
parents: 2123
diff changeset
12 started: number; // unix sec
eb5d8349c871 pass timing updates in a simpler way
drewp@bigasterisk.com
parents: 2123
diff changeset
13 t: number; // seconds into song
eb5d8349c871 pass timing updates in a simpler way
drewp@bigasterisk.com
parents: 2123
diff changeset
14 state: { current: { name: string }; pending: { name: string } };
eb5d8349c871 pass timing updates in a simpler way
drewp@bigasterisk.com
parents: 2123
diff changeset
15 }
eb5d8349c871 pass timing updates in a simpler way
drewp@bigasterisk.com
parents: 2123
diff changeset
16
2360
6c6b29d21959 carefully rm parameter
drewp@bigasterisk.com
parents: 2311
diff changeset
17 (window as any).finishOldStyleSetup = async (times: { intro: number; post: number }, timingUpdate: (data: TimingUpdate) => void) => {
2053
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
18 let currentHighlightedSong = "";
2123
c4427fd59306 port some of ascoltami into lit
drewp@bigasterisk.com
parents: 2114
diff changeset
19 // let lastPlaying = false;
2050
7ed414bdaab9 wip porting asco to TS and not-jquery
drewp@bigasterisk.com
parents:
diff changeset
20
2311
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
21
2427
cc69faa87c27 tear up and rewrite ascoltami to emit player state into the graph. web ui works but displays nothing but songs
drewp@bigasterisk.com
parents: 2376
diff changeset
22 const events = new EventSource("/service/ascoltami/time/stream");
2311
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
23 events.addEventListener("message", (m)=>{
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
24 const update = JSON.parse(m.data) as TimingUpdate
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
25 updateCurrent(update)
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
26 markUpdateTiming();
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
27 })
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
28
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
29 async function updateCurrent(data:TimingUpdate) {
2053
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
30 byId("currentSong").innerText = data.song;
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
31 if (data.song != currentHighlightedSong) {
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
32 showCurrentSong(data.song);
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
33 }
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
34 byId("currentTime").innerText = data.t.toFixed(1);
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
35 byId("leftTime").innerText = (data.duration - data.t).toFixed(1);
2123
c4427fd59306 port some of ascoltami into lit
drewp@bigasterisk.com
parents: 2114
diff changeset
36 byId("leftAutoStopTime").innerText = Math.max(0, data.duration - times.post - data.t).toFixed(1);
2053
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
37 byId("states").innerText = JSON.stringify(data.state);
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
38 // document.querySelector("#timeSlider").slider({ value: data.t, max: data.duration });
2124
eb5d8349c871 pass timing updates in a simpler way
drewp@bigasterisk.com
parents: 2123
diff changeset
39 timingUpdate(data);
2053
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
40 }
2311
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
41 let recentUpdates: Array<number> = [];
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
42 function markUpdateTiming() {
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
43 recentUpdates.push(+new Date());
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
44 recentUpdates = recentUpdates.slice(Math.max(recentUpdates.length - 5, 0));
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
45 }
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
46
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
47 function refreshUpdateFreqs() {
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
48 if (recentUpdates.length > 1) {
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
49 if (+new Date() - recentUpdates[recentUpdates.length - 1] > 1000) {
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
50 byId("updateActual").innerText = "(stalled)";
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
51 return;
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
52 }
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
53
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
54 var avgMs = (recentUpdates[recentUpdates.length - 1] - recentUpdates[0]) / (recentUpdates.length - 1);
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
55 byId("updateActual").innerText = "" + Math.round(1000 / avgMs);
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
56 }
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
57 }
a10f0f0e4dae update web ui with one SSE, not repeated requests
drewp@bigasterisk.com
parents: 2124
diff changeset
58 setInterval(refreshUpdateFreqs, 2000);
2053
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
59
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
60 function showCurrentSong(uri: string) {
2123
c4427fd59306 port some of ascoltami into lit
drewp@bigasterisk.com
parents: 2114
diff changeset
61 document.querySelectorAll(".songs div").forEach((row: Element, i: number) => {
c4427fd59306 port some of ascoltami into lit
drewp@bigasterisk.com
parents: 2114
diff changeset
62 if (row.querySelector("button")!.dataset.uri == uri) {
c4427fd59306 port some of ascoltami into lit
drewp@bigasterisk.com
parents: 2114
diff changeset
63 row.classList.add("currentSong");
c4427fd59306 port some of ascoltami into lit
drewp@bigasterisk.com
parents: 2114
diff changeset
64 } else {
c4427fd59306 port some of ascoltami into lit
drewp@bigasterisk.com
parents: 2114
diff changeset
65 row.classList.remove("currentSong");
c4427fd59306 port some of ascoltami into lit
drewp@bigasterisk.com
parents: 2114
diff changeset
66 }
c4427fd59306 port some of ascoltami into lit
drewp@bigasterisk.com
parents: 2114
diff changeset
67 });
2053
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
68 currentHighlightedSong = uri;
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
69 }
b7a3dff5514d rough and untested port of asco from jquery to vanilla
drewp@bigasterisk.com
parents: 2050
diff changeset
70
2058
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
71 const data = await (await fetch("api/songs")).json();
2123
c4427fd59306 port some of ascoltami into lit
drewp@bigasterisk.com
parents: 2114
diff changeset
72 data.songs.forEach((song: { uri: string; label: string }) => {
2058
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
73 const button = document.createElement("button");
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
74 // link is just for dragging, not clicking
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
75 const link = document.createElement("a");
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
76 const n = document.createElement("span");
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
77 n.classList.add("num");
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
78 n.innerText = song.label.slice(0, 2);
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
79 link.appendChild(n);
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
80
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
81 const sn = document.createElement("span");
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
82 sn.classList.add("song-name");
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
83 sn.innerText = song.label.slice(2).trim();
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
84 link.appendChild(sn);
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
85 link.setAttribute("href", song.uri);
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
86 link.addEventListener("click", (ev) => {
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
87 ev.stopPropagation();
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
88 button.click();
2050
7ed414bdaab9 wip porting asco to TS and not-jquery
drewp@bigasterisk.com
parents:
diff changeset
89 });
2058
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
90 button.appendChild(link);
2114
758ce4dfbd2f asco layout
drewp@bigasterisk.com
parents: 2058
diff changeset
91 button.dataset.uri = song.uri;
2058
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
92 button.addEventListener("click", async (ev) => {
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
93 await fetch("api/song", { method: "POST", body: song.uri });
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
94 showCurrentSong(song.uri);
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
95 });
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
96 const dv = document.createElement("div");
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
97 dv.appendChild(button);
2123
c4427fd59306 port some of ascoltami into lit
drewp@bigasterisk.com
parents: 2114
diff changeset
98 document.querySelector(".songs")!.appendChild(dv);
2058
16c7dd543250 asco web: fix more porting bugs. UI might work (except for time slider)
drewp@bigasterisk.com
parents: 2053
diff changeset
99 });
2050
7ed414bdaab9 wip porting asco to TS and not-jquery
drewp@bigasterisk.com
parents:
diff changeset
100
2123
c4427fd59306 port some of ascoltami into lit
drewp@bigasterisk.com
parents: 2114
diff changeset
101 };