Moved Static Client
This commit is contained in:
parent
8d78960f0b
commit
4d3c707301
17 changed files with 0 additions and 0 deletions
|
|
@ -1,730 +0,0 @@
|
|||
// set all the global stuff
|
||||
let ip;
|
||||
let alertTime = 2;
|
||||
let adminPass = "";
|
||||
let justSkipped = false;
|
||||
let justChangedSetting = false;
|
||||
const ERR_NO_ADMIN = 401;
|
||||
const VALID_FILE_EXT = ["mp3","flac","wav"];
|
||||
|
||||
let playlistTimeTimer=null;
|
||||
let playlistElapsedSeconds=0;
|
||||
let playlistSongLength=-1;
|
||||
let currentlyPlaying = false;
|
||||
|
||||
const params = new URLSearchParams(location.search);
|
||||
|
||||
let darkmodetemp = getCookie("darkmode");
|
||||
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||
darkmodetemp = "true";
|
||||
}
|
||||
if(darkmodetemp === "") {
|
||||
darkmodetemp = params.get("darkmode")
|
||||
}
|
||||
if (darkmodetemp === "true") {
|
||||
// i know this is gonna cause weird blinking
|
||||
// maybe the dark mode function should be loaded before any content, would that work?
|
||||
// NEW JS FILE ????? exciting stuff
|
||||
// im thinking a few new js files
|
||||
// you know like good design separating stuff
|
||||
// yeah but i need the getCookie function in both the darkmode.js and this one, so im gonna make a
|
||||
// getcookie.js
|
||||
toggleDark("None");
|
||||
}
|
||||
|
||||
async function alertText(text="Song Added!") {
|
||||
alertbox = document.getElementById("alert");
|
||||
alertbox.innerHTML = text;
|
||||
await new Promise(r => setTimeout(r, alertTime*1000));
|
||||
if (alertbox.innerHTML == text) {
|
||||
alertbox.innerHTML = ""
|
||||
}
|
||||
}
|
||||
// a lot of this is kinda waffly because i was trying to get
|
||||
// it to return the right stuff and javascript is asyrcronouse (boo)
|
||||
async function getFromServer(bodyInfo, source="", secure=false, password=adminPass) {
|
||||
try{
|
||||
if (bodyInfo != null) {
|
||||
// the currently set password is always included in every request
|
||||
bodyInfo["password"] = password;
|
||||
}
|
||||
let href = "";
|
||||
if(secure) {
|
||||
href = "https://"+ip+"/" + source;
|
||||
} else {
|
||||
href = "http://"+ip+"/" + source;
|
||||
}
|
||||
const response = await fetch(href, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(bodyInfo),
|
||||
headers: {
|
||||
"Content-type": "application/json; charset=UTF-8"
|
||||
}
|
||||
});
|
||||
|
||||
let data = await response.json(); // original json
|
||||
if (response.status == ERR_NO_ADMIN) {
|
||||
// im suprised i didn't comment on this already but this is kinda lame desing
|
||||
// its not wrong but you know
|
||||
// it is easy which i like
|
||||
alertText("Error: Admin restricted action")
|
||||
} else if(!response.ok){
|
||||
throw new Error(data.error);
|
||||
alertText("Error: "+data.error);
|
||||
}
|
||||
// we add some information from the response just in case it is needed
|
||||
data["ok"] = response.ok;
|
||||
data["status"] = response.status;
|
||||
// console.log(data);
|
||||
return await data;
|
||||
} catch(e) {
|
||||
// console.log("error print here:");
|
||||
// console.log(e);
|
||||
if (e.toString().includes("TypeError: Failed to fetch")){
|
||||
alertText("Error: Can't Connect to Server (is the ip set?)")
|
||||
} else {
|
||||
alertText("Error: " + e);
|
||||
}
|
||||
const response=null;
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
//cookie reader is taken from internet because cookies ae too complicated for me
|
||||
//i still understand how it works though promise just i see no reason to write this from scratch
|
||||
function getCookie(cname) {
|
||||
let name = cname + "=";
|
||||
let decodedCookie = decodeURIComponent(document.cookie);
|
||||
let ca = decodedCookie.split(';');
|
||||
for(let i = 0; i <ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) == ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
//someone more organised than me would have set all these html elements to variables so they dont have to get them 50 times
|
||||
// also someone who likes things not being dumb more than me would have separated the client and server buttons
|
||||
async function controlButton(buttonType) {
|
||||
if (buttonType == "pp") { // Play-Pause button
|
||||
let result = await getFromServer({control: "play-pause"}, "controls");
|
||||
// console.log(result);
|
||||
currentlyPlaying = result["data"]["playingState"];
|
||||
} else if (buttonType == "sk") { // Skip button
|
||||
// clearInterval(playlistTimeTimer);
|
||||
let returnCode = await getFromServer({control: "skip"}, "controls");
|
||||
// console.log(returnCode["ok"])
|
||||
if(returnCode["ok"]) {
|
||||
if (document.getElementById("playlist-mode").style.display == "block") {
|
||||
skipInPlaylist();
|
||||
playlistElapsedSeconds = 0;
|
||||
justSkipped = true;
|
||||
}
|
||||
}
|
||||
} else if (buttonType == "pl") { // Playlist button
|
||||
clearInterval(playlistTimeTimer);
|
||||
document.getElementById("songlist").innerHTML = "";
|
||||
document.getElementById("playlist").innerHTML = "<h1 id=\"playlist-alert\"></h1>";
|
||||
document.getElementById("playlist-mode").style.display = "block";
|
||||
document.getElementById("songlist-mode").style.display = "none";
|
||||
document.getElementById("settings-mode").style.display = "none";
|
||||
generateVisualPlaylist();
|
||||
} else if (buttonType == "se") { //SearchMode button
|
||||
clearInterval(playlistTimeTimer);
|
||||
document.getElementById("songlist").innerHTML = "<h1>Search to find songs!</h1>";
|
||||
document.getElementById("playlist").innerHTML = "";
|
||||
document.getElementById("playlist-mode").style.display = "none";
|
||||
document.getElementById("songlist-mode").style.display = "block";
|
||||
document.getElementById("settings-mode").style.display = "none";
|
||||
} else if (buttonType == "st") { //Settings button
|
||||
clearInterval(playlistTimeTimer);
|
||||
document.getElementById("songlist").innerHTML = "";
|
||||
document.getElementById("playlist").innerHTML = "";
|
||||
document.getElementById("playlist-mode").style.display = "none";
|
||||
document.getElementById("songlist-mode").style.display = "none";
|
||||
document.getElementById("settings-mode").style.display = "block";
|
||||
checkSettings()
|
||||
} else if (buttonType == "pm") { //Partymode toggle (in settings)
|
||||
let response = await getFromServer({setting: "partymode-toggle"}, "settings")
|
||||
if(response.ok) {
|
||||
justChangedSetting = true;
|
||||
checkSettings();
|
||||
} else {
|
||||
// dont think anything is needed here
|
||||
}
|
||||
} else {
|
||||
alertText("Error: You pushed a button that does not exist");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function searchSongsEnter(e) {
|
||||
if (e.keyCode == 13) {
|
||||
searchSongs(document.getElementById("songsearch").value)
|
||||
}
|
||||
}
|
||||
|
||||
async function searchSongs(searchTerm){
|
||||
document.getElementById("songlist").innerHTML = ""
|
||||
let fetchResults = await getFromServer({search:searchTerm},"search").then();
|
||||
let searchResults = fetchResults.data;
|
||||
//generate the visual song list
|
||||
for(var fileName in searchResults) {
|
||||
let currentSongInJSON = searchResults[fileName]
|
||||
let newItem = document.createElement("div");
|
||||
newItem.className = "item";
|
||||
newItem.id = fileName;
|
||||
newItem.tabIndex = 0;
|
||||
let image = document.createElement("img");
|
||||
try {
|
||||
if (currentSongInJSON["art"] == null) {
|
||||
throw "no image lolz"
|
||||
}
|
||||
image.src = currentSongInJSON["art"];
|
||||
} catch(err){
|
||||
image.src = "./images/placeholder.png";
|
||||
}
|
||||
image.id = String(fileName)+" image";
|
||||
let head3 = document.createElement("h3");
|
||||
head3.innerText = currentSongInJSON["title"];
|
||||
let head4 = document.createElement("h4");
|
||||
head4.innerText = currentSongInJSON["artist"];
|
||||
newItem.appendChild(image);
|
||||
newItem.appendChild(head3);
|
||||
newItem.appendChild(head4);
|
||||
// I like this concept but i'm leaving it out for now
|
||||
if(currentSongInJSON.lossless === 1) {
|
||||
let losslesstag = document.createElement("p");
|
||||
losslesstag.textContent = "Ⓛ";
|
||||
losslesstag.classList.add("lossless-tag");
|
||||
newItem.appendChild(losslesstag);
|
||||
}
|
||||
document.getElementById("songlist").appendChild(newItem);
|
||||
|
||||
}
|
||||
if (JSON.stringify(searchResults)==JSON.stringify({})) {
|
||||
//display error if no results
|
||||
document.getElementById("songlist").innerHTML = "<h1>We might not have that one...</h1>";
|
||||
}
|
||||
}
|
||||
|
||||
function alertTimeEnter(e){
|
||||
if (e.key == "Enter") {
|
||||
e.preventDefault();
|
||||
alertTimeSet(document.getElementById("alerttimetextbox").value);
|
||||
}
|
||||
}
|
||||
|
||||
function alertTimeSet(time) {
|
||||
alertTime = time;
|
||||
document.cookie = "alertTime="+alertTime+"; path=/;"
|
||||
alertText("Alerts stay on screen for " + alertTime.toString() + " seconds")
|
||||
}
|
||||
|
||||
function ipSetEnter(e){
|
||||
if (e.key == "Enter") {
|
||||
e.preventDefault();
|
||||
// why on gosh's green earth am i sending a value here?
|
||||
// im gonna get rid of all these individual "enter" dectectors and do something
|
||||
// like i did for the keyboard selection of elements
|
||||
// basically just if(e==click || e.key == enter)
|
||||
ipSetter(document.getElementById("iptextbox").value)
|
||||
}
|
||||
}
|
||||
|
||||
function ipSetter(){
|
||||
ipBox = document.getElementById("iptextbox").value
|
||||
if (ipBox == "") {
|
||||
alertText("Your IP is set to "+ip)
|
||||
} else {
|
||||
if (ipBox.includes(":")) {
|
||||
port = ipBox.slice(ipBox.indexOf(":")+1)
|
||||
ip = ipBox;
|
||||
document.cookie = "ip="+ip+"; path=/;"
|
||||
alertText("Your IP is now set to "+ip.slice(0, ipBox.indexOf(":"))+" at port "+port)
|
||||
} else {
|
||||
ip = ipBox + ":19054"
|
||||
document.cookie = "ip="+ip+"; path=/;"
|
||||
alertText("Your IP is now set to "+ipBox+" at port 19054 (Default)")
|
||||
}
|
||||
}
|
||||
// anytime the server ip changes the qrcode should change to use it
|
||||
qrCodeGenerate()
|
||||
|
||||
}
|
||||
|
||||
function qrCodeGenerate() {
|
||||
let tempURL = "http://" + document.location.href.split("/")[2] + "/?ip=" + ip;
|
||||
document.getElementById("qrcode").innerHTML = "";
|
||||
// get the current foreground and background
|
||||
let dark = window.getComputedStyle(document.body).getPropertyValue("--text-color");
|
||||
let light = window.getComputedStyle(document.body).getPropertyValue("--bg-main");
|
||||
new QRCode(document.getElementById("qrcode"), {
|
||||
text: tempURL,
|
||||
width: 256,
|
||||
height: 256,
|
||||
colorDark : dark,
|
||||
colorLight : light,
|
||||
correctLevel : QRCode.CorrectLevel.H
|
||||
});
|
||||
}
|
||||
|
||||
async function displayElapsedPlaylistTime(elapsed=0,length=-1) {
|
||||
if(currentlyPlaying) {
|
||||
if(Math.floor(elapsed) > Math.floor(length) && typeof length === "number" && typeof elapsed === "number"){
|
||||
// console.log("somethingShouldBeHappening")
|
||||
playlistElapsedSeconds = 0;
|
||||
generateVisualPlaylist();
|
||||
}
|
||||
let mins = Math.floor(elapsed/60);
|
||||
let secs = Math.floor(elapsed%60);
|
||||
let durMins = Math.floor(length/60);
|
||||
let durSecs = Math.floor(length%60);
|
||||
let timeLeft = document.getElementById("elapsed-time-display");
|
||||
if(mins > durMins) {
|
||||
mins = durMins;
|
||||
if(secs > durSecs) {
|
||||
secs = durSecs;
|
||||
}
|
||||
}
|
||||
|
||||
timeLeft.innerHTML = mins.toString() +":"+ secs.toLocaleString('en-US', {minimumIntegerDigits: 2,useGrouping: false}) + "/"+ durMins.toString()+":"+durSecs.toLocaleString('en-US', {minimumIntegerDigits: 2,useGrouping: false});
|
||||
playlistElapsedSeconds++;
|
||||
}
|
||||
}
|
||||
|
||||
async function updateSingleSetting(data) {
|
||||
let toBeChanged = data["settingToChange"];
|
||||
if (toBeChanged === "partymode") {
|
||||
document.getElementById("partymode-button").textContent = data["newData"];
|
||||
} else if (toBeChanged === "perms") {
|
||||
let currentAdminPerms = data["newData"];
|
||||
document.getElementById("addsongsettingcheckbox").checked = currentAdminPerms["AS"];
|
||||
document.getElementById("skipsongsettingcheckbox").checked = currentAdminPerms["SK"];
|
||||
document.getElementById("playpausesettingcheckbox").checked = currentAdminPerms["PP"];
|
||||
document.getElementById("partymodesettingcheckbox").checked = currentAdminPerms["PM"];
|
||||
document.getElementById("volumechangesettingcheckbox").checked = currentAdminPerms["VOL"];
|
||||
document.getElementById("duplicateallowesettingcheckbox").checked = currentAdminPerms["DUP"];
|
||||
} else if (toBeChanged === "volume") {
|
||||
document.getElementById("volumerange").value = data["newData"];
|
||||
}
|
||||
}
|
||||
|
||||
async function checkSettings(skipServer=false) {
|
||||
//check client stuff first so if the server doesn't exist it can still be changed and seen
|
||||
if (ip.slice(-5)=="19054") {
|
||||
// don't show the port if it is the default
|
||||
document.getElementById("iptextbox").value = ip.slice(0,-6)
|
||||
} else {
|
||||
document.getElementById("iptextbox").value = ip;
|
||||
}
|
||||
qrCodeGenerate()
|
||||
document.getElementById("alerttimetextbox").value = alertTime
|
||||
partyButtonState = document.getElementById("partymode-button").innerHTML;
|
||||
let nodeList = document.getElementById("admincheckholder").children
|
||||
// temporary
|
||||
for (let i=0; i<nodeList.length;i++) {
|
||||
if (nodeList[i].type == 'checkbox') {
|
||||
nodeList[i].checked = true;
|
||||
}
|
||||
}
|
||||
//ping the server here
|
||||
data = await getFromServer({setting: "getsettings"}, "settings");
|
||||
x = data["data"];
|
||||
if (!(skipServer) || partyButtonState=="N/A") {
|
||||
if (x["partymode"] == false) {
|
||||
document.getElementById("partymode-button").innerHTML = "Off";
|
||||
} else {
|
||||
document.getElementById("partymode-button").innerHTML = "On";
|
||||
}
|
||||
} else if (document.getElementById("partymode-button").innerHTML == "Off") {
|
||||
document.getElementById("partymode-button").innerHTML = "On";
|
||||
} else {
|
||||
document.getElementById("partymode-button").innerHTML = "Off";
|
||||
}
|
||||
document.getElementById("volumerange").value = parseInt(x["volume"])
|
||||
|
||||
// do the admin checkboxes here
|
||||
let currentAdminPerms = x["admin"];
|
||||
document.getElementById("addsongsettingcheckbox").checked = currentAdminPerms["AS"];
|
||||
document.getElementById("skipsongsettingcheckbox").checked = currentAdminPerms["SK"];
|
||||
document.getElementById("playpausesettingcheckbox").checked = currentAdminPerms["PP"];
|
||||
document.getElementById("partymodesettingcheckbox").checked = currentAdminPerms["PM"];
|
||||
document.getElementById("volumechangesettingcheckbox").checked = currentAdminPerms["VOL"];
|
||||
document.getElementById("duplicateallowesettingcheckbox").checked = currentAdminPerms["DUP"];
|
||||
}
|
||||
|
||||
async function addToPlaylist(songObject) {
|
||||
i = document.getElementById("playlist").children.length-1
|
||||
let newItem = document.createElement("div");
|
||||
newItem.className = "item";
|
||||
newItem.id = Object.keys(songObject)[0];
|
||||
newItem.tabIndex = 0;
|
||||
let image = document.createElement("img");
|
||||
try {
|
||||
if (songObject[newItem.id]["art"] == null) {
|
||||
throw "no image lolz"
|
||||
}
|
||||
image.src = songObject[newItem.id]["art"];
|
||||
} catch(err){
|
||||
image.src = "./images/placeholder.png";
|
||||
}
|
||||
image.id = String(songObject[newItem.id])+" image";
|
||||
let head3 = document.createElement("h3");
|
||||
head3.innerText = songObject[newItem.id]["title"];
|
||||
let head4 = document.createElement("h4");
|
||||
head4.innerText= songObject[newItem.id]["artist"];
|
||||
let head5 = document.createElement("h5");
|
||||
let timeLeft =document.createElement("h5");
|
||||
timeLeft.style.fontWeight = 100;
|
||||
if(i==0) {
|
||||
// they can all have the text, doesn't really matter, but only the first one
|
||||
// should get the ids since its the one we want to mess with
|
||||
head5.id = "playing-indicator-text";
|
||||
timeLeft.id = "elapsed-time-display";
|
||||
}
|
||||
let textdiv = document.createElement("div")
|
||||
textdiv.className="text"
|
||||
newItem.appendChild(image);
|
||||
textdiv.appendChild(head3);
|
||||
textdiv.appendChild(head4);
|
||||
textdiv.appendChild(timeLeft);
|
||||
textdiv.appendChild(head5);
|
||||
newItem.appendChild(textdiv);
|
||||
document.getElementById("playlist").appendChild(newItem);
|
||||
try {
|
||||
if (i == 0) { // Only the first song in the loop gets a time
|
||||
head5.innerHTML="Playing";
|
||||
playlistElapsedSeconds = playlist[0]["time"];
|
||||
playlistSongLength = playlist[0]["length"];
|
||||
displayElapsedPlaylistTime(playlistElapsedSeconds,playlistSongLength);
|
||||
clearInterval(playlistTimeTimer);
|
||||
}
|
||||
} catch(e) {
|
||||
console.log("I dunno something bad happened:"+e);
|
||||
}
|
||||
}
|
||||
|
||||
async function skipInPlaylist() {
|
||||
playlistElapsedSeconds = 0;
|
||||
let playlistChildren = document.getElementById("playlist").children;
|
||||
if(playlistChildren[1].nodeName === "DIV") {
|
||||
playlistChildren[1].remove();
|
||||
}
|
||||
playlistChildren = document.getElementById("playlist").children;
|
||||
if(playlistChildren.length === 1) {
|
||||
playlistChildren[0].innerText = "Nothing's Queued..."
|
||||
} else {
|
||||
let firstElementTextChildren = playlistChildren[1].children[1].children
|
||||
// console.log(firstElementTextChildren);
|
||||
firstElementTextChildren[2].id = "elapsed-time-display";
|
||||
firstElementTextChildren[3].id = "playing-indicator-text";
|
||||
firstElementTextChildren[3].textContent = "Playing";
|
||||
}
|
||||
displayElapsedPlaylistTime(playlistElapsedSeconds,playlistSongLength);
|
||||
}
|
||||
|
||||
async function generateVisualPlaylist(conditions="") {
|
||||
document.getElementById("playlist").innerHTML = "<h1 id=\"playlist-alert\"></h1>";
|
||||
data = await getFromServer(null, "playlist");
|
||||
playlist = data["data"]["playlist"];
|
||||
currentlyPlaying = data["data"]["playingState"]
|
||||
playlist = Object.values(playlist).map(obj => {
|
||||
const filename = Object.keys(obj)[0]; // Get the filename
|
||||
const songData = obj[filename]; // Get the song metadata
|
||||
return { filename, ...songData }; // Merge filename with song data
|
||||
});
|
||||
if (playlist.length==0){
|
||||
clearInterval(playlistTimeTimer);
|
||||
document.getElementById("playlist-alert").innerHTML = "Nothing's Queued..."
|
||||
} else {
|
||||
if (conditions==="skip-button") {
|
||||
playlist.shift()
|
||||
if (playlist.length==0){
|
||||
document.getElementById("playlist-alert").innerHTML = "Nothing's Queued..."
|
||||
}
|
||||
}
|
||||
for (let i in playlist) {
|
||||
let fileName = playlist[i]["filename"]
|
||||
let newItem = document.createElement("div");
|
||||
newItem.className = "item";
|
||||
newItem.id = fileName;
|
||||
newItem.tabIndex = 0;
|
||||
let image = document.createElement("img");
|
||||
try {
|
||||
if (playlist[i]["art"] == null) {
|
||||
throw "no image lolz"
|
||||
}
|
||||
image.src = playlist[i]["art"];
|
||||
} catch(err){
|
||||
image.src = "./images/placeholder.png";
|
||||
}
|
||||
image.id = String(fileName)+" image";
|
||||
let head3 = document.createElement("h3");
|
||||
head3.innerText = playlist[i]["title"];
|
||||
let head4 = document.createElement("h4");
|
||||
head4.innerText=playlist[i]["artist"];
|
||||
let head5 = document.createElement("h5");
|
||||
let timeLeft =document.createElement("h5");
|
||||
timeLeft.style.fontWeight = 100;
|
||||
if(i== 0) {
|
||||
// they can all have the text, doesn't really matter, but only the first one
|
||||
// should get the ids since its the one we want to mess with
|
||||
head5.id = "playing-indicator-text";
|
||||
timeLeft.id = "elapsed-time-display";
|
||||
}
|
||||
let textdiv = document.createElement("div")
|
||||
textdiv.className="text"
|
||||
newItem.appendChild(image);
|
||||
textdiv.appendChild(head3);
|
||||
textdiv.appendChild(head4);
|
||||
textdiv.appendChild(timeLeft);
|
||||
textdiv.appendChild(head5);
|
||||
newItem.appendChild(textdiv);
|
||||
document.getElementById("playlist").appendChild(newItem);
|
||||
try {
|
||||
if (i == 0) { // Only the first song in the loop gets a time
|
||||
head5.innerHTML="Playing";
|
||||
if ((conditions != "skip-button")) {
|
||||
playlistElapsedSeconds = playlist[0]["time"];
|
||||
playlistSongLength = playlist[0]["length"];
|
||||
displayElapsedPlaylistTime(playlistElapsedSeconds,playlistSongLength);
|
||||
clearInterval(playlistTimeTimer);
|
||||
}
|
||||
}
|
||||
}catch(err){
|
||||
// i dont know why there's a try catch here but i'm leaving it i dont want to break something
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
playlistTimeTimer = setInterval(() => {
|
||||
displayElapsedPlaylistTime(playlistElapsedSeconds,playlistSongLength);
|
||||
},1000)
|
||||
}
|
||||
}
|
||||
|
||||
async function submitSong(songid) {
|
||||
let returncode = await getFromServer({song: songid}, "songadd");
|
||||
if(returncode["status"] === ERR_NO_ADMIN) {
|
||||
// right now the error is alerted in getFromServer, maybe will change that
|
||||
} else if(returncode["status"]!==200) {
|
||||
alertText("That song's already in the queue! Hang on!")
|
||||
} else {
|
||||
alertText("Added to Queue");
|
||||
}
|
||||
}
|
||||
function checkWhatSongWasClicked(e) {
|
||||
if(e.type == "click" || e.key == "Enter") {
|
||||
itemId = e.srcElement.id;
|
||||
if ((itemId.length-itemId.lastIndexOf("image") == 5) && itemId.lastIndexOf("image")!=-1) {
|
||||
itemId = itemId.slice(0,-6)
|
||||
}
|
||||
let filenameSep = itemId.split('.')
|
||||
//i feel like later kristy won't apreciate this
|
||||
//one of my files was "file.MP3" so it didn't work
|
||||
//windows be like
|
||||
if (VALID_FILE_EXT.includes(filenameSep[filenameSep.length-1].toLowerCase())) {
|
||||
submitSong(itemId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function toggleDark(e) {
|
||||
let x = document.getElementById("test-body").classList
|
||||
if (!(x.contains("dark-mode"))) {
|
||||
document.cookie = "darkmode=true; path=/;";
|
||||
document.getElementById("darkmode-button").innerHTML = "On";
|
||||
x.add("dark-mode");
|
||||
} else {
|
||||
document.cookie = "darkmode=false; path=/;";
|
||||
document.getElementById("darkmode-button").innerHTML = "Off";
|
||||
x.remove("dark-mode");
|
||||
}
|
||||
qrCodeGenerate();
|
||||
}
|
||||
|
||||
// async function sha256(message) {
|
||||
// // Encode the message as UTF-8
|
||||
// const msgBuffer = new TextEncoder().encode(message);
|
||||
|
||||
// // Hash the message
|
||||
// const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
|
||||
|
||||
// // Convert ArrayBuffer to hex string
|
||||
// const hashArray = Array.from(new Uint8Array(hashBuffer));
|
||||
// const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
||||
|
||||
// return hashHex;
|
||||
// }
|
||||
|
||||
async function adminPassEnter(e) {
|
||||
if (e.key == "Enter") {
|
||||
e.preventDefault();
|
||||
let enteredpass = document.getElementById("adminpasswordbox").value;
|
||||
if(enteredpass === "") {
|
||||
adminPass = ""; // an empty pass is technically meant to represent not having one
|
||||
// this isn't stritly necesarry but i dont wanna break anything that might depend on this being true
|
||||
} else {
|
||||
adminPass= await sha256(document.getElementById("adminpasswordbox").value);
|
||||
}
|
||||
alertText("Admin Password Updated");
|
||||
}
|
||||
}
|
||||
|
||||
async function submitPerms(e) {
|
||||
let tempData = {}
|
||||
tempData["PP"] = document.getElementById("playpausesettingcheckbox").checked;
|
||||
tempData["SK"] = document.getElementById("skipsongsettingcheckbox").checked;
|
||||
tempData["AS"] = document.getElementById("addsongsettingcheckbox").checked;
|
||||
tempData["PM"] = document.getElementById("partymodesettingcheckbox").checked;
|
||||
tempData["VOL"] = document.getElementById("volumechangesettingcheckbox").checked;
|
||||
tempData["DUP"] = document.getElementById("duplicateallowesettingcheckbox").checked;
|
||||
let returncode = await getFromServer({"setting":"perms","admin":tempData},"settings");
|
||||
if (!(returncode["ok"])) {
|
||||
// if you aren't allowed to check the box then toggle it again
|
||||
// its not perfect if you spam click, but it gets the point across to the user
|
||||
let clickedBox = e.srcElement;
|
||||
clickedBox.checked = !clickedBox.checked;
|
||||
} else {
|
||||
justChangedSetting = true;
|
||||
}
|
||||
}
|
||||
|
||||
async function clearPlaylist() {
|
||||
let returncode = await getFromServer({control:"clear"},"controls");
|
||||
if(returncode == ERR_NO_ADMIN || returncode == null) {
|
||||
// alertText("Admin Restricted ")
|
||||
// there's an admin restrict alert built into getFromServer
|
||||
} else {
|
||||
alertText("Playlist Cleared!");
|
||||
}
|
||||
}
|
||||
|
||||
let optionslist = []
|
||||
|
||||
//sets all de stuff for buttons
|
||||
document.addEventListener('keydown', function(e){
|
||||
if (e.key == "/"){
|
||||
document.getElementById("title").scrollIntoView();
|
||||
document.getElementById("songsearch").select();
|
||||
e.preventDefault()
|
||||
}})
|
||||
document.getElementById("playlist-mode").style.display = "none";
|
||||
document.getElementById("settings-mode").style.display = "none";
|
||||
document.getElementById("volumerange").onchange = async function(e) {
|
||||
// there is no reason for this not to be a defined function
|
||||
// FIX THIS
|
||||
let returnValue = await getFromServer({setting:"volume",level:e.target.value}, "settings")
|
||||
if (returnValue["status"] == ERR_NO_ADMIN) {
|
||||
// alertText("Error: Admin restricted action");
|
||||
// there's an admin restrict alert built into getFromServer
|
||||
// i wanna put the volume slider back to where it was but idk a good way to keep the previous volume
|
||||
checkSettings(false);
|
||||
} else if (returnValue["data"]["volumePassed"] !=0) {
|
||||
// i forgot about this, i had to do this because it confused the crap out of me one time
|
||||
// vlc doesn't let you change the volume of nothing, which makes sense if you think about it
|
||||
alertText("Nothing is playing")
|
||||
document.getElementById("volumerange").value = -1
|
||||
} else if (this.value == 0) {
|
||||
alertText("The volume is now set to 0 (Pause?)")
|
||||
} else {
|
||||
alertText("The volume is now set to " + this.value.toString())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//bit of a cheat code for clearing the alerts when they don't clear normally
|
||||
document.getElementById("title").addEventListener('click',function(){document.getElementById("alert").innerHTML = ""})
|
||||
document.getElementById("settings-button").addEventListener('click',function(){controlButton("st")});
|
||||
document.getElementById("play-pause-button").addEventListener('click', function(){controlButton("pp")});
|
||||
document.getElementById("playlist-button").addEventListener('click', function(){controlButton("pl")});
|
||||
document.getElementById("search-button").addEventListener('click', function(){controlButton("se")});
|
||||
document.getElementById("skip-button").addEventListener('click',function(){controlButton("sk")});
|
||||
document.getElementById("go-search").addEventListener('click', function(){searchSongs(document.getElementById("songsearch").value)})
|
||||
document.getElementById("songsearch").addEventListener('keydown', function(e){searchSongsEnter(e)});
|
||||
document.getElementById("iptextbox").addEventListener('keydown', function(e){ipSetEnter(e)});
|
||||
document.getElementById("alerttimetextbox").addEventListener('keydown', function(e){alertTimeEnter(e)});
|
||||
document.getElementById("adminpasswordbox").addEventListener('keydown',function(e){adminPassEnter(e)});
|
||||
document.getElementById("admincheckholder").addEventListener('click',function(e){submitPerms(e)});
|
||||
document.getElementById("partymode-button").addEventListener('click',function(){controlButton("pm")})
|
||||
document.getElementById("darkmode-button").addEventListener('click',function(){toggleDark()})
|
||||
document.getElementById("clear-button").addEventListener('click',function(){clearPlaylist()})
|
||||
//sets the fact that clicking a song needs to return its id to the function to find it
|
||||
document.getElementById("songlist").addEventListener('keydown', function(e){checkWhatSongWasClicked(e)});
|
||||
document.getElementById("songlist").addEventListener('click', function(e){checkWhatSongWasClicked(e)});
|
||||
|
||||
//makes the controls look mostly normal on all screens, best solution i could find, idk man
|
||||
// replaced this with "transform" css stuff
|
||||
// let tempWidth = document.getElementById('controls').clientWidth;
|
||||
// document.getElementById("controls").style.marginLeft = "-"+String(parseInt(tempWidth/2))+"px";
|
||||
|
||||
//for my use case (my immediate family), they dont know how to set an ip
|
||||
//using this allows the creator of the link for, a qr code for example, to set the ip before distributing the code, and it would all work smoothly
|
||||
//example (http://192.168.1.100:8000/?ip=192.168.1.100:19054 sets the ip to the same host at the default port)
|
||||
//the port must be set manually using this method, but only has to be done once for the url that ends up being shared
|
||||
|
||||
//tries the url first, then the cookie, then the default
|
||||
ip = params.get("ip")
|
||||
if (ip == null || ip=="") {
|
||||
ip=getCookie("ip")
|
||||
}
|
||||
if (ip==null || ip==""){
|
||||
ip = ""
|
||||
}
|
||||
|
||||
// saving the cookies (don't tell the EU)
|
||||
document.cookie = "ip="+ip+"; path=/;"
|
||||
|
||||
alertTime = getCookie("alertTime")
|
||||
document.getElementById("alerttimetextbox").value = alertTime
|
||||
if (alertTime == "") {
|
||||
alertTime = 2;
|
||||
document.cookie = "alertTime="+alertTime+"; path=/;"
|
||||
}
|
||||
// this is the code that makes the qr code at the very start
|
||||
qrCodeGenerate()
|
||||
|
||||
// socket testing stuff
|
||||
|
||||
socket = io("http://"+ip,{
|
||||
reconnectionAttemps: 5,
|
||||
timeout: 10000,
|
||||
});
|
||||
|
||||
socket.on("songAdd", function(data) {
|
||||
// console.log("recieved data from songAdd");
|
||||
// console.log(data);
|
||||
addToPlaylist(data);
|
||||
})
|
||||
|
||||
socket.on("timeUpdate", function(data) {
|
||||
// console.log("recieved data from timeUpdate");
|
||||
// console.log(data);
|
||||
playlistElapsedSeconds = data["elapsedTime"];
|
||||
currentlyPlaying = data["playingState"]
|
||||
});
|
||||
|
||||
socket.on("skipSong",() => {
|
||||
if(justSkipped === false) {
|
||||
skipInPlaylist();
|
||||
} else {
|
||||
justSkipped = false;
|
||||
}
|
||||
})
|
||||
|
||||
socket.on("settingsChange",(data) => {
|
||||
// console.log(data);
|
||||
if(justChangedSetting) {
|
||||
// console.log("working");
|
||||
justChangedSetting = false;
|
||||
} else {
|
||||
// checkSettings();
|
||||
updateSingleSetting(data);
|
||||
}
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue