89 lines
2.6 KiB
TypeScript
89 lines
2.6 KiB
TypeScript
class Radiostasis {
|
|
// audio player
|
|
private readonly player: Player;
|
|
private readonly playlist: Playlist;
|
|
|
|
// ui element
|
|
private readonly main: HTMLElement;
|
|
|
|
private lastSearch: string | null = null;
|
|
private debouncer: number | null = null;
|
|
|
|
constructor() {
|
|
this.playlist = new Playlist();
|
|
this.player = new Player(this.playlist);
|
|
|
|
this.main = document.getElementsByTagName('main').item(0)!;
|
|
|
|
// set up htmx event handlers
|
|
document.addEventListener('htmx:historyRestore', () => this.wireLoadedFragment());
|
|
document.getElementsByTagName('main').item(0)!.addEventListener(
|
|
'htmx:afterSwap', () => this.wireLoadedFragment());
|
|
}
|
|
|
|
private wireLoadedFragment(): void {
|
|
// episode play and queue buttons
|
|
const episodes = this.main.getElementsByClassName('episode');
|
|
for (let i = 0; i < episodes.length; i++) {
|
|
const el = <HTMLElement>episodes.item(i)!;
|
|
const episode: Episode = {
|
|
slug: el.dataset.slug!,
|
|
title: el.getAttribute('title')!,
|
|
file: el.dataset.file!,
|
|
series: {
|
|
slug: el.dataset.sslug!,
|
|
title: el.dataset.series!,
|
|
cover: el.dataset.cover!,
|
|
},
|
|
};
|
|
|
|
// play button
|
|
el.getElementsByTagName('a')[0]!.addEventListener('click', (e) => {
|
|
this.player.playEpisode(episode);
|
|
e.preventDefault();
|
|
});
|
|
|
|
// TODO: queue button
|
|
}
|
|
|
|
// series filter input
|
|
const filter = <HTMLInputElement>this.main
|
|
.getElementsByClassName('filter').item(0);
|
|
|
|
if (filter) {
|
|
if (this.lastSearch) {
|
|
filter.value = this.lastSearch;
|
|
this.lastSearch = null;
|
|
}
|
|
|
|
const allSeries = this.main.getElementsByTagName('section');
|
|
filter.addEventListener('input', () => {
|
|
if (this.debouncer) clearTimeout(this.debouncer);
|
|
this.debouncer = setTimeout(() => {
|
|
this.lastSearch = filter.value.toLowerCase();
|
|
const terms = this.lastSearch.split(' ');
|
|
for (var i = 0; i < allSeries.length; i++) {
|
|
const series = allSeries.item(i)!;
|
|
let match = true;
|
|
for (let term of terms) {
|
|
if (term.length > 0 && series.dataset.filter!.indexOf(term) < 0) {
|
|
match = false;
|
|
break;
|
|
}
|
|
}
|
|
if (match) series.classList.remove('no-match');
|
|
else series.classList.add('no-match');
|
|
}
|
|
}, 499);
|
|
});
|
|
}
|
|
}
|
|
|
|
public initialize(): void {
|
|
const path = location.pathname == '/'
|
|
? '/partial/home.html'
|
|
: `/partial/${location.pathname}.html`;
|
|
htmx.ajax('GET', path, 'main');
|
|
}
|
|
}
|