110 lines
3 KiB
JavaScript
110 lines
3 KiB
JavaScript
import { span, popup, shuffle } from '/static/util.js';
|
|
|
|
const music = document.getElementById('music');
|
|
|
|
const audio = document.createElement('audio');
|
|
document.body.appendChild(audio);
|
|
|
|
function addButton(text, cb) {
|
|
// insane jank because the pause/play unicode symbols are not the same width
|
|
const d = document.createElement('div');
|
|
d.className = 'fa'
|
|
const l = span('[');
|
|
const m = span(text);
|
|
const r = span(']');
|
|
l.className = 'usn';
|
|
r.className = 'usn';
|
|
d.appendChild(l);
|
|
d.appendChild(m);
|
|
d.appendChild(r);
|
|
music.appendChild(d);
|
|
d.onclick = d.onkeydown = cb;
|
|
d.tabIndex = 0;
|
|
return d;
|
|
}
|
|
function addVolume(n) {
|
|
const vol = document.createElement('div');
|
|
const chars = [];
|
|
vol.id = 'vol'
|
|
const l = span('[');
|
|
let drag = false;
|
|
document.addEventListener('mouseup', () => drag = false);
|
|
function setVol(v) {
|
|
return function (e) {
|
|
if (e && e.type === 'keydown' && e.key != 'Enter') return;
|
|
if (e && e.type === 'mouseenter' && (!(e.buttons & 1) || !drag)) return;
|
|
if (e && e.type === 'mousedown') {
|
|
drag = true;
|
|
e.preventDefault();
|
|
}
|
|
audio.volume = (v / n) ** 2;
|
|
localStorage.setItem('volume', v)
|
|
for (let i = 0; i < n; i++) {
|
|
chars[i].textContent = i < v ? '+' : '-';
|
|
}
|
|
};
|
|
}
|
|
l.onmouseenter = l.onmousedown = l.onkeydown = setVol(0);
|
|
l.tabIndex = 0;
|
|
vol.appendChild(l);
|
|
for (let i = 1; i <= n; i++) {
|
|
let x = span('+');
|
|
chars.push(x);
|
|
x.onmouseenter = x.onmousedown = x.onkeydown = setVol(i);
|
|
x.tabIndex = 0;
|
|
vol.appendChild(x);
|
|
}
|
|
const r = span(']');
|
|
r.onmouseenter = r.onmousedown = r.onkeydown = setVol(n);
|
|
r.tabIndex = 0;
|
|
l.className = r.className = 'usn';
|
|
vol.appendChild(r);
|
|
setVol(Number(localStorage.getItem('volume') ?? Math.ceil(n / 2)))();
|
|
music.appendChild(vol);
|
|
}
|
|
let songs = [];
|
|
function playSong() {
|
|
fetch('/static/songlist.json').then(e => e.json()).then(e => {
|
|
songs = e;
|
|
shuffle(songs);
|
|
playSong = _playSong;
|
|
_playSong()
|
|
});
|
|
}
|
|
let n = 0;
|
|
function _playSong() {
|
|
let song = songs[n] ?? songs[n = 0];
|
|
audio.src = song.href;
|
|
popup(song.src
|
|
? `\u266b - ${song.src} (${song.artist}) - ${song.name}`
|
|
: `\u266b - ${song.artist} - ${song.name}`);
|
|
audio.play();
|
|
play.children[1].textContent = '\u23F8'
|
|
}
|
|
addButton('\u23EE', (e) => {
|
|
if (e && e.type === 'keydown' && e.key != 'Enter') return;
|
|
playSong(--n);
|
|
});
|
|
let play = addButton('\u23F5', (e) => {
|
|
if (e && e.type === 'keydown' && e.key != 'Enter') return;
|
|
const target = e.target.localName === 'span' ? e.target.parentElement.children[1] : e.target.children[1];
|
|
if (audio.paused) {
|
|
if (!audio.src) {
|
|
playSong(n);
|
|
audio.addEventListener('ended', e => {
|
|
playSong(++n);
|
|
});
|
|
}
|
|
audio.play();
|
|
target.textContent = '\u23F8';
|
|
} else {
|
|
audio.pause();
|
|
target.textContent = '\u23F5';
|
|
}
|
|
});
|
|
addButton('\u23EF', (e) => {
|
|
if (e && e.type === 'keydown' && e.key != 'Enter') return;
|
|
playSong(++n);
|
|
});
|
|
addVolume(5);
|