1
0
dwelling-radio/web/assets/js/main.js

106 lines
3.7 KiB
JavaScript

const $ = id => document.getElementById(id);
const formatDuration = date => `${date.getUTCHours() > 0 ? date.getUTCHours() + ":" : ""}${date.getUTCMinutes()}:${date.getUTCSeconds().toString().padStart(2, "0")}`;
const formatStartAt = date => `${date.getHours().toString().padStart(2, "0")}:${date.getMinutes().toString().padStart(2, "0")}`;
let cursong_startat = null;
let cursong_duration_msec = 0;
async function updateStatus() {
const resp = await fetch("/api/status");
if (!resp.ok || 200 != resp.status) {
$("radio-song").textContent =
$("radio-duration-estimate").textContent =
$("radio-duration").textContent = "";
$("radio-listeners").textContent =
$("radio-listener-peak").textContent = "0";
$("last-songs").firstChild.remove();
return [-1, null];
}
const s = await resp.json();
if (undefined != s.most_listened_song) {
$("radio-mls-song").textContent = s.most_listened_song.song;
$("radio-mls-listeners").textContent = s.most_listened_song.listeners;
$("radio-mls-date").textContent = (new Intl.DateTimeFormat('en-GB',
{timeStyle: "long",
dateStyle: "long",
timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone}))
.format(new Date(s.most_listened_song.date))
}
if (undefined == s.current_song)
return [-1, null];
$("radio-song").textContent = `${s.current_song.artist} - ${s.current_song.title}`;
$("radio-duration").textContent = formatDuration(new Date(s.current_song.duration_msec));
$("radio-listeners").textContent = s.listeners.current;
$("radio-listener-peak").textContent = s.listeners.peak;
if (undefined != s.last_songs) {
$("last-songs").firstChild.remove();
$("last-songs").appendChild(document.createElement("tbody"));
for (let i = 0; i < s.last_songs.length; ++i) {
let row = $("last-songs").insertRow();
row.insertCell().appendChild(document.createTextNode(formatStartAt(new Date(s.last_songs[i].start_at))));
row.insertCell().appendChild(document.createTextNode(s.last_songs[i].listeners == 0 ? "" : s.last_songs[i].listeners));
row.insertCell().appendChild(document.createTextNode(`${s.last_songs[i].artist} - ${s.last_songs[i].title}`));
}
}
return [s.current_song.duration_msec, new Date(s.current_song.start_at)];
}
async function update() {
if (null === cursong_startat)
return -1;
const estimate = (new Date()) - (new Date(cursong_startat));
if (estimate >= cursong_duration_msec) {
return 1;
}
$("radio-duration-estimate").textContent = `${formatDuration(new Date(estimate))} / `;
return 0;
}
$("radio-update").addEventListener("click", async () =>
[cursong_duration_msec, cursong_startat] = await updateStatus());
let update_interval_id = null;
async function interval() {
switch (await update()) {
case 1:
[cursong_duration_msec, cursong_startat] = await updateStatus();
break;
case -1:
clearInterval(update_interval_id);
await new Promise(resolve => setTimeout(resolve, 5000));
[cursong_duration_msec, cursong_startat] = await updateStatus();
update_interval_id = setInterval(interval, 1000);
}
}
updateStatus().then(r => [cursong_duration_msec, cursong_startat] = r);
update_interval_id = setInterval(interval, 1000);
const audio = document.getElementsByTagName("audio")[0];
audio.hidden = true;
const audio_src = audio.childNodes[0].src;
const volume = $("radio-volume");
audio.volume = volume.value / 100.0;
volume.addEventListener("input", e => audio.volume = e.target.value / 100.0);
$("player").style.display = $("player").firstChild.style.display = "flex";
$("radio-play").addEventListener("click", e => {
audio.paused ? (audio.src = audio_src) && audio.play() : audio.src = "";
e.target.style.maskImage = e.target.style.webkitMaskImage = audio.paused ?
"url(/assets/img/play.svg)" : "url(/assets/img/stop.svg)"; });