-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
109 lines (88 loc) · 3.5 KB
/
index.js
File metadata and controls
109 lines (88 loc) · 3.5 KB
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import '@picocss/pico';
import './css/custom.css';
import shuffleLetters from 'shuffle-letters';
import stations from './stations/stations';
import {o,html} from 'sinuous';
import {subscribe} from 'sinuous/observable';
import Sun from './icons/sun';
import Moon from './icons/moon';
import Play from './icons/play';
import Pause from './icons/pause';
import PlayAnim from './components/play_animation';
const loading = html`<span aria-busy="true"></span>`;
const App = () => {
let isLight = true,
theme = o('light');
playBtn = o(Play),
source = o(stations[0].stream),
station = o(stations[0].name),
vol = o(.25),
showVol = o(Math.floor(vol() * 100)),
icon = o(isLight? Sun : Moon),
anim = o(null);
document.title = station();
subscribe(() => {
document.documentElement.setAttribute('data-theme', `${theme()}`);
});
const toggleTheme = (e) => {
e.preventDefault();
isLight = !isLight;
theme(isLight? 'light':'dark');
icon(isLight? Sun : Moon);
}
const changeStation = (e) => {
e.preventDefault();
anim(null);
player.pause();
source(e.target.getAttribute('data-source'));
station(e.target.getAttribute('data-name'));
player.src = source();
document.title = station();
shuffleLetters(document.querySelector('li strong'),{
iterations: 12,
fps: 60,
onComplete: () => {
play();
}
});
}
const changeVolume = (e) => {
e.preventDefault();
vol(e.target.value);
showVol(Math.floor(vol() * 100));
player.volume = vol();
document.title = `${station()} | vol. ${showVol()} %`;
}
const changeAnim = (e) => {
e.preventDefault();
player.volume < 0.01 ? anim(null)
: !player.paused ? anim(PlayAnim)
: anim(null);
}
const playRadio = (e) => {
e.preventDefault();
play();
}
const play = () => {
if(player.paused) {
player.readyState < 2 ? anim(loading) : anim(null);
player.play();
player.onplaying = () => {
playBtn(Pause);
player.volume > 0.01 ? anim(PlayAnim) : anim(null);
}
} else {
player.pause();
player.onpause = () => {
playBtn(Play);
anim(null);
}
}
}
const radio = html`<article><nav><ul><li><a href="#" onclick=${playRadio} data-play>${playBtn}</a></li><li><strong>${station}</strong></li>${anim}</ul><ul><li><a href="#" onclick=${toggleTheme}>${icon}</a></li></ul></nav><audio src=${source} preload="none"/><input type="range" min="0.00" max="1.00" step=".01" value=${vol} oninput=${changeVolume} onchange=${changeAnim} id="volume" name="volume" data-tooltip="vol.${showVol} %" /><details><summary>stations</summary><section><ul>${() => stations.map(s => html`<li><a href="#" data-source="${s.stream}" data-name="${s.name}" onclick=${changeStation}>${s.name}</a> <sup><mark>${s.category}</mark></sup></li>`)}</ul></section><label>volume ${showVol} %</label></details></article>`;
const view = html`<main class="container"><${radio}/></main>`;
return view;
};
document.body.append(html`<${App}/>`);
const player = document.querySelector('audio');
player.volume = vol();