-
Notifications
You must be signed in to change notification settings - Fork 13
/
index.html
69 lines (69 loc) · 3.89 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<!doctype html>
<html lang=en>
<meta name="viewport" content="width=device-width, user-scalable=no">
<script type=module>
const $$ = document.querySelectorAll.bind(document);
const el = (tag, props={}, ch=[]) => ch.reduce((e,c) => (e.appendChild(c),e),Object.assign(document.createElement(tag),props))
const api = (path, callback=`cb_${+new Date()}`) => new Promise(function(ok, ko) {
window[callback] = (data) => {delete window[callback]; data?.error?ko(data.error):ok(data)};
const src = new URL(`https://api.deezer.com/${path}`);
src.searchParams.append('output','jsonp');
src.searchParams.append('callback',callback);
document.head.append(el('script', { src, onload:({target})=>target.parentNode.removeChild(target)}));
});
const rel = (h) => h.startsWith('/') ? h : `${location.hash.slice(1)}/${h}`
const list = (tags) => document.forms.results.replaceChildren(...tags.map(([tag, props]) => el(tag, {innerText:props?.href, ...props, href:`#${rel(props.href)}`})))
const toLink = (...links) => links.map(href => ['a', {href}])
const routes = {
'' : (_) => list(toLink('/search/track?q=','/search/artist?q=','/search/album?q=','/search/playlist?q=','/search/radio?q=','/search/user?q=','/user/0','/genre','/radio')),
genre_0: (_) => list(toLink('radios','artists')),
radio_0: (_) => list(toLink('tracks', 'fans')),
album_0: (_) => list(toLink('tracks', 'fans')),
user_0: (_) => list(toLink('charts','albums','playlist','flow','tracks','artists')),
artist_0:(_) => list(toLink('top?limit=50','albums','fans','related','radio','playlist')),
default: async (h) => list( (await api(h)).data.map(d => ['a', {
href:`/${d.type}/${d.id}`,
innerText: `${d.title||d.name} ${d.artist?.name||''}`
}]) )
};
const modes = {
none: (p) => {},
replay: (p) => p.play(),
random: (p) => window.onhashchange({newURL:$$('a[href^="#/track/"]')[0].href}),
next: (p) => window.onhashchange({newURL:$$(`a[href="${p.dataset.href}"]`)[0].nextElementSibling.href}),
}
window.onhashchange = function(event) {
const newurl = new URL(event.newURL);
const path = newurl.hash.replace(/#?\/?/,'');
if (path.endsWith('=')||path.endsWith('/0'))
return location.hash += prompt(`query for ${path}`);
if (path.startsWith('track')){
if(!window.cgi.value) return alert('No dzr cgi url detected! (is dzr running as cgi ?)\nplease manually set it up in options');
window.player.src = `${window.cgi.value}?`+newurl.hash.match(/\d+/);
window.player.dataset.href = newurl.hash; // to find it back in next track
window.document.title = path;
return location.hash = (new URL(event.oldURL||location)).hash; // don't change URL
}
const route = path.replace(/[,?].*/,'').replace(/[^a-zA-Z0-9]+/g,'_').replace(/[0-9,]+/g,'0').replace(/_+/g,'_');
(routes[route]||routes.default)(path);
}
window.onload = function() {
window.player.onended = ()=>modes[window.mode.value](window.player);
window.https.hidden = location.protocol=='http:';
if (localStorage.dzr_mode) window.mode.value = localStorage.dzr_mode;
if (localStorage.dzr_cgi) window.cgi.value = localStorage.dzr_cgi;
else ['/cgi-bin/dzr', '//0.0.0.0:8000/cgi-bin/dzr', '//127.0.0.1:8000/cgi-bin/dzr', '//localhost:8000/cgi-bin/dzr']
.forEach(url => fetch(url,{method:'HEAD'}).then(e=>e.ok ? window.cgi.value = localStorage.dzr_cgi = url:0))
window.onhashchange({newURL:`${location}`});
}
</script>
<body style="margin-bottom:100px;font-size:2em;font-family:monospace">
<cite id=https>Warning: dzr don't normaly use https, please downgrade to http://</cite>
<details style="display: grid">
<summary>Options</summary>
<label>dzr cgi url: <input id="cgi" placeholder="http://example:8000/cgi-bin/dzr"></label>
<label>next track: <select id="mode" onchange="localStorage.dzr_mode=value"><option>none<option>replay<option>random<option>next</select></label>
</details>
<form name=results style="display: grid"></form>
<audio id="player" autoplay controls style="position:fixed;bottom:0;left:0;width:100%"></audio>
</body>