2020-04-07 21:44:46 +02:00
|
|
|
class Player {
|
|
|
|
async init() {
|
2020-08-01 21:51:54 +02:00
|
|
|
this.playlist = new Playlist();
|
|
|
|
}
|
|
|
|
|
|
|
|
nextSong() {
|
|
|
|
let next = this.playlist.getNext();
|
2020-08-06 23:44:37 +02:00
|
|
|
audioHandler.loadSong(next);
|
2020-08-01 21:51:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
prevSong() {
|
|
|
|
let next = this.playlist.getPrevious();
|
2020-08-06 23:44:37 +02:00
|
|
|
audioHandler.loadSong(next);
|
2020-08-01 21:51:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
playStop() {
|
|
|
|
if (!audioHandler.lastSong) {
|
|
|
|
let next = this.playlist.getCurrent();
|
2020-08-06 23:44:37 +02:00
|
|
|
audioHandler.loadSong(next);
|
2020-08-05 11:24:59 +02:00
|
|
|
return;
|
2020-08-01 21:51:54 +02:00
|
|
|
}
|
|
|
|
let audioFile = audioHandler.audioFile;
|
|
|
|
if (audioFile.paused) {
|
|
|
|
audioFile.play();
|
|
|
|
} else {
|
|
|
|
audioFile.pause();
|
|
|
|
}
|
2020-08-05 11:24:59 +02:00
|
|
|
window.dispatchEvent(new CustomEvent('playSong'));
|
2020-08-01 21:51:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
playByID(number) {
|
2020-08-05 11:24:59 +02:00
|
|
|
this.playlist.index = number;
|
|
|
|
let next = this.playlist.getCurrent();
|
2020-08-06 23:44:37 +02:00
|
|
|
audioHandler.loadSong(next);
|
2020-08-01 21:51:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const PAGINATIONLIMIT = 50;
|
|
|
|
|
|
|
|
class Playlist {
|
|
|
|
constructor() {
|
|
|
|
this.list = [];
|
|
|
|
this.shuffled = [];
|
|
|
|
this.index = 0;
|
|
|
|
this.page = 0;
|
2020-08-07 19:31:30 +02:00
|
|
|
this.isShuffle = pConf.get("shuffle", false);
|
2020-08-01 21:51:54 +02:00
|
|
|
$('body').addDelegatedEventListener('change', 'input[type="file"]', this.changeFiles.bind(this));
|
|
|
|
$('body').addDelegatedEventListener('click', '.pagination .item', this.handlePagination.bind(this));
|
2020-08-06 23:44:37 +02:00
|
|
|
eventHandler.addEvent('id3-request', this.handle.bind(this));
|
|
|
|
eventHandler.addEvent('id3-request-force', this.forceID3.bind(this));
|
2020-08-01 21:51:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
shuffle() {
|
|
|
|
// only shuffle if more then 2 elements are in
|
|
|
|
let len = this.list.length;
|
|
|
|
if (len < 3) {
|
2020-08-06 23:44:37 +02:00
|
|
|
this.shuffled = [0, 1, 2];
|
|
|
|
return;
|
2020-08-01 21:51:54 +02:00
|
|
|
}
|
|
|
|
// the current-list need to be shuffled...
|
|
|
|
for (let i = 0; i < len; i++) {
|
|
|
|
let random = VTUtils.randomInt(0, len - 1);
|
|
|
|
this.swap(i, random);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
swap(a, b) {
|
2020-08-06 23:44:37 +02:00
|
|
|
this.shuffled[a] = b;
|
|
|
|
this.shuffled[b] = a;
|
2020-08-01 21:51:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
getNext() {
|
2020-08-06 23:44:37 +02:00
|
|
|
let items = this.list,
|
2020-08-01 21:51:54 +02:00
|
|
|
len = items.length - 1,
|
|
|
|
next = this.index + 1;
|
|
|
|
if (next > len) {
|
|
|
|
next = 0;
|
|
|
|
}
|
|
|
|
this.index = next;
|
2020-08-06 23:44:37 +02:00
|
|
|
return items[this.getRealIndex()];
|
2020-08-01 21:51:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
getPrevious() {
|
2020-08-06 23:44:37 +02:00
|
|
|
let items = this.list,
|
2020-08-01 21:51:54 +02:00
|
|
|
len = items.length - 1,
|
|
|
|
next = this.index - 1;
|
|
|
|
if (next < 0) {
|
|
|
|
next = len;
|
|
|
|
}
|
|
|
|
this.index = next;
|
2020-08-06 23:44:37 +02:00
|
|
|
return items[this.getRealIndex()];
|
2020-08-01 21:51:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
getCurrent() {
|
2020-08-06 23:44:37 +02:00
|
|
|
return this.list[this.getRealIndex()];
|
2020-08-01 21:51:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// on new upload... this has to be an array!
|
|
|
|
setPlaylist(files) {
|
|
|
|
this.index = 0;
|
2020-08-06 23:44:37 +02:00
|
|
|
this.forceData = undefined;
|
2020-08-01 21:51:54 +02:00
|
|
|
this.list = files;
|
|
|
|
this.shuffle();
|
|
|
|
}
|
|
|
|
|
|
|
|
handlePagination(event, el) {
|
|
|
|
if (el.hasClass('inactive')) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (el.hasClass('next-site')) {
|
|
|
|
this.renderPagination(this.page + 1);
|
|
|
|
} else {
|
|
|
|
this.renderPagination(this.page - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
renderPagination(page) {
|
2020-08-06 23:44:37 +02:00
|
|
|
if (page === undefined) {
|
|
|
|
page = this.page;
|
|
|
|
}
|
2020-08-01 21:51:54 +02:00
|
|
|
let length = this.list.length,
|
|
|
|
maxSite = Math.ceil(length / PAGINATIONLIMIT) - 1;
|
|
|
|
if (page < 0) {
|
|
|
|
page = 0;
|
|
|
|
}
|
|
|
|
if (page > maxSite) {
|
|
|
|
page = maxSite;
|
|
|
|
}
|
|
|
|
let s = page * PAGINATIONLIMIT,
|
|
|
|
e = s + PAGINATIONLIMIT,
|
|
|
|
data = "";
|
|
|
|
this.page = page;
|
|
|
|
if (e >= length) {
|
|
|
|
e = length;
|
|
|
|
}
|
|
|
|
if (length > 0) {
|
2020-08-06 23:44:37 +02:00
|
|
|
let items = this.list;
|
2020-08-01 21:51:54 +02:00
|
|
|
for (let i = s; i < e; i++) {
|
|
|
|
let obj = {
|
2020-08-05 11:24:59 +02:00
|
|
|
index: i.toString(),
|
2020-08-01 21:51:54 +02:00
|
|
|
nr: i + 1,
|
2020-08-06 23:44:37 +02:00
|
|
|
title: items[this.getRealIndex(i)].getAudioName(),
|
2020-08-05 11:24:59 +02:00
|
|
|
active: !audioHandler.audioFile.paused && i === this.index ? 'active' : ''
|
2020-08-01 21:51:54 +02:00
|
|
|
}
|
|
|
|
data += template.parseTemplate("playlist-item", obj);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
data = "<h1>No Songs uploaded!</h1>";
|
|
|
|
}
|
|
|
|
let hasNext = maxSite > 1 && page < maxSite;
|
|
|
|
gui.modal.renderModal(
|
|
|
|
"Playlist",
|
|
|
|
template.parseTemplate("playlist", {
|
|
|
|
content: data,
|
|
|
|
}),
|
|
|
|
template.parseTemplate('playlist-footer', {
|
|
|
|
prevActive: page > 0 ? 'active' : 'inactive',
|
|
|
|
nextActive: hasNext ? 'active' : 'inactive',
|
|
|
|
page: (page + 1) + ' / ' + parseInt(maxSite + 1),
|
|
|
|
})
|
|
|
|
);
|
|
|
|
}
|
2020-04-07 21:44:46 +02:00
|
|
|
|
2020-08-01 21:51:54 +02:00
|
|
|
//playlist handler for file input!
|
|
|
|
changeFiles(e, el) {
|
2020-08-05 11:24:59 +02:00
|
|
|
|
|
|
|
if (el.id !== 'upload-dir') {
|
|
|
|
return;
|
|
|
|
}
|
2020-08-01 21:51:54 +02:00
|
|
|
let files = [];
|
|
|
|
let i = 0;
|
|
|
|
for (let file of el.files) {
|
|
|
|
if (file && file.type.indexOf('audio') !== -1 && file.name.match(".m3u") === null) {
|
2020-08-06 23:44:37 +02:00
|
|
|
let audioFile = new AudioPlayerFile(file, i++);
|
|
|
|
files.push(audioFile);
|
2020-08-01 21:51:54 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
this.setPlaylist(files);
|
|
|
|
if (files.length > 0) {
|
2020-08-06 23:44:37 +02:00
|
|
|
NotificationHandler.createNotification("Songs added successfully!<br> Songs: " + files.length, "success", 3000);
|
2020-08-01 21:51:54 +02:00
|
|
|
this.renderPagination(0);
|
|
|
|
} else {
|
2020-08-06 23:44:37 +02:00
|
|
|
NotificationHandler.createNotification("File Upload failed!", "error", 3000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
getRealIndex(index) {
|
|
|
|
if (index === undefined) {
|
|
|
|
index = this.index;
|
|
|
|
}
|
|
|
|
if (this.isShuffle) {
|
|
|
|
return this.shuffled[index];
|
|
|
|
}
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
|
|
|
handle(data) {
|
|
|
|
let index = data.index;
|
|
|
|
if (data.status === "waiting") {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.list[index].id3 = data;
|
|
|
|
if (this.timeout) {
|
|
|
|
window.clearTimeout(this.timeout);
|
|
|
|
}
|
|
|
|
this.timeout = setTimeout(this.renderPagination.bind(this), 100);
|
|
|
|
}
|
|
|
|
|
|
|
|
forceID3(data) {
|
|
|
|
let self = this;
|
|
|
|
if (!self.forceData) {
|
|
|
|
self.forceData = {};
|
|
|
|
self.forceNotification = NotificationHandler.createNotification("TagReader -> 0 / " + self.list.length, "info", -1);
|
|
|
|
}
|
|
|
|
let index = data.index;
|
|
|
|
if (data.status === "waiting") {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
self.list[index].id3 = data;
|
|
|
|
self.forceData[index] = true;
|
|
|
|
let leng = Object.keys(self.forceData).length;
|
|
|
|
this.forceNotification.updateMessageOnly("TagReader -> " + leng + " / " + self.list.length);
|
|
|
|
if (leng === self.list.length) {
|
|
|
|
self.forceNotification.remove()
|
2020-08-01 21:51:54 +02:00
|
|
|
}
|
2020-04-07 21:44:46 +02:00
|
|
|
}
|
|
|
|
}
|