Added showModal/hideModal utility functions
Added readStorageFile/eraseStorageFile to handle efficiently downloading large files (fix #119)master
parent
04f8cbcd13
commit
dd0e3c89d1
|
|
@ -5,32 +5,9 @@
|
|||
<body>
|
||||
<div id="tracks"></div>
|
||||
|
||||
<div class="modal active" id="status-modal">
|
||||
<div class="modal-overlay"></div>
|
||||
<div class="modal-container">
|
||||
<div class="modal-header">
|
||||
<div class="modal-title h5">Please wait</div>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="content">
|
||||
Loading...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../../lib/interface.js"></script>
|
||||
<script>
|
||||
var domTracks = document.getElementById("tracks");
|
||||
var domModal = document.getElementById("status-modal");
|
||||
|
||||
function showModal(title) {
|
||||
domModal.querySelector(".content").innerHTML = title;
|
||||
domModal.classList.add("active");
|
||||
}
|
||||
function hideModal(title) {
|
||||
domModal.classList.remove("active");
|
||||
}
|
||||
|
||||
function saveKML(track,title) {
|
||||
var kml = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
|
@ -107,19 +84,15 @@ function trackLineToObject(l, hasTrackNumber) {
|
|||
}
|
||||
|
||||
function downloadTrack(trackid, callback) {
|
||||
showModal("Downloading Track...");
|
||||
Puck.write(`\x10(function() {
|
||||
var f = require("Storage").open(".gpsrc${trackid.toString(36)}","r");
|
||||
var l = f.readLine();
|
||||
while (l!==undefined) { Bluetooth.print(l); l = f.readLine(); }
|
||||
})()\n`,tracklist=>{
|
||||
hideModal();
|
||||
var track = tracklist.trim().split("\n").map(l=>trackLineToObject(l,false));
|
||||
Util.showModal("Downloading Track...");
|
||||
Util.readStorageFile(`.gpsrc${trackid.toString(36)}`,data=>{
|
||||
Util.hideModal();
|
||||
var track = data.trim().split("\n").map(l=>trackLineToObject(l,false));
|
||||
callback(track);
|
||||
});
|
||||
}
|
||||
function getTrackList() {
|
||||
showModal("Loading Tracks...");
|
||||
Util.showModal("Loading Tracks...");
|
||||
domTracks.innerHTML = "";
|
||||
Puck.write(`\x10(function() {
|
||||
for (var n=0;n<36;n++) {
|
||||
|
|
@ -171,7 +144,7 @@ function getTrackList() {
|
|||
</div>
|
||||
</div>`;
|
||||
domTracks.innerHTML = html;
|
||||
hideModal();
|
||||
Util.hideModal();
|
||||
var buttons = domTracks.querySelectorAll("button");
|
||||
for (var i=0;i<buttons.length;i++) {
|
||||
buttons[i].addEventListener("click",event => {
|
||||
|
|
@ -179,9 +152,9 @@ function getTrackList() {
|
|||
var trackid = parseInt(button.getAttribute("trackid"));
|
||||
var task = button.getAttribute("task");
|
||||
if (task=="delete") {
|
||||
showModal("Deleting Track...");
|
||||
Puck.write(`\x10require("Storage").open(".gpsrc${trackid.toString(36)}","r").erase()\n`,()=>{
|
||||
hideModal();
|
||||
Util.showModal("Deleting Track...");
|
||||
Util.eraseStorageFile(`.gpsrc${trackid.toString(36)}`,()=>{
|
||||
Util.hideModal();
|
||||
getTrackList();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,32 +5,9 @@
|
|||
<body>
|
||||
<div id="records"></div>
|
||||
|
||||
<div class="modal active" id="status-modal">
|
||||
<div class="modal-overlay"></div>
|
||||
<div class="modal-container">
|
||||
<div class="modal-header">
|
||||
<div class="modal-name h5">Please wait</div>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="content">
|
||||
Loading...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../../lib/interface.js"></script>
|
||||
<script>
|
||||
var domRecords = document.getElementById("records");
|
||||
var domModal = document.getElementById("status-modal");
|
||||
|
||||
function showModal(name) {
|
||||
domModal.querySelector(".content").innerHTML = name;
|
||||
domModal.classList.add("active");
|
||||
}
|
||||
function hideModal(name) {
|
||||
domModal.classList.remove("active");
|
||||
}
|
||||
|
||||
function saveRecord(record,name) {
|
||||
var csv = `${record.map(rec=>[rec.time, rec.bpm, rec.confidence].join(",")).join("\n")}`;
|
||||
|
|
@ -62,20 +39,16 @@ function recordLineToObject(l, hasRecordNbr) {
|
|||
}
|
||||
|
||||
function downloadRecord(recordNbr, callback) {
|
||||
showModal("Downloading heart rate record...");
|
||||
Puck.write(`\x10(function() {
|
||||
var f = require("Storage").open(".heart${recordNbr.toString(36)}","r");
|
||||
var l = f.readLine();
|
||||
while (l!==undefined) { Bluetooth.print(l); l = f.readLine(); }
|
||||
})()\n`,recordList=>{
|
||||
hideModal();
|
||||
var record = recordList.trim().split("\n").map(l=>recordLineToObject(l,false));
|
||||
Util.showModal("Downloading heart rate record...");
|
||||
Util.readStorageFile(`.heart${recordNbr.toString(36)}`,data=>{
|
||||
Util.hideModal();
|
||||
var record = data.trim().split("\n").map(l=>recordLineToObject(l,false));
|
||||
callback(record);
|
||||
});
|
||||
}
|
||||
|
||||
function getRecordList() {
|
||||
showModal("Loading heart rate records...");
|
||||
Util.showModal("Loading heart rate records...");
|
||||
domRecords.innerHTML = "";
|
||||
Puck.write(`\x10(function() {
|
||||
for (var n=0;n<36;n++) {
|
||||
|
|
@ -118,7 +91,7 @@ function getRecordList() {
|
|||
</div>
|
||||
</div>`;
|
||||
domRecords.innerHTML = html;
|
||||
hideModal();
|
||||
Util.hideModal();
|
||||
var buttons = domRecords.querySelectorAll("button");
|
||||
for (var i=0;i<buttons.length;i++) {
|
||||
buttons[i].addEventListener("click",event => {
|
||||
|
|
@ -126,9 +99,9 @@ function getRecordList() {
|
|||
var recordNbr = parseInt(button.getAttribute("recordNbr"));
|
||||
var task = button.getAttribute("task");
|
||||
if (task=="delete") {
|
||||
showModal("Deleting record...");
|
||||
Puck.write(`\x10require("Storage").open(".heart${recordNbr.toString(36)}","r").erase()\n`,()=>{
|
||||
hideModal();
|
||||
Util.showModal("Deleting record...");
|
||||
Util.eraseStorageFile(`.heart${recordNbr.toString(36)}`,()=>{
|
||||
Util.hideModal();
|
||||
getRecordList();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
45
js/comms.js
45
js/comms.js
|
|
@ -147,5 +147,50 @@ readFile : (file) => {
|
|||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
readStorageFile : (filename) => { // StorageFiles are different to normal storage entries
|
||||
return new Promise((resolve,reject) => {
|
||||
// Use "\xFF" to signal end of file (can't occur in files anyway)
|
||||
var fileContent = "";
|
||||
var fileSize = undefined;
|
||||
var connection = Puck.getConnection();
|
||||
connection.received = "";
|
||||
connection.cb = function(d) {
|
||||
var finished = false;
|
||||
var eofIndex = d.indexOf("\xFF");
|
||||
if (eofIndex>=0) {
|
||||
finished = true;
|
||||
d = d.substr(0,eofIndex);
|
||||
}
|
||||
fileContent += d;
|
||||
if (fileSize === undefined) {
|
||||
var newLineIdx = fileContent.indexOf("\n");
|
||||
if (newLineIdx>=0) {
|
||||
fileSize = parseInt(fileContent.substr(0,newLineIdx));
|
||||
console.log("File size is "+fileSize);
|
||||
fileContent = fileContent.substr(newLineIdx+1);
|
||||
}
|
||||
} else {
|
||||
showProgress(undefined,100*fileContent.length / (fileSize||1000000));
|
||||
}
|
||||
if (finished) {
|
||||
hideProgress();
|
||||
connection.received = "";
|
||||
connection.cb = undefined;
|
||||
resolve(fileContent);
|
||||
}
|
||||
};
|
||||
console.log(`Reading StorageFile ${JSON.stringify(filename)}`);
|
||||
connection.write(`\x03\x10(function() {
|
||||
var f = require("Storage").open(${JSON.stringify(filename)},"r");
|
||||
Bluetooth.println(f.getLength());
|
||||
var l = f.readLine();
|
||||
while (l!==undefined) { Bluetooth.print(l); l = f.readLine(); }
|
||||
Bluetooth.print("\xFF");
|
||||
})()\n`,() => {
|
||||
showProgress(`Reading ${JSON.stringify(filename)}`,0);
|
||||
console.log(`StorageFile read started...`);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -229,6 +229,14 @@ function handleAppInterface(app) {
|
|||
id : msg.id
|
||||
});
|
||||
});
|
||||
} else if (msg.type=="readstoragefile") {
|
||||
Comms.readStorageFile(msg.data/*filename*/).then(function(result) {
|
||||
iwin.postMessage({
|
||||
type : "readstoragefilersp",
|
||||
data : result,
|
||||
id : msg.id
|
||||
});
|
||||
});
|
||||
}
|
||||
}, false);
|
||||
iwin.postMessage({type:"init"});
|
||||
|
|
|
|||
|
|
@ -3,10 +3,21 @@ be used from within BangleApps
|
|||
|
||||
See: README.md / `apps.json`: `interface` element
|
||||
|
||||
This exposes a 'Puck' object like the puck.js library,
|
||||
and calls `onInit` when it's ready. `Puck` can be used
|
||||
for sending/receiving data to the correctly connected
|
||||
This exposes a 'Puck' object (a simple version of
|
||||
https://github.com/espruino/EspruinoWebTools/blob/master/puck.js)
|
||||
and calls `onInit` when it's ready. `Puck` can be used for
|
||||
sending/receiving data to the correctly connected
|
||||
device with Puck.eval/write.
|
||||
|
||||
Puck.write(data,callback)
|
||||
Puck.eval(data,callback)
|
||||
|
||||
There is also:
|
||||
|
||||
Util.readStorageFile(filename,callback)
|
||||
Util.eraseStorageFile(filename,callback)
|
||||
Util.showModal(title)
|
||||
Util.hideModal()
|
||||
*/
|
||||
var __id = 0, __idlookup = [];
|
||||
var Puck = {
|
||||
|
|
@ -20,11 +31,48 @@ var Puck = {
|
|||
window.postMessage({type:"write",data:data,id:__id});
|
||||
}
|
||||
};
|
||||
|
||||
var Util = {
|
||||
readStorageFile : function(filename,callback) {
|
||||
__id++;
|
||||
__idlookup[__id] = callback;
|
||||
window.postMessage({type:"readstoragefile",data:filename,id:__id});
|
||||
},
|
||||
eraseStorageFile : function(filename,callback) {
|
||||
Puck.write(`\x10require("Storage").open(${JSON.stringify(filename)}","r").erase()\n`,callback);
|
||||
},
|
||||
showModal : function(title) {
|
||||
if (!Util.domModal) {
|
||||
Util.domModal = document.createElement('div');
|
||||
Util.domModal.id = "status-modal";
|
||||
Util.domModal.classList.add("modal");
|
||||
Util.domModal.classList.add("active");
|
||||
Util.domModal.innerHTML = `<div class="modal-overlay"></div>
|
||||
<div class="modal-container">
|
||||
<div class="modal-header">
|
||||
<div class="modal-title h5">Please wait</div>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="content">
|
||||
Loading...
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
document.body.appendChild(Util.domModal);
|
||||
}
|
||||
Util.domModal.querySelector(".content").innerHTML = title;
|
||||
Util.domModal.classList.add("active");
|
||||
},
|
||||
hideModal : function() {
|
||||
if (!Util.domModal) return;
|
||||
Util.domModal.classList.remove("active");
|
||||
}
|
||||
};
|
||||
window.addEventListener("message", function(event) {
|
||||
var msg = event.data;
|
||||
if (msg.type=="init") {
|
||||
onInit();
|
||||
} else if (msg.type=="evalrsp" || msg.type=="writersp") {
|
||||
} else if (msg.type=="evalrsp" || msg.type=="writersp"|| msg.type=="readstoragefilersp") {
|
||||
var cb = __idlookup[msg.id];
|
||||
delete __idlookup[msg.id];
|
||||
cb(msg.data);
|
||||
|
|
|
|||
Loading…
Reference in New Issue