forked from server/soundboard
273 lines
6.4 KiB
JavaScript
273 lines
6.4 KiB
JavaScript
/* jshint esversion: 6 */
|
|
|
|
var localModeEnabled = false;
|
|
var selectedTags = [];
|
|
|
|
// References to howler objects
|
|
var howlerSounds = [];
|
|
|
|
function ready(fn) {
|
|
if (document.attachEvent ? document.readyState === "complete" : document.readyState !== "loading") {
|
|
fn();
|
|
} else {
|
|
document.addEventListener("DOMContentLoaded", fn);
|
|
}
|
|
}
|
|
|
|
function sleep(ms) {
|
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
}
|
|
|
|
ready(function() {
|
|
hideSections();
|
|
|
|
var sections = document.querySelectorAll("section");
|
|
var nav = document.querySelectorAll("nav > a");
|
|
|
|
if (sections.length > 0)
|
|
sections[0].style.display = "block";
|
|
|
|
nav.forEach(function(item) {
|
|
item.onclick = function(e) {
|
|
e.preventDefault();
|
|
|
|
var target = e.target.href.split("#");
|
|
var id = target[target.length - 1];
|
|
|
|
hideSections();
|
|
|
|
document.querySelector("#" + id).style.display = "block";
|
|
};
|
|
});
|
|
|
|
var searchfield = document.querySelector("#search");
|
|
searchfield.focus();
|
|
|
|
searchFilter(searchfield, ".sound", "inline-block");
|
|
|
|
var reset = document.querySelector("#reset");
|
|
var sounds_nav = document.querySelector("#sounds-nav");
|
|
|
|
reset.addEventListener("click", resetSearch, false);
|
|
sounds_nav.addEventListener("click", resetSearch, false);
|
|
|
|
addKeyListeners();
|
|
});
|
|
|
|
function searchFilter(searchfield, itemSelector, unHideStyle) {
|
|
if (searchfield !== null) {
|
|
searchfield.addEventListener("keyup", function() {
|
|
var items = document.querySelectorAll(itemSelector);
|
|
|
|
items.forEach(function(item) {
|
|
item.style.display = unHideStyle;
|
|
});
|
|
|
|
items.forEach(function(item) {
|
|
var name = item.firstChild.innerHTML;
|
|
|
|
if (name.toLowerCase().indexOf(searchfield.value.toLowerCase()) === -1) {
|
|
item.style.display = "none";
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
function tagFilter(sounds) {
|
|
var items = document.querySelectorAll(".sound");
|
|
|
|
items.forEach(function(item) {
|
|
item.style.display = "inline-block";
|
|
});
|
|
|
|
items.forEach(function(item) {
|
|
var name = item.firstChild.innerHTML;
|
|
|
|
if (sounds.length > 0 && sounds.indexOf(name) === -1) {
|
|
item.style.display = "none";
|
|
}
|
|
});
|
|
}
|
|
|
|
/*
|
|
* Adds all necessary KeyListeners to document
|
|
*/
|
|
function addKeyListeners() {
|
|
// keyboard listener for global key strokes/inputs
|
|
document.onkeydown = function(evt) {
|
|
evt = evt || window.event;
|
|
if (evt.keyCode == 27) {
|
|
// esc key
|
|
resetSearch();
|
|
} else if ((evt.keyCode == 75 || evt.keyCode == 67) && evt.ctrlKey) {
|
|
// ctrl+k and ctrl+c key binding
|
|
killAllAudio();
|
|
} else if (evt.keyCode == 88 && evt.ctrlKey){
|
|
// ctrl+x key binding
|
|
toggleLocalMode();
|
|
}
|
|
};
|
|
|
|
// keyboard listener for playing sounds using enter key
|
|
var buttons = document.querySelectorAll(".sound");
|
|
|
|
buttons.forEach(function(item) {
|
|
item.firstChild.addEventListener('keypress', async function (e) {
|
|
var key = e.keyCode;
|
|
var source = e.target;
|
|
// keylistener for enter or ctrl+enter (which is k10 on chrome)
|
|
if (key === 13 || (key === 10 && e.ctrlKey)) {
|
|
if (e.ctrlKey){
|
|
killAllAudio();
|
|
await sleep(100);
|
|
}
|
|
source.classList.add("sound-pressed");
|
|
source.onclick();
|
|
await sleep(300);
|
|
source.classList.remove("sound-pressed");
|
|
}
|
|
});
|
|
});
|
|
|
|
var tags = document.querySelectorAll(".tags li");
|
|
|
|
tags.forEach(function(tag) {
|
|
tag.addEventListener("click", function(e) {
|
|
var className = "tagged";
|
|
var el = this.firstChild;
|
|
|
|
var classes = el.className.split(" ");
|
|
var existingIndex = classes.indexOf(className);
|
|
|
|
if (existingIndex >= 0)
|
|
classes.splice(existingIndex, 1);
|
|
else
|
|
classes.push(className);
|
|
|
|
el.className = classes.join(" ");
|
|
|
|
var i = selectedTags.indexOf(el.innerHTML);
|
|
|
|
if (i == -1)
|
|
selectedTags.push(el.innerHTML);
|
|
else
|
|
selectedTags.splice(i, 1);
|
|
|
|
if (selectedTags.length > 0) {
|
|
ajaxRequest("/tags/" + encodeURI(selectedTags.join()), function() {
|
|
tagFilter(JSON.parse(this.responseText));
|
|
});
|
|
} else {
|
|
tagFilter([]);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
|
|
function resetSearch() {
|
|
var searchfield = document.querySelector("#search");
|
|
var buttons = document.querySelectorAll(".sound");
|
|
searchfield.blur();
|
|
searchfield.value = "";
|
|
|
|
buttons.forEach(function(item) {
|
|
item.style.display = "inline-block";
|
|
});
|
|
|
|
searchfield.focus();
|
|
}
|
|
|
|
/*
|
|
* Reads the stream url from input with id #streaming-url and forwards it to the server using AJAX.
|
|
*/
|
|
function playStream() {
|
|
var streamUrl = document.querySelector("#streaming-url").value;
|
|
ajaxRequest("/?video="+encodeURI(streamUrl));
|
|
}
|
|
|
|
function hideSections() {
|
|
var sections = document.querySelectorAll("section");
|
|
|
|
sections.forEach(function(item, i) {
|
|
item.style.display = "none";
|
|
});
|
|
}
|
|
|
|
function ajaxRequest(url, callback) {
|
|
var ajaxRequest;
|
|
try {
|
|
ajaxRequest = new XMLHttpRequest();
|
|
ajaxRequest.open("GET", url, true);
|
|
|
|
if (typeof callback !== 'undefined')
|
|
ajaxRequest.onload = callback;
|
|
|
|
ajaxRequest.send(null);
|
|
} catch (e) {
|
|
alert("Unfortunately we were unable to handle your request. Please try again later and contact the server administrator if the problem persists.");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Switches between local and remote playback mode.
|
|
* Additionally changes the button text and its color so that the user has a visible feedback.
|
|
*/
|
|
function toggleLocalMode() {
|
|
toggleButton = document.getElementById("local-mode-button").children[0];
|
|
if (localModeEnabled) {
|
|
localModeEnabled = false;
|
|
toggleButton.classList.remove("local");
|
|
toggleButton.innerHTML = "[S]";
|
|
toggleButton.title = "play sounds on server";
|
|
} else {
|
|
localModeEnabled = true;
|
|
toggleButton.classList.add("local");
|
|
toggleButton.innerHTML = "[L]";
|
|
toggleButton.title = "play sounds locally";
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Either plays the given sound file locally by using howler.js or forwards the request to the remote server using AJAX.
|
|
*/
|
|
function playSound(filename) {
|
|
if (localModeEnabled){
|
|
// play local audio using howler.js
|
|
var sound = new Howl({
|
|
src: ['/sounds/' + filename]
|
|
});
|
|
sound.play();
|
|
howlerSounds.push(sound);
|
|
} else {
|
|
ajaxRequest("/play/" + filename);
|
|
}
|
|
}
|
|
|
|
function killAllHowlerAudio() {
|
|
for (var i = 0; i < howlerSounds.length; i++) {
|
|
howlerSounds[i].stop();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Kills all local or remote audio, depending on localModeEnabled
|
|
*/
|
|
function killAllAudio() {
|
|
if (localModeEnabled) {
|
|
killAllHowlerAudio();
|
|
} else {
|
|
ajaxRequest("/?killvideo=yes");
|
|
}
|
|
}
|
|
|
|
function wm2018(channel) {
|
|
if (channel === "ard") {
|
|
ajaxRequest("/?video=https://www.ardmediathek.de/tv/live?kanal=208");
|
|
} else if (channel === "zdf") {
|
|
ajaxRequest("/?video=https://www.zdf.de/sender/zdf/zdf-live-beitrag-100.html");
|
|
}
|
|
}
|