added download all and delete all files

master
nravanelli 2025-05-05 14:07:40 +08:00
parent 5d9f1a7a43
commit 45f1f612ef
2 changed files with 90 additions and 32 deletions

View File

@ -3,6 +3,7 @@
<head>
<link rel="stylesheet" href="../../css/spectre.min.css">
<link rel="stylesheet" href="../../css/spectre-icons.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
<style>
.jsoneditor-container {
height: 500px;
@ -152,6 +153,7 @@
</thead>
<tbody id="downloadData-tab-content">
</tbody>
<div id="progressElementHeatSuite" style="margin-top:10px; font-weight:bold;"></div>
</table>
</div>
<p class="p-2 m-2"><button id="upload" class="btn btn-success">Upload</button></p>
@ -161,6 +163,7 @@
<script src="https://cdn.jsdelivr.net/npm/jsoneditor@latest/dist/jsoneditor.min.js"></script>
<script>
let HeatSuiteFileList = [];
//default Schema
let heatsuite__taskFile_defaultSchema = [
{
@ -373,46 +376,76 @@
});
});
}
function DownloadSingleFile(filename){
Util.readStorageFile(filename, (c)=>{
function downloadSingleFile(filename, callback) {
Util.readStorageFile(filename, (c) => {
let url;
let blob;
const a = document.createElement('a');
fnArr = filename.split('_');
if(fnArr[1] !== 'accel'){
const blob = new Blob([c], { type: 'text/plain' });
let fnArr = filename.split('_');
if (fnArr[1] !== 'accel') {
blob = new Blob([c], { type: 'text/plain' });
url = URL.createObjectURL(blob);
}else{
if (callback) return callback(filename, blob); // Call with original blob
} else {
function secondsToClock(seconds) {
let h = Math.floor(seconds / 3600);
let m = Math.floor((seconds % 3600) / 60);
let s = seconds % 60;
return [h, m, s].map(v => v.toString().padStart(2, '0')).join(':');
}
let csv = "time,seconds,mag_avg,mag_sum\n"; // Header
let csv = "time,seconds,mag_avg,mag_sum\n";
let lines = c.trim().split("\n");
for (let line of lines) {
let parts = line.split(",").map(v => parseInt(v, 10));
if (parts.length !== 3) continue;
let seconds = parts[0];
let avg = parts[1]/8192;
let sum = parts[2]/1024; //scaled differently
let avg = parts[1] / 8192;
let sum = parts[2] / 1024;
let time = secondsToClock(seconds);
csv += `${time},${seconds},${avg},${sum}\n`;
}
const blob = new Blob([csv], { type: 'text/csv' });
url = URL.createObjectURL(blob);
blob = new Blob([csv], { type: 'text/csv' });
}
if (callback) return callback(filename, blob);
url = URL.createObjectURL(blob);
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
return;
});
}
function downloadAllFiles(){
function downloadAllFiles() {
console.log("Downloading all files", HeatSuiteFileList);
const zip = new JSZip();
let index = 0;
const progressEl = document.getElementById("progressElementHeatSuite");
if (progressEl) progressEl.textContent = "Preparing to download...";
function processNext() {
if (index >= HeatSuiteFileList.length) {
if (progressEl) progressEl.textContent = "Creating ZIP...";
zip.generateAsync({ type: "blob" }).then(content => {
const a = document.createElement('a');
const url = URL.createObjectURL(content);
a.href = url;
a.download = "all_files.zip";
a.click();
URL.revokeObjectURL(url);
if (progressEl) progressEl.textContent = "Download complete!";
});
return;
}
const filename = HeatSuiteFileList[index];
if (progressEl) progressEl.textContent = `Downloading file ${index + 1} of ${HeatSuiteFileList.length}: ${filename}`;
downloadSingleFile(filename, (name, blob) => {
zip.file(name, blob);
index++;
processNext();
});
}
processNext();
}
function deleteFile(filename){
if (confirm(`Are you sure you want to delete ${filename}?`)) {
Util.eraseStorageFile(filename,(c) =>{
@ -421,6 +454,30 @@
});
}
}
function deleteAllFiles() {
if (!confirm("Are you sure you want to delete all files?")) return;
console.log("Deleting all files", HeatSuiteFileList);
let index = 0;
const progressEl = document.getElementById("progressElementHeatSuite");
if (progressEl) progressEl.textContent = "Preparing to delete files...";
function processNext() {
if (index >= HeatSuiteFileList.length) {
if (progressEl) progressEl.textContent = "All files deleted.";
// Refresh the list via Puck/E.show
const filePrefix = settings.filePrefix || 'htst';
Puck.eval('require("Storage").list(/^' + filePrefix + '/)', renderDownloadTab);
return;
}
const filename = HeatSuiteFileList[index];
if (progressEl) progressEl.textContent = `Deleting file ${index + 1} of ${HeatSuiteFileList.length}: ${filename}`;
Util.eraseStorageFile(filename, () => {
index++;
processNext();
});
}
processNext(); // Start the chain
}
function renderDownloadTabLogs(e){
var element = document.getElementById("downloadData-tab-content");
if(e.length > 0){
@ -430,17 +487,17 @@
}
}
function renderDownloadTab(e){
HeatSuiteFileList = e.map(file => file.replace(/\x01$/, '')); //save it globally for later use...safer
var element = document.getElementById("downloadData-tab-content");
var tab_badge = document.getElementById("downloadData-tab-label");
if(e.length > 0){
if(HeatSuiteFileList.length > 0){
tab_badge.classList.add("badge");
tab_badge.dataset.badge = e.length;
tab_badge.dataset.badge = HeatSuiteFileList.length;
element.innerHTML = "";
e.forEach((file)=>{
var filename = file.replace(/\x01$/, '');
element.insertAdjacentHTML('beforeend', `<tr id="file-${filename}"><td>${filename}</td><td><i class="icon icon-download" onclick="DownloadSingleFile('${filename}');"></i>&nbsp; <i class="icon icon-delete" onclick="deleteFile('${filename}');"></i></td></tr>`);
HeatSuiteFileList.forEach((filename)=>{
element.insertAdjacentHTML('beforeend', `<tr id="file-${filename}"><td>${filename}</td><td><i class="icon icon-download" onclick="downloadSingleFile('${filename}');"></i>&nbsp; <i class="icon icon-delete" onclick="deleteFile('${filename}');"></i></td></tr>`);
});
//element.insertAdjacentHTML('beforeend',`<tr id="end" class="text-bold"><td><button class="btn">Download All <i class="icon icon-download" onclick="DownloadAllFiles(JSON.parse("${e}"));"></i></button></td><td><button class="btn">Delete All <i class="icon icon-delete" onclick=""></i></button> </td></tr>`);
element.insertAdjacentHTML('beforeend',`<tr id="end" class="text-bold"><td><button class="btn" onclick="downloadAllFiles();">Download All <i class="icon icon-download" ></i></button></td><td><button class="btn" onclick="">Delete All <i class="icon icon-delete" ></i></button> </td></tr>`);
}else{
tab_badge.classList.remove("badge");
tab_badge.dataset.badge = 0;

View File

@ -520,7 +520,7 @@
E.showPrompt("Did you fall?", { title: "FALL DETECTION", img: atob("FBQBAfgAf+Af/4P//D+fx/n+f5/v+f//n//5//+f//n////3//5/n+P//D//wf/4B/4AH4A=") }).then((r) => {
if (r) {
fallDetected = true;
modHS.saveDataToFile('alert', 'alert', { 'type': 'fall' });
modHS.saveDataToFile('alert', 'marker', { 'event': 'fall' });
Bangle.showClock();
} else {
Bangle.showClock(); //no fall, so just return to clock
@ -785,23 +785,24 @@
}
};
Bangle.on('tap', function(data) {
if(data.double && data.dir === "front" && !Bangle.isCharging()){
require("widget_utils").hide();
Bangle.load('heatsuite.app.js');
}
});
Bangle.on('swipe', function(dir) {
if (dir === 1) { // 1 = right swipe
Bangle.buzz();
require("widget_utils").hide();
Bangle.load('heatsuite.app.js');
}
});
//Diagnosing BLUETOOTH Connection Issues
if (NRF.getSecurityStatus().connected) { //if widget starts while a bluetooth connection exits, need to force connection flag
connectionLock = true;
//for managing memory issues - keeping code here for testing purposes in the future
if (NRF.getSecurityStatus().connected) { //if widget starts while a bluetooth connection exits, force connection flag - but this is
//connectionLock = true;
}
NRF.on('error', function (msg) {
modHS.log("[NRF][ERROR] " + msg);
});
NRF.on('connect', function (addr) {
connectionLock = true;
//connectionLock = true;
modHS.log("[NRF][CONNECTED] " + JSON.stringify(addr));
});
NRF.on('disconnect', function (reason) {