Skip to content

Commit 3bccb42

Browse files
committedMar 19, 2025
Smoother progress, handle packet upload nicely and report errors when custom/interface HTML calls create errors
1 parent 3b846e8 commit 3bccb42

File tree

3 files changed

+77
-42
lines changed

3 files changed

+77
-42
lines changed
 

‎js/comms.js

+44-27
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ const Comms = {
4949
/// Evaluate the given expression, return the result as a promise
5050
eval : (expr) => {
5151
if (expr===undefined) throw new Error("Comms.eval(undefined) called!")
52-
if (typeof UART === "undefined") { // New method
52+
if (typeof UART !== "undefined") { // New method
5353
return UART.eval(expr);
5454
} else { // Old method
5555
return new Promise((resolve,reject) =>
@@ -76,29 +76,40 @@ const Comms = {
7676
return Puck.getConnection();
7777
}
7878
},
79+
supportsPacketUpload : () => Comms.getConnection().espruinoSendFile && !Utils.versionLess(device.version,"2v25"),
7980
// Faking EventEmitter
8081
handlers : {},
8182
on : function(id, callback) { // calling with callback=undefined will disable
8283
if (id!="data") throw new Error("Only data callback is supported");
8384
var connection = Comms.getConnection();
8485
if (!connection) throw new Error("No active connection");
85-
/* This is a bit of a mess - the Puck.js lib only supports one callback with `.on`. If you
86-
do Puck.getConnection().on('data') then it blows away the default one which is used for
87-
.write/.eval and you can't get it back unless you reconnect. So rather than trying to fix the
88-
Puck lib we just copy in the default handler here. */
89-
if (callback===undefined) {
90-
connection.on("data", function(d) { // the default handler
91-
connection.received += d;
92-
connection.hadData = true;
93-
if (connection.cb) connection.cb(d);
94-
});
95-
} else {
96-
connection.on("data", function(d) {
97-
connection.received += d;
98-
connection.hadData = true;
99-
if (connection.cb) connection.cb(d);
100-
callback(d);
101-
});
86+
if ("undefined"!==typeof Puck) {
87+
/* This is a bit of a mess - the Puck.js lib only supports one callback with `.on`. If you
88+
do Puck.getConnection().on('data') then it blows away the default one which is used for
89+
.write/.eval and you can't get it back unless you reconnect. So rather than trying to fix the
90+
Puck lib we just copy in the default handler here. */
91+
if (callback===undefined) {
92+
connection.on("data", function(d) { // the default handler
93+
connection.received += d;
94+
connection.hadData = true;
95+
if (connection.cb) connection.cb(d);
96+
});
97+
} else {
98+
connection.on("data", function(d) {
99+
connection.received += d;
100+
connection.hadData = true;
101+
if (connection.cb) connection.cb(d);
102+
callback(d);
103+
});
104+
}
105+
} else { // UART
106+
if (callback===undefined) {
107+
if (Comms.dataCallback) connection.removeListener("data",Comms.dataCallback);
108+
delete Comms.dataCallback;
109+
} else {
110+
Comms.dataCallback = callback;
111+
connection.on("data",Comms.dataCallback);
112+
}
102113
}
103114
},
104115
// ================================================================================
@@ -265,16 +276,15 @@ const Comms = {
265276
}
266277
let f = fileContents.shift();
267278
// Only upload as a packet if it makes sense for the file, connection supports it, as does device firmware
268-
let uploadPacket = (!!f.canUploadPacket) && Comms.getConnection().espruinoSendFile && !Utils.versionLess(device.version,"2v25");
279+
let uploadPacket = (!!f.canUploadPacket) && Comms.supportsPacketUpload();
269280

270281
console.log(`<COMMS> Upload ${f.name} => ${JSON.stringify(f.content.length>50 ? f.content.substr(0,50)+"..." : f.content)} (${f.content.length}b${uploadPacket?", binary":""})`);
271282
if (uploadPacket) {
272283
Comms.getConnection().espruinoSendFile(f.name, f.content, {
273284
fs: Const.FILES_IN_FS,
274285
chunkSize: Const.PACKET_UPLOAD_CHUNKSIZE,
275-
noACK: Const.PACKET_UPLOAD_NOACK,
276-
progress: (chunkNo,chunkCount)=>{Progress.show({percent: chunkNo*100/chunkCount});}
277-
}).then(doUploadFiles); // progress?
286+
noACK: Const.PACKET_UPLOAD_NOACK
287+
}).then(doUploadFiles);
278288
} else {
279289
Comms.uploadCommandList(f.cmd, currentBytes, maxBytes).then(doUploadFiles);
280290
}
@@ -621,11 +631,18 @@ ${Const.CONNECTION_DEVICE}.print("\\xFF");
621631
},
622632
// Read a non-storagefile file
623633
writeFile : (filename, data) => {
624-
console.log(`<COMMS> writeFile ${JSON.stringify(filename)}`);
625-
var cmds = AppInfo.getFileUploadCommands(filename, data);
634+
console.log(`<COMMS> writeFile ${JSON.stringify(filename)} (${data.length}b)`);
626635
Progress.show({title:`Writing ${JSON.stringify(filename)}`,percent:0});
627-
return Comms.write("\x10"+Comms.getProgressCmd()+"\n").then(() =>
628-
Comms.uploadCommandList(cmds, 0, cmds.length)
629-
);
636+
if (Comms.supportsPacketUpload()) {
637+
return Comms.getConnection().espruinoSendFile(filename, data, {
638+
chunkSize: Const.PACKET_UPLOAD_CHUNKSIZE,
639+
noACK: Const.PACKET_UPLOAD_NOACK
640+
});
641+
} else {
642+
var cmds = AppInfo.getFileUploadCommands(filename, data);
643+
return Comms.write("\x10"+Comms.getProgressCmd()+"\n").then(() =>
644+
Comms.uploadCommandList(cmds, 0, cmds.length)
645+
);
646+
}
630647
},
631648
};

‎js/index.js

+18
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,9 @@ function iframeSetup(options) {
245245
data : result,
246246
id : msg.id
247247
});
248+
}, function(err) {
249+
showToast("Eval from app loader failed:\n"+err,"error");
250+
console.warn(err);
248251
});
249252
} else if (msg.type=="write") {
250253
Comms.write(msg.data).then(function(result) {
@@ -253,6 +256,9 @@ function iframeSetup(options) {
253256
data : result,
254257
id : msg.id
255258
});
259+
}, function(err) {
260+
showToast("File Write from app loader failed:\n"+err,"error");
261+
console.warn(err);
256262
});
257263
} else if (msg.type=="readstoragefile") {
258264
Comms.readStorageFile(msg.filename).then(function(result) {
@@ -261,6 +267,9 @@ function iframeSetup(options) {
261267
data : result,
262268
id : msg.id
263269
});
270+
}, function(err) {
271+
showToast("StorageFile Read from app loader failed:\n"+err,"error");
272+
console.warn(err);
264273
});
265274
} else if (msg.type=="readstorage") {
266275
Comms.readFile(msg.filename).then(function(result) {
@@ -269,6 +278,9 @@ function iframeSetup(options) {
269278
data : result,
270279
id : msg.id
271280
});
281+
}, function(err) {
282+
showToast("File Read from app loader failed:\n"+err,"error");
283+
console.warn(err);
272284
});
273285
} else if (msg.type=="readstoragejson") {
274286
Comms.readFile(msg.filename).then(function(result) {
@@ -277,6 +289,9 @@ function iframeSetup(options) {
277289
data : Utils.parseRJSON(result),
278290
id : msg.id
279291
});
292+
}, function(err) {
293+
showToast("JSON File Read from app loader failed:\n"+err,"error");
294+
console.warn(err);
280295
});
281296
} else if (msg.type=="writestorage") {
282297
Progress.show({title:`Uploading ${JSON.stringify(msg.filename)}`,sticky:true});
@@ -286,6 +301,9 @@ function iframeSetup(options) {
286301
type : "writestoragersp",
287302
id : msg.id
288303
});
304+
}, function(err) {
305+
showToast("StorageFile Write from app loader failed:\n"+err,"error");
306+
console.warn(err);
289307
});
290308
} else if (options.messageHandler) options.messageHandler(event);
291309
}, false);

‎js/ui.js

+15-15
Original file line numberDiff line numberDiff line change
@@ -25,31 +25,31 @@ const Progress = {
2525
let percent = options.percent;
2626
if (percent!==undefined)
2727
percent = Progress.min*100 + (Progress.max-Progress.min)*percent;
28-
if (!Progress.domElement) {
29-
if (Progress.interval) {
30-
clearInterval(Progress.interval);
31-
Progress.interval = undefined;
32-
}
33-
if (options.percent == "animate") {
34-
Progress.interval = setInterval(function() {
35-
Progress.percent += 2;
36-
if (Progress.percent>100) Progress.percent=0;
37-
Progress.show({percent:Progress.percent});
38-
}, 100);
39-
Progress.percent = percent = 0;
40-
}
28+
if (Progress.interval) {
29+
clearInterval(Progress.interval);
30+
Progress.interval = undefined;
31+
}
32+
if (options.percent == "animate") {
33+
Progress.interval = setInterval(function() {
34+
Progress.percent += 2;
35+
if (Progress.percent>100) Progress.percent=0;
36+
Progress.show({percent:Progress.percent});
37+
}, 100);
38+
Progress.percent = percent = 0;
39+
}
4140

41+
if (!Progress.domElement) {
4242
let toastcontainer = document.getElementById("toastcontainer");
4343
Progress.domElement = htmlElement(`<div class="toast">
4444
${text ? `<div>${text}</div>`:``}
4545
<div class="bar bar-sm">
46-
<div class="bar-item" id="Progress.domElement" role="progressbar" style="width:${percent}%;" aria-valuenow="${percent}" aria-valuemin="0" aria-valuemax="100"></div>
46+
<div class="bar-item" id="Progress.domElement" role="progressbar" style="width:${percent}%;" aria-valuenow="${Math.round(percent)}" aria-valuemin="0" aria-valuemax="100"></div>
4747
</div>
4848
</div>`);
4949
toastcontainer.append(Progress.domElement);
5050
} else {
5151
let pt=document.getElementById("Progress.domElement");
52-
pt.setAttribute("aria-valuenow",percent);
52+
pt.setAttribute("aria-valuenow",Math.round(percent));
5353
pt.style.width = percent+"%";
5454
}
5555
},

0 commit comments

Comments
 (0)