mirror of
https://github.com/Crocmagnon/buzzer.git
synced 2024-11-21 23:48:07 +01:00
Handle unlimited files
This commit is contained in:
parent
9a9d3b8533
commit
707a099e63
2 changed files with 78 additions and 24 deletions
|
@ -1,6 +1,7 @@
|
||||||
const GLOBAL_TIMEOUT = 10000;
|
const GLOBAL_TIMEOUT = 10000;
|
||||||
let connectionOk = true;
|
let connectionOk = true;
|
||||||
let statusTimeout = null;
|
let statusTimeout = null;
|
||||||
|
let selectedFile = "";
|
||||||
|
|
||||||
function play() {
|
function play() {
|
||||||
console.log("Play...");
|
console.log("Play...");
|
||||||
|
@ -23,9 +24,9 @@ function volume(modifier) {
|
||||||
.catch(handleError);
|
.catch(handleError);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadStatus() {
|
async function loadStatus() {
|
||||||
console.log("Status...");
|
console.log("Status...");
|
||||||
fetch("/status", { signal: AbortSignal.timeout(GLOBAL_TIMEOUT) })
|
return fetch("/status", { signal: AbortSignal.timeout(GLOBAL_TIMEOUT) })
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(handleStatus)
|
.then(handleStatus)
|
||||||
.catch(handleError);
|
.catch(handleError);
|
||||||
|
@ -49,18 +50,18 @@ function handleStatus(data) {
|
||||||
location.reload();
|
location.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
let dom = "";
|
if (data.files.selected != selectedFile) {
|
||||||
data.files.available.forEach((element, index) => {
|
selectedFile = data.files.selected;
|
||||||
let className = "w3-blue";
|
document.querySelectorAll(".w3-green").forEach(element => {
|
||||||
if (index === data.files.selectedIndex) {
|
element.classList.remove("w3-green");
|
||||||
className = "w3-green";
|
element.classList.add("w3-blue");
|
||||||
}
|
|
||||||
dom += `<button class="w3-button ${className}" onclick="selectFile('${element}')">${element}</button>`;
|
|
||||||
});
|
});
|
||||||
if (data.files.moreNotShown) {
|
const previouslySelected = document.querySelector(`[data-name='${selectedFile}']`);
|
||||||
dom += `<button class="w3-button w3-gray" disabled="" title="D'autres fichiers sont disponibles">...</button>`;
|
if (previouslySelected) {
|
||||||
|
previouslySelected.classList.remove("w3-blue");
|
||||||
|
previouslySelected.classList.add("w3-green");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
document.getElementById("available-files").innerHTML = dom;
|
|
||||||
|
|
||||||
document.getElementById("volume-current").innerText = data.volume.current;
|
document.getElementById("volume-current").innerText = data.volume.current;
|
||||||
document.getElementById("volume-increase").disabled = !data.volume.canIncrease;
|
document.getElementById("volume-increase").disabled = !data.volume.canIncrease;
|
||||||
|
@ -68,6 +69,40 @@ function handleStatus(data) {
|
||||||
statusTimeout = setTimeout(loadStatus, GLOBAL_TIMEOUT);
|
statusTimeout = setTimeout(loadStatus, GLOBAL_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function listFiles(cursor=0) {
|
||||||
|
console.log("List files...");
|
||||||
|
return fetch(`/list-files?cursor=${cursor}`, { signal: AbortSignal.timeout(GLOBAL_TIMEOUT) })
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
let dom = "";
|
||||||
|
data.files.forEach(element => {
|
||||||
|
if (!element) {
|
||||||
|
// Filter out null
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let className = "w3-blue";
|
||||||
|
if (element === selectedFile) {
|
||||||
|
className = "w3-green";
|
||||||
|
}
|
||||||
|
dom += `<button class="w3-button ${className}" data-name="${element}" onclick="selectFile('${element}')">${element}</button>`;
|
||||||
|
});
|
||||||
|
if (data.files.moreNotShown) {
|
||||||
|
dom += `<button class="w3-button w3-gray" disabled="" title="D'autres fichiers sont disponibles">...</button>`;
|
||||||
|
}
|
||||||
|
const availableFilesNode = document.getElementById("available-files");
|
||||||
|
if (cursor == 0) {
|
||||||
|
availableFilesNode.innerHTML = dom;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
availableFilesNode.innerHTML += dom;
|
||||||
|
}
|
||||||
|
if (data.next) {
|
||||||
|
return listFiles(data.next);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(handleError);
|
||||||
|
}
|
||||||
|
|
||||||
function handleError(error) {
|
function handleError(error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
clearTimeout(statusTimeout);
|
clearTimeout(statusTimeout);
|
||||||
|
@ -78,6 +113,6 @@ function handleError(error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
(() => {
|
(() => {
|
||||||
loadStatus();
|
loadStatus().then(() => listFiles());
|
||||||
statusTimeout = setTimeout(loadStatus, GLOBAL_TIMEOUT);
|
statusTimeout = setTimeout(loadStatus, GLOBAL_TIMEOUT);
|
||||||
})();
|
})();
|
||||||
|
|
41
src/main.cpp
41
src/main.cpp
|
@ -83,6 +83,7 @@ void play()
|
||||||
|
|
||||||
void onStop(AsyncWebServerRequest *request)
|
void onStop(AsyncWebServerRequest *request)
|
||||||
{
|
{
|
||||||
|
Serial.println("Stop playing");
|
||||||
audio.stopSong();
|
audio.stopSong();
|
||||||
request->send(200);
|
request->send(200);
|
||||||
}
|
}
|
||||||
|
@ -98,40 +99,57 @@ void onStatus(AsyncWebServerRequest *request)
|
||||||
Serial.println("Status");
|
Serial.println("Status");
|
||||||
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
||||||
|
|
||||||
DynamicJsonDocument root(4096);
|
StaticJsonDocument<96> root;
|
||||||
JsonObject files = root.createNestedObject("files");
|
root["files"]["selected"] = selectedFile.c_str();
|
||||||
files["selectedIndex"] = -1;
|
|
||||||
files["moreNotShown"] = false;
|
|
||||||
|
|
||||||
JsonObject volume = root.createNestedObject("volume");
|
JsonObject volume = root.createNestedObject("volume");
|
||||||
volume["current"] = currentVolume;
|
volume["current"] = currentVolume;
|
||||||
volume["canDecrease"] = currentVolume > 0;
|
volume["canDecrease"] = currentVolume > 0;
|
||||||
volume["canIncrease"] = currentVolume < 21;
|
volume["canIncrease"] = currentVolume < 21;
|
||||||
|
|
||||||
JsonArray availableFiles = files.createNestedArray("available");
|
serializeJson(root, *response);
|
||||||
|
request->send(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onListFiles(AsyncWebServerRequest *request)
|
||||||
|
{
|
||||||
|
Serial.print("List files cursor=");
|
||||||
|
int cursor = 0;
|
||||||
|
if (request->hasParam("cursor")) {
|
||||||
|
String s_cursor = request->getParam("cursor")->value();
|
||||||
|
cursor = s_cursor.toInt();
|
||||||
|
}
|
||||||
|
Serial.println(cursor);
|
||||||
|
|
||||||
|
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
||||||
|
|
||||||
|
StaticJsonDocument<512> root;
|
||||||
|
root["next"] = -1;
|
||||||
|
JsonArray files = root.createNestedArray("files");
|
||||||
File music = SD.open("/");
|
File music = SD.open("/");
|
||||||
File file = music.openNextFile();
|
File file = music.openNextFile();
|
||||||
unsigned int index = 0;
|
int index = 0;
|
||||||
while (file)
|
while (file)
|
||||||
{
|
{
|
||||||
String fileName = file.name();
|
String fileName = file.name();
|
||||||
if (fileIsValid(fileName))
|
if (fileIsValid(fileName))
|
||||||
{
|
{
|
||||||
availableFiles.add(fileName);
|
|
||||||
if (fileName == selectedFile) {
|
|
||||||
files["selectedIndex"] = index;
|
|
||||||
}
|
|
||||||
index++;
|
index++;
|
||||||
|
if (index >= cursor)
|
||||||
|
files.add(fileName);
|
||||||
}
|
}
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
if (root.overflowed())
|
if (root.overflowed())
|
||||||
{
|
{
|
||||||
files["moreNotShown"] = true;
|
root["next"] = index;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
file = music.openNextFile();
|
file = music.openNextFile();
|
||||||
}
|
}
|
||||||
|
if (root["next"] == -1) {
|
||||||
|
root.remove("next");
|
||||||
|
}
|
||||||
|
|
||||||
serializeJson(root, *response);
|
serializeJson(root, *response);
|
||||||
request->send(response);
|
request->send(response);
|
||||||
|
@ -316,6 +334,7 @@ void setup()
|
||||||
server.on("/play", HTTP_GET, onPlay);
|
server.on("/play", HTTP_GET, onPlay);
|
||||||
server.on("/stop", HTTP_GET, onStop);
|
server.on("/stop", HTTP_GET, onStop);
|
||||||
server.on("/status", HTTP_GET, onStatus);
|
server.on("/status", HTTP_GET, onStatus);
|
||||||
|
server.on("/list-files", HTTP_GET, onListFiles);
|
||||||
server.on("/select-file", HTTP_POST, onSelectFile);
|
server.on("/select-file", HTTP_POST, onSelectFile);
|
||||||
server.on("/change-volume", HTTP_POST, onChangeVolume);
|
server.on("/change-volume", HTTP_POST, onChangeVolume);
|
||||||
server.on("/upload", HTTP_POST, onUpload, onUploadFile);
|
server.on("/upload", HTTP_POST, onUpload, onUploadFile);
|
||||||
|
|
Loading…
Reference in a new issue