Fix issues caused by Storage.eraseAll taking too long (fix #64)
Add progress bar and description to erase, uploads, and getting file infomaster
parent
d1fe3c5c97
commit
5c3d1a48fa
53
comms.js
53
comms.js
|
|
@ -2,7 +2,15 @@ Puck.debug=3;
|
|||
|
||||
// FIXME: use UART lib so that we handle errors properly
|
||||
var Comms = {
|
||||
uploadApp : app => {
|
||||
reset : () => {
|
||||
return new Promise((resolve,reject) => {
|
||||
Puck.write("\x03reset();\n", (result) => {
|
||||
if (result===null) return reject("");
|
||||
setTimeout(resolve,500);
|
||||
});
|
||||
});
|
||||
},
|
||||
uploadApp : (app,skipReset) => {
|
||||
return AppInfo.getFiles(app, httpGet).then(fileContents => {
|
||||
return new Promise((resolve,reject) => {
|
||||
var appJSONFile = fileContents.find(f=>f.name=="+"+app.id);
|
||||
|
|
@ -16,16 +24,18 @@ uploadApp : app => {
|
|||
}
|
||||
fileContents = fileContents.map(storageFile=>storageFile.cmd).join("\n")+"\n";
|
||||
console.log("uploadApp",fileContents);
|
||||
// reset to ensure we have enough memory to upload what we need to
|
||||
Puck.write("\x03reset();\n", (result) => {
|
||||
if (result===null) return reject("");
|
||||
setTimeout(() => { // wait for reset
|
||||
Puck.write("\x10E.showMessage('Uploading...')\n"+fileContents+"\x10E.showMessage('Hold BTN3\\nto reload')\n",(result) => {
|
||||
if (result===null) return reject("");
|
||||
resolve(appJSON);
|
||||
});
|
||||
},500);
|
||||
});
|
||||
function doUpload() {
|
||||
Puck.write(`\x10E.showMessage('Uploading\\n${app.id}...')\n${fileContents}\x10E.showMessage('Hold BTN3\\nto reload')\n`,(result) => {
|
||||
if (result===null) return reject("");
|
||||
resolve(appJSON);
|
||||
});
|
||||
}
|
||||
if (skipReset) {
|
||||
doUpload();
|
||||
} else {
|
||||
// reset to ensure we have enough memory to upload what we need to
|
||||
Comms.reset().then(doUpload)
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
|
@ -46,24 +56,21 @@ removeApp : app => { // expects an app structure
|
|||
return `\x10require("Storage").erase(${toJS(file.name)});\n`;
|
||||
}).join("");
|
||||
console.log("removeApp", cmds);
|
||||
return new Promise((resolve,reject) => {
|
||||
Puck.write("\x03"+cmds+"\x10E.showMessage('Hold BTN3\\nto reload')\n",(result) => {
|
||||
return Comms.reset().then(new Promise((resolve,reject) => {
|
||||
Puck.write(`\x03\x10E.showMessage('Erasing\\n${app.id}...')${cmds}\x10E.showMessage('Hold BTN3\\nto reload')\n`,(result) => {
|
||||
if (result===null) return reject("");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}));
|
||||
},
|
||||
removeAllApps : () => {
|
||||
return new Promise((resolve,reject) => {
|
||||
// Use eval here so we wait for it to finish
|
||||
Puck.eval('require("Storage").eraseAll()||true', (result,err) => {
|
||||
return Comms.reset().then(new Promise((resolve,reject) => {
|
||||
// Use write with newline here so we wait for it to finish
|
||||
Puck.write('\x10E.showMessage("Erasing...");require("Storage").eraseAll();Bluetooth.println("OK")\n', (result,err) => {
|
||||
if (result===null) return reject(err || "");
|
||||
Puck.write('\x03\x10reset()\n',(result) => {
|
||||
if (result===null) return reject("");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
resolve();
|
||||
}, true /* wait for newline */);
|
||||
}));
|
||||
},
|
||||
setTime : () => {
|
||||
return new Promise((resolve,reject) => {
|
||||
|
|
|
|||
89
index.js
89
index.js
|
|
@ -29,17 +29,31 @@ function showToast(message, type) {
|
|||
msgDiv.remove();
|
||||
}, 5000);
|
||||
}
|
||||
var progressToast;
|
||||
Puck.writeProgress = function(charsSent, charsTotal) {
|
||||
if (charsSent===undefined) {
|
||||
if (progressToast) progressToast.remove();
|
||||
progressToast = undefined;
|
||||
return;
|
||||
}
|
||||
var percent = Math.round(charsSent*100/charsTotal);
|
||||
var progressToast; // the DOM element
|
||||
var progressSticky; // showProgress(,,"sticky") don't remove until hideProgress("sticky")
|
||||
var progressInterval; // the interval used if showProgress(..., "animate")
|
||||
var progressPercent; // the current progress percentage
|
||||
function showProgress(text, percent, sticky) {
|
||||
if (sticky=="sticky")
|
||||
progressSticky = true;
|
||||
if (!progressToast) {
|
||||
if (progressInterval) {
|
||||
clearInterval(progressInterval);
|
||||
progressInterval = undefined;
|
||||
}
|
||||
if (percent == "animate") {
|
||||
progressInterval = setInterval(function() {
|
||||
progressPercent += 2;
|
||||
if (progressPercent>100) progressPercent=0;
|
||||
showProgress(undefined, progressPercent);
|
||||
}, 100);
|
||||
percent = 0;
|
||||
}
|
||||
progressPercent = percent;
|
||||
|
||||
var toastcontainer = document.getElementById("toastcontainer");
|
||||
progressToast = htmlElement(`<div class="toast">
|
||||
${text ? `<div>${text}</div>`:``}
|
||||
<div class="bar bar-sm">
|
||||
<div class="bar-item" id="progressToast" role="progressbar" style="width:${percent}%;" aria-valuenow="${percent}" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
|
|
@ -51,6 +65,26 @@ Puck.writeProgress = function(charsSent, charsTotal) {
|
|||
pt.style.width = percent+"%";
|
||||
}
|
||||
}
|
||||
function hideProgress(sticky) {
|
||||
if (progressSticky && sticky!="sticky")
|
||||
return;
|
||||
progressSticky = false;
|
||||
if (progressInterval) {
|
||||
clearInterval(progressInterval);
|
||||
progressInterval = undefined;
|
||||
}
|
||||
if (progressToast) progressToast.remove();
|
||||
progressToast = undefined;
|
||||
}
|
||||
|
||||
Puck.writeProgress = function(charsSent, charsTotal) {
|
||||
if (charsSent===undefined) {
|
||||
hideProgress();
|
||||
return;
|
||||
}
|
||||
var percent = Math.round(charsSent*100/charsTotal);
|
||||
showProgress(undefined, percent);
|
||||
}
|
||||
function showPrompt(title, text, buttons) {
|
||||
if (!buttons) buttons={yes:1,no:1};
|
||||
return new Promise((resolve,reject) => {
|
||||
|
|
@ -78,7 +112,7 @@ function showPrompt(title, text, buttons) {
|
|||
document.body.append(modal);
|
||||
modal.querySelector("a[href='#close']").addEventListener("click",event => {
|
||||
event.preventDefault();
|
||||
reject();
|
||||
reject("User cancelled");
|
||||
modal.remove();
|
||||
});
|
||||
htmlToArray(modal.getElementsByTagName("button")).forEach(button => {
|
||||
|
|
@ -86,7 +120,7 @@ function showPrompt(title, text, buttons) {
|
|||
event.preventDefault();
|
||||
var isYes = event.target.getAttribute("isyes")=="1";
|
||||
if (isYes) resolve();
|
||||
else reject();
|
||||
else reject("User cancelled");
|
||||
modal.remove();
|
||||
});
|
||||
});
|
||||
|
|
@ -132,7 +166,14 @@ function handleCustomApp(app) {
|
|||
var app = event.data;
|
||||
console.log("Received custom app", app);
|
||||
modal.remove();
|
||||
Comms.uploadApp(app).then(resolve,reject);
|
||||
showProgress(`Uploading ${app.name}`,undefined,"sticky");
|
||||
Comms.uploadApp(app).then(()=>{
|
||||
hideProgress("sticky");
|
||||
resolve();
|
||||
}).catch(e => {
|
||||
hideProgress("sticky");
|
||||
reject(e);
|
||||
});
|
||||
}, false);
|
||||
});
|
||||
}
|
||||
|
|
@ -270,7 +311,9 @@ function refreshLibrary() {
|
|||
// upload
|
||||
icon.classList.remove("icon-upload");
|
||||
icon.classList.add("loading");
|
||||
showProgress(`Uploading ${app.name}`,undefined,"sticky");
|
||||
Comms.uploadApp(app).then((appJSON) => {
|
||||
hideProgress("sticky");
|
||||
if (appJSON) appsInstalled.push(appJSON);
|
||||
showToast(app.name+" Uploaded!", "success");
|
||||
icon.classList.remove("loading");
|
||||
|
|
@ -278,6 +321,7 @@ function refreshLibrary() {
|
|||
refreshMyApps();
|
||||
refreshLibrary();
|
||||
}).catch(err => {
|
||||
hideProgress("sticky");
|
||||
showToast("Upload failed, "+err, "error");
|
||||
icon.classList.remove("loading");
|
||||
icon.classList.add("icon-upload");
|
||||
|
|
@ -334,16 +378,19 @@ function removeApp(app) {
|
|||
}
|
||||
|
||||
function updateApp(app) {
|
||||
showProgress(`Upgrading ${app.name}`,undefined,"sticky");
|
||||
Comms.removeApp(app).then(()=>{
|
||||
showToast(app.name+" removed successfully. Updating...",);
|
||||
appsInstalled = appsInstalled.filter(a=>a.id!=app.id);
|
||||
return Comms.uploadApp(app);
|
||||
}).then((appJSON) => {
|
||||
hideProgress("sticky");
|
||||
if (appJSON) appsInstalled.push(appJSON);
|
||||
showToast(app.name+" Updated!", "success");
|
||||
refreshMyApps();
|
||||
refreshLibrary();
|
||||
}, err=>{
|
||||
hideProgress("sticky");
|
||||
showToast(app.name+" update failed, "+err,"error");
|
||||
});
|
||||
}
|
||||
|
|
@ -413,14 +460,20 @@ return `<div class="tile column col-6 col-sm-12 col-xs-12">
|
|||
|
||||
function getInstalledApps() {
|
||||
showLoadingIndicator("myappscontainer");
|
||||
showProgress(`Getting app list...`,undefined,"sticky");
|
||||
// Get apps and files
|
||||
return Comms.getInstalledApps()
|
||||
.then(appJSON => {
|
||||
hideProgress("sticky");
|
||||
appsInstalled = appJSON;
|
||||
refreshMyApps();
|
||||
refreshLibrary();
|
||||
})
|
||||
.then(() => handleConnectionChange(true));
|
||||
.then(() => handleConnectionChange(true))
|
||||
.catch(err=>{
|
||||
hideProgress("sticky");
|
||||
return Promise.reject();
|
||||
});
|
||||
}
|
||||
|
||||
var connectMyDeviceBtn = document.getElementById("connectmydevice");
|
||||
|
|
@ -475,12 +528,15 @@ document.getElementById("settime").addEventListener("click",event=>{
|
|||
});
|
||||
document.getElementById("removeall").addEventListener("click",event=>{
|
||||
showPrompt("Remove All","Really remove all apps?").then(() => {
|
||||
showProgress("Removing all apps","animate", "sticky");
|
||||
return Comms.removeAllApps();
|
||||
}).then(()=>{
|
||||
hideProgress("sticky");
|
||||
appsInstalled = [];
|
||||
showToast("All apps removed","success");
|
||||
return getInstalledApps();
|
||||
}).catch(err=>{
|
||||
hideProgress("sticky");
|
||||
showToast("App removal failed, "+err,"error");
|
||||
});
|
||||
});
|
||||
|
|
@ -495,18 +551,25 @@ document.getElementById("installdefault").addEventListener("click",event=>{
|
|||
appCount = defaultApps.length;
|
||||
return showPrompt("Install Defaults","Remove everything and install default apps?");
|
||||
}).then(() => {
|
||||
showProgress("Removing all apps","animate", "sticky");
|
||||
return Comms.removeAllApps();
|
||||
}).then(()=>{
|
||||
hideProgress("sticky");
|
||||
appsInstalled = [];
|
||||
showToast(`Existing apps removed. Installing ${appCount} apps...`);
|
||||
return new Promise(resolve => {
|
||||
return new Promise((resolve,reject) => {
|
||||
function upload() {
|
||||
var app = defaultApps.shift();
|
||||
if (app===undefined) return resolve();
|
||||
showProgress(`${app.name} (${appCount-defaultApps.length}/${appCount})`,undefined,"sticky");
|
||||
Comms.uploadApp(app).then((appJSON) => {
|
||||
hideProgress("sticky");
|
||||
if (appJSON) appsInstalled.push(appJSON);
|
||||
showToast(`(${appCount-defaultApps.length}/${appCount}) ${app.name} Uploaded`);
|
||||
upload();
|
||||
}).catch(function() {
|
||||
hideProgress("sticky");
|
||||
reject()
|
||||
});
|
||||
}
|
||||
upload();
|
||||
|
|
|
|||
Loading…
Reference in New Issue