File manager

This commit is contained in:
Stefan Ostermann 2025-07-27 12:37:21 +02:00
parent 54e3100867
commit 177530d030
3 changed files with 100 additions and 6 deletions

View File

@ -18,6 +18,7 @@
// define pins for RFID // define pins for RFID
#define CS_RFID 32 // SIC, tried 4 and 32 but only this worked! #define CS_RFID 32 // SIC, tried 4 and 32 but only this worked!
#define RST_RFID 33 #define RST_RFID 33
// this does not work as the irq pin is input only:
#define IRQ_RFID 34 #define IRQ_RFID 34
// Audio DAC // Audio DAC
@ -471,6 +472,11 @@ String getState()
else else
jsonState["title"] = "Angehalten"; // Store in flash jsonState["title"] = "Angehalten"; // Store in flash
if (currentNode != nullptr)
jsonState["filepath"] = currentNode->getCurrentPlayingFilePath();
else
jsonState["filepath"] = "";
jsonState["time"] = audio.getAudioCurrentTime(); jsonState["time"] = audio.getAudioCurrentTime();
jsonState["volume"] = audio.getVolume(); jsonState["volume"] = audio.getVolume();
jsonState["length"] = audio.getAudioFileDuration(); jsonState["length"] = audio.getAudioFileDuration();
@ -717,8 +723,8 @@ void setup()
pinMode(BTN_NEXT, INPUT_PULLUP); pinMode(BTN_NEXT, INPUT_PULLUP);
pinMode(BTN_PREV, INPUT_PULLUP); pinMode(BTN_PREV, INPUT_PULLUP);
/* setup the IRQ pin*/ /* setup the IRQ pin, not working because the pin is input only:*/
pinMode(IRQ_RFID, INPUT_PULLUP); //pinMode(IRQ_RFID, INPUT_PULLUP);
pinMode(CS_RFID, OUTPUT); pinMode(CS_RFID, OUTPUT);
pinMode(CS_SDCARD, OUTPUT); pinMode(CS_SDCARD, OUTPUT);
@ -792,7 +798,7 @@ void setup()
AsyncWiFiManager wifiManager(&server, &dns); AsyncWiFiManager wifiManager(&server, &dns);
// Memory optimizations for WiFiManager // Memory optimizations for WiFiManager
wifiManager.setDebugOutput(false); // Disable debug strings wifiManager.setDebugOutput(true); // Disable debug strings
wifiManager.setMinimumSignalQuality(20); // Reduce AP scan results wifiManager.setMinimumSignalQuality(20); // Reduce AP scan results
wifiManager.setRemoveDuplicateAPs(true); // Remove duplicate APs from memory wifiManager.setRemoveDuplicateAPs(true); // Remove duplicate APs from memory

View File

@ -40,7 +40,15 @@
%DIRECTORY% %DIRECTORY%
</p> </p>
<form id="uploadForm" method="POST" action="/upload" enctype="multipart/form-data">
<button id="toggleFileManagerButton" onclick="toggleFileManager()">Toggle File Manager</button>
<div id="fileManager" style="display:none; margin-top:20px;">
<h2>File Manager</h2>
<h2>Upload File</h2>
<form id="uploadForm" method="POST" action="/upload" enctype="multipart/form-data">
<input type="file" name="data" id="uploadFile" accept=".mp3,.wav,.flac,.m4a,.ogg"/> <input type="file" name="data" id="uploadFile" accept=".mp3,.wav,.flac,.m4a,.ogg"/>
<input type="submit" name="upload" value="Upload" title="Upload Audio File" id="uploadButton"/> <input type="submit" name="upload" value="Upload" title="Upload Audio File" id="uploadButton"/>
<div id="uploadStatus"></div> <div id="uploadStatus"></div>
@ -52,7 +60,7 @@
</div> </div>
</form> </form>
<h2>Edit RFID Mapping</h2> <h3>Edit RFID Mapping</h3>
<form id="editMappingForm"> <form id="editMappingForm">
<label for="rfid">RFID:</label> <label for="rfid">RFID:</label>
<input type="text" id="rfid" name="rfid" required><br> <input type="text" id="rfid" name="rfid" required><br>
@ -61,6 +69,19 @@
<button type="button" onclick="editMapping()">Update Mapping</button> <button type="button" onclick="editMapping()">Update Mapping</button>
</form> </form>
<h3>Move / Rename File</h3>
<label for="moveFrom">From:</label>
<input type="text" id="moveFrom" placeholder="/oldname.mp3"/>
<label for="moveTo">To:</label>
<input type="text" id="moveTo" placeholder="/newname.mp3"/>
<button onclick="moveFile()">Move/Rename</button>
<h3>Delete File</h3>
<label for="deleteFile">Filename:</label>
<input type="text" id="deleteFile" placeholder="/song.mp3"/>
<button onclick="deleteFile()">Delete</button>
</div>
<script src="/script.js"></script> <script src="/script.js"></script>
</body> </body>
</html> </html>

View File

@ -84,6 +84,16 @@ function displayState(state) {
document.getElementById("voltage").innerHTML = state['voltage']+' mV'; document.getElementById("voltage").innerHTML = state['voltage']+' mV';
document.getElementById("heap").innerHTML = state['heap']+' bytes free heap'; document.getElementById("heap").innerHTML = state['heap']+' bytes free heap';
document.getElementById("uid").innerHTML = 'Last NFC ID: '+state['uid']; document.getElementById("uid").innerHTML = 'Last NFC ID: '+state['uid'];
/* ==== Autofill convenience fields ==== */
if (state['filepath']) {
document.getElementById('moveFrom').value = state['filepath'];
document.getElementById('deleteFile').value = state['filepath'];
document.getElementById('song').value = state['filepath'];
}
if (state['uid']) {
document.getElementById('rfid').value = state['uid'];
}
var elements = document.getElementsByClassName('play-button'); var elements = document.getElementsByClassName('play-button');
var btn = elements[0]; var btn = elements[0];
@ -260,3 +270,60 @@ function resetUploadForm() {
// Clear file input // Clear file input
document.getElementById('uploadFile').value = ''; document.getElementById('uploadFile').value = '';
} }
/* ================= File Manager Functions ================= */
function toggleFileManager() {
var fm = document.getElementById('fileManager');
if (fm.style.display === 'none' || fm.style.display === '') {
fm.style.display = 'block';
} else {
fm.style.display = 'none';
}
}
function moveFile() {
var from = document.getElementById('moveFrom').value.trim();
var to = document.getElementById('moveTo').value.trim();
if (!from || !to) {
alert('Please provide both source and destination paths.');
return;
}
var xhr = new XMLHttpRequest();
xhr.open('GET', '/move_file?from=' + encodeURIComponent(from) + '&to=' + encodeURIComponent(to), true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
alert('File moved successfully.');
location.reload();
} else {
alert('Move failed: ' + (xhr.responseText || 'Unknown error'));
}
}
};
xhr.send();
}
function deleteFile() {
var filename = document.getElementById('deleteFile').value.trim();
if (!filename) {
alert('Please provide filename to delete.');
return;
}
if (!confirm('Are you sure you want to delete ' + filename + '?')) {
return;
}
var xhr = new XMLHttpRequest();
xhr.open('GET', '/delete_file?filename=' + encodeURIComponent(filename), true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
alert('File deleted successfully.');
location.reload();
} else {
alert('Delete failed: ' + (xhr.responseText || 'Unknown error'));
}
}
};
xhr.send();
}