Sockets allowing for live updates rather than complete rebuilds #7
4 changed files with 48 additions and 19 deletions
|
|
@ -6,6 +6,8 @@
|
||||||
<link rel="stylesheet" href="styles.css">
|
<link rel="stylesheet" href="styles.css">
|
||||||
<link rel="manifest" href="manifest.json" />
|
<link rel="manifest" href="manifest.json" />
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-sha256/0.11.0/sha256.min.js"></script>
|
||||||
|
<!-- above allows use of sha256() on http -->
|
||||||
<script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script>
|
<script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body id="test-body">
|
<body id="test-body">
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@
|
||||||
let ip;
|
let ip;
|
||||||
let alertTime = 2;
|
let alertTime = 2;
|
||||||
let adminPass = "";
|
let adminPass = "";
|
||||||
let justSkipped = false
|
let justSkipped = false;
|
||||||
|
let justChangedSetting = false;
|
||||||
const ERR_NO_ADMIN = 401;
|
const ERR_NO_ADMIN = 401;
|
||||||
const VALID_FILE_EXT = ["mp3","flac","wav"];
|
const VALID_FILE_EXT = ["mp3","flac","wav"];
|
||||||
|
|
||||||
|
|
@ -41,12 +42,16 @@ async function alertText(text="Song Added!") {
|
||||||
}
|
}
|
||||||
// a lot of this is kinda waffly because i was trying to get
|
// a lot of this is kinda waffly because i was trying to get
|
||||||
// it to return the right stuff and javascript is asyrcronouse (boo)
|
// it to return the right stuff and javascript is asyrcronouse (boo)
|
||||||
async function getFromServer(bodyInfo, source="",password=adminPass) {
|
async function getFromServer(bodyInfo, source="", secure=false, password=adminPass) {
|
||||||
try{
|
try{
|
||||||
if (bodyInfo != null) {
|
if (bodyInfo != null) {
|
||||||
// the currently set password is always included in every request
|
// the currently set password is always included in every request
|
||||||
bodyInfo["password"] = password;
|
bodyInfo["password"] = password;
|
||||||
}
|
}
|
||||||
|
let href = "";
|
||||||
|
if(secure) {
|
||||||
|
href = "https://"+ip+"/"
|
||||||
|
}
|
||||||
const response = await fetch("http://"+ip+"/"+source, {
|
const response = await fetch("http://"+ip+"/"+source, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify(bodyInfo),
|
body: JSON.stringify(bodyInfo),
|
||||||
|
|
@ -142,8 +147,13 @@ async function controlButton(buttonType) {
|
||||||
document.getElementById("settings-mode").style.display = "block";
|
document.getElementById("settings-mode").style.display = "block";
|
||||||
checkSettings()
|
checkSettings()
|
||||||
} else if (buttonType = "pm") { //Partymode toggle (in settings)
|
} else if (buttonType = "pm") { //Partymode toggle (in settings)
|
||||||
await getFromServer({setting: "partymode-toggle"}, "settings")
|
let response = await getFromServer({setting: "partymode-toggle"}, "settings")
|
||||||
checkSettings(true)
|
if(response.ok) {
|
||||||
|
justChangedSetting = true;
|
||||||
|
checkSettings();
|
||||||
|
} else {
|
||||||
|
// dont think anything is needed here
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -517,19 +527,19 @@ function toggleDark(e) {
|
||||||
qrCodeGenerate();
|
qrCodeGenerate();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sha256(message) {
|
// async function sha256(message) {
|
||||||
// Encode the message as UTF-8
|
// // Encode the message as UTF-8
|
||||||
const msgBuffer = new TextEncoder().encode(message);
|
// const msgBuffer = new TextEncoder().encode(message);
|
||||||
|
|
||||||
// Hash the message
|
// // Hash the message
|
||||||
const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
|
// const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
|
||||||
|
|
||||||
// Convert ArrayBuffer to hex string
|
// // Convert ArrayBuffer to hex string
|
||||||
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
// const hashArray = Array.from(new Uint8Array(hashBuffer));
|
||||||
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
// const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
||||||
|
|
||||||
return hashHex;
|
// return hashHex;
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
|
|||||||
async function adminPassEnter(e) {
|
async function adminPassEnter(e) {
|
||||||
if (e.key == "Enter") {
|
if (e.key == "Enter") {
|
||||||
|
|
@ -559,6 +569,8 @@ async function submitPerms(e) {
|
||||||
// its not perfect if you spam click, but it gets the point across to the user
|
// its not perfect if you spam click, but it gets the point across to the user
|
||||||
let clickedBox = e.srcElement;
|
let clickedBox = e.srcElement;
|
||||||
clickedBox.checked = !clickedBox.checked;
|
clickedBox.checked = !clickedBox.checked;
|
||||||
|
} else {
|
||||||
|
justChangedSetting = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -627,8 +639,9 @@ document.getElementById("songlist").addEventListener('keydown', function(e){chec
|
||||||
document.getElementById("songlist").addEventListener('click', 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
|
//makes the controls look mostly normal on all screens, best solution i could find, idk man
|
||||||
let tempWidth = document.getElementById('controls').clientWidth;
|
// replaced this with "transform" css stuff
|
||||||
document.getElementById("controls").style.marginLeft = "-"+String(parseInt(tempWidth/2))+"px";
|
// 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
|
//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
|
//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
|
||||||
|
|
@ -665,13 +678,13 @@ socket = io("http://"+ip,{
|
||||||
|
|
||||||
socket.on("songAdd", function(data) {
|
socket.on("songAdd", function(data) {
|
||||||
// console.log("recieved data from songAdd");
|
// console.log("recieved data from songAdd");
|
||||||
console.log(data);
|
// console.log(data);
|
||||||
addToPlaylist(data);
|
addToPlaylist(data);
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on("timeUpdate", function(data) {
|
socket.on("timeUpdate", function(data) {
|
||||||
// console.log("recieved data from timeUpdate");
|
// console.log("recieved data from timeUpdate");
|
||||||
console.log(data);
|
// console.log(data);
|
||||||
|
The
The `settingsChange` socket handler still logs to console (`console.log(data)` / `console.log("working")`). These debug statements will be noisy for all clients; remove them once behavior is validated.
```suggestion
if (justChangedSetting) {
```
|
|||||||
playlistElapsedSeconds = data["elapsedTime"];
|
playlistElapsedSeconds = data["elapsedTime"];
|
||||||
currentlyPlaying = data["playingState"]
|
currentlyPlaying = data["playingState"]
|
||||||
});
|
});
|
||||||
|
|
@ -682,4 +695,14 @@ socket.on("skipSong",() => {
|
||||||
} else {
|
} else {
|
||||||
justSkipped = false;
|
justSkipped = false;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
socket.on("settingsChange",(data) => {
|
||||||
|
console.log(data);
|
||||||
|
if(justChangedSetting) {
|
||||||
|
console.log("working");
|
||||||
|
justChangedSetting = false;
|
||||||
|
} else {
|
||||||
|
checkSettings();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -62,6 +62,7 @@ h4 {
|
||||||
left: 50%;
|
left: 50%;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
|
transform: translateX(-50%);
|
||||||
background-color:var(--bg-main);
|
background-color:var(--bg-main);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,7 @@ def settingsControl():
|
||||||
volumeLevel = int(recieveData["level"])
|
volumeLevel = int(recieveData["level"])
|
||||||
if(volumeLevel <= 100 and volumeLevel >= 0):
|
if(volumeLevel <= 100 and volumeLevel >= 0):
|
||||||
volumePassed = player.audio_set_volume(volumeLevel)
|
volumePassed = player.audio_set_volume(volumeLevel)
|
||||||
|
socketio.emit("settingsChange")
|
||||||
return {"error":"ok","data":{"volumePassed":volumePassed}},200
|
return {"error":"ok","data":{"volumePassed":volumePassed}},200
|
||||||
else:
|
else:
|
||||||
return {"error":"Invalid volume level","data":None},422
|
return {"error":"Invalid volume level","data":None},422
|
||||||
|
|
@ -198,11 +199,13 @@ def settingsControl():
|
||||||
elif recieveData["setting"] == "partymode-toggle":
|
elif recieveData["setting"] == "partymode-toggle":
|
||||||
if ADMIN_PASS == recieveData['password'] or controlPerms["PM"]:
|
if ADMIN_PASS == recieveData['password'] or controlPerms["PM"]:
|
||||||
partyMode = not(partyMode)
|
partyMode = not(partyMode)
|
||||||
|
socketio.emit("settingsChange")
|
||||||
return ERR_200
|
return ERR_200
|
||||||
else:
|
else:
|
||||||
return ERR_NO_ADMIN
|
return ERR_NO_ADMIN
|
||||||
elif recieveData["setting"] == "perms":
|
elif recieveData["setting"] == "perms":
|
||||||
if ADMIN_PASS == recieveData["password"]:
|
if ADMIN_PASS == recieveData["password"]:
|
||||||
|
socketio.emit("settingsChange")
|
||||||
controlPerms = recieveData["admin"]
|
controlPerms = recieveData["admin"]
|
||||||
# print(recieveData["admin"])
|
# print(recieveData["admin"])
|
||||||
return ERR_200
|
return ERR_200
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue
In
addToPlaylist,iis assigned withoutlet/const, creating an implicit global. Alsoimage.id = String(songObject[newItem.id]) + " image"will usually become "[object Object] image" and won’t be unique/meaningful. Declareilocally and base the image id on the filename (newItem.id) like the rest of the file does.