mirror of https://github.com/espruino/BangleApps
Added bin/sanitycheck.js to perform a bunch of tests to make sure everything is correct
parent
122ee5342a
commit
8220765c11
13
README.md
13
README.md
|
@ -67,6 +67,10 @@ This is the best way to test...
|
|||
* Run your personal `Bangle App Loader` at https://\<your-github-username\>.github.io/BangleApps/index.html to load apps onto your device
|
||||
* Your apps should be inside it - if there are problems, check your web browser's 'developer console' for errors
|
||||
|
||||
**Note:** It's a great idea to get a local copy of the repository on your PC,
|
||||
then run `bin/sanitycheck.js` - it'll run through a bunch of common issues
|
||||
that there might be.
|
||||
|
||||
Be aware of the delay between commits and updates on github.io - it can take a few minutes (and a 'hard refresh' of your browser) for changes to take effect.
|
||||
|
||||
### Offline
|
||||
|
@ -280,8 +284,6 @@ See [apps/gpsrec/interface.html](the GPS Recorder) for a full example.
|
|||
|
||||
## Coding hints
|
||||
|
||||
- Need to save state? Use the `E.on('kill',...)` event to save JSON to a file called `7chname.json`, then load it at startup.
|
||||
|
||||
- use `g.setFont(.., size)` to multiply the font size, eg ("6x8",3) : "18x24"
|
||||
|
||||
- use `g.drawString(text,x,y,true)` to draw with background color to overwrite existing text
|
||||
|
@ -296,6 +298,13 @@ See [apps/gpsrec/interface.html](the GPS Recorder) for a full example.
|
|||
|
||||
- chaining graphics methods, eg `g.setColor(0xFD20).setFontAlign(0,0).setfont("6x8",3)`
|
||||
|
||||
### Misc Notes
|
||||
|
||||
- Need to save state? Use the `E.on('kill',...)` event to save JSON to a file called `7chname.json`, then load it at startup.
|
||||
|
||||
- 'Welcome' apps define a file called `welcome.js` which the booloader picks up. This then chain-loads the welcome app itself.
|
||||
|
||||
|
||||
### Graphic areas
|
||||
|
||||
The screen is parted in a widget and app area for lcd mode `direct`(default).
|
||||
|
|
48
apps.json
48
apps.json
|
@ -42,9 +42,10 @@
|
|||
"icon": "app.png",
|
||||
"version":"0.03",
|
||||
"description": "Appears at first boot and explains how to use Bangle.js",
|
||||
"tags": "welcome",
|
||||
"tags": "start,welcome",
|
||||
"allow_emulator":true,
|
||||
"storage": [
|
||||
{"name":"welcome.js","url":"welcome.js"},
|
||||
{"name":"welcome.app.js","url":"app.js"},
|
||||
{"name":"welcome.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
|
@ -210,12 +211,14 @@
|
|||
},
|
||||
{ "id": "openloc",
|
||||
"name": "Open Location / Plus Codes",
|
||||
"icon": "openlocation.png",
|
||||
"shortName": "Open Location",
|
||||
"icon": "app.png",
|
||||
"version":"0.01",
|
||||
"description": "Convert your current GPS location to a series of characters",
|
||||
"tags": "tool,outdoors,gps",
|
||||
"storage": [
|
||||
{"name":"openloc.app.js","url":"openlocation.js","evaluate":true}
|
||||
{"name":"openloc.app.js","url":"app.js"},
|
||||
{"name":"openloc.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
},
|
||||
{ "id": "speedo",
|
||||
|
@ -304,6 +307,7 @@
|
|||
"version":"0.01",
|
||||
"description": "When the screen is on, the widget turns on the heart rate monitor and displays the current heart rate (or last known in grey). For this to work well you'll need at least a 15 second LCD Timeout.",
|
||||
"tags": "health,widget",
|
||||
"type": "widget",
|
||||
"storage": [
|
||||
{"name":"widhrm.wid.js","url":"widget.js"}
|
||||
]
|
||||
|
@ -333,6 +337,7 @@
|
|||
},
|
||||
{ "id": "hidmsic",
|
||||
"name": "Bluetooth Music Controls",
|
||||
"shortName": "Music Control",
|
||||
"icon": "hid-music.png",
|
||||
"version":"0.01",
|
||||
"description": "Enable HID in settings, pair with your phone, then use this app to control music from your watch!",
|
||||
|
@ -344,6 +349,7 @@
|
|||
},
|
||||
{ "id": "hidkbd",
|
||||
"name": "Bluetooth Keyboard",
|
||||
"shortName": "Bluetooth Kbd",
|
||||
"icon": "hid-keyboard.png",
|
||||
"version":"0.01",
|
||||
"description": "Enable HID in settings, pair with your phone/PC, then use this app to control other apps",
|
||||
|
@ -355,6 +361,7 @@
|
|||
},
|
||||
{ "id": "hidbkbd",
|
||||
"name": "Binary Bluetooth Keyboard",
|
||||
"shortName": "Binary BT Kbd",
|
||||
"icon": "hid-binary-keyboard.png",
|
||||
"version":"0.01",
|
||||
"description": "Enable HID in settings, pair with your phone/PC, then type messages using the onscreen keyboard by tapping repeatedly on the key you want",
|
||||
|
@ -392,7 +399,7 @@
|
|||
"custom": "qrcode.html",
|
||||
"storage": [
|
||||
{"name":"qrcode.app.js"},
|
||||
{"name":"qrcode.wid.js"}
|
||||
{"name":"qrcode.img"}
|
||||
]
|
||||
},
|
||||
{ "id": "beer",
|
||||
|
@ -404,7 +411,7 @@
|
|||
"custom": "beercompass.html",
|
||||
"storage": [
|
||||
{"name":"beer.app.js"},
|
||||
{"name":"beer.wid.js"}
|
||||
{"name":"beer.img"}
|
||||
]
|
||||
},
|
||||
{ "id": "route",
|
||||
|
@ -416,27 +423,25 @@
|
|||
"custom": "route.html",
|
||||
"storage": [
|
||||
{"name":"route.app.js"},
|
||||
{"name":"route.wid.js"}
|
||||
{"name":"route.img"}
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
"id": "ncstart",
|
||||
"name": "NCEU Startup",
|
||||
"icon": "start.png",
|
||||
"version":"0.02",
|
||||
"description": "NodeConfEU 2019 'First Start' Sequence",
|
||||
"tags": "start",
|
||||
"tags": "start,welcome",
|
||||
"storage": [
|
||||
{"name":".boot3","url":"start.js"},
|
||||
{"name":"welcome.js","url":"welcome.js"},
|
||||
{"name":"ncstart.app.js","url":"start.js"},
|
||||
{"name":"ncstart.img","url":"start-icon.js","evaluate":true},
|
||||
{"name":"bangle.img","url":"start-bangle.js","evaluate":true},
|
||||
{"name":"nceu.img","url":"start-nceu.js","evaluate":true},
|
||||
{"name":"nfr.img","url":"start-nfr.js","evaluate":true},
|
||||
{"name":"nodew.img","url":"start-nodew.js","evaluate":true},
|
||||
{"name":"tf.img","url":"start-tf.js","evaluate":true}
|
||||
{"name":"nc-bangle.img","url":"start-bangle.js","evaluate":true},
|
||||
{"name":"nc-nceu.img","url":"start-nceu.js","evaluate":true},
|
||||
{"name":"nc-nfr.img","url":"start-nfr.js","evaluate":true},
|
||||
{"name":"nc-nodew.img","url":"start-nodew.js","evaluate":true},
|
||||
{"name":"nc-tf.img","url":"start-tf.js","evaluate":true}
|
||||
]
|
||||
},
|
||||
{ "id": "ncfrun",
|
||||
|
@ -637,9 +642,8 @@
|
|||
"tags": "gps",
|
||||
"type": "app",
|
||||
"storage": [
|
||||
{"name": "+gpsinfo","url": "gps-info.json"},
|
||||
{"name": "-gpsinfo","url": "gps-info.js"},
|
||||
{"name": "*gpsinfo","url": "gps-info-icon.js","evaluate": true}
|
||||
{"name":"gpsinfo.app.js","url": "gps-info.js"},
|
||||
{"name":"gpsinfo.img","url": "gps-info-icon.js","evaluate": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -652,13 +656,13 @@
|
|||
"type": "app",
|
||||
"allow_emulator":true,
|
||||
"storage": [
|
||||
{"name": "+pomodo","url": "pomodoro.json"},
|
||||
{"name": "-pomodo","url": "pomodoro.js"},
|
||||
{"name": "*pomodo","url": "pomodoro-icon.js","evaluate": true}
|
||||
{"name":"pomodo.app.js","url": "pomodoro.js"},
|
||||
{"name":"pomodo.img","url": "pomodoro-icon.js","evaluate": true}
|
||||
]
|
||||
},
|
||||
{ "id": "blobclk",
|
||||
"name": "Large Digit Blob Clock",
|
||||
"shortName" : "Blob Clock",
|
||||
"icon": "clock-blob.png",
|
||||
"version":"0.03",
|
||||
"description": "A clock with big digits",
|
||||
|
|
|
@ -1 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AH4Az4/HDDAACCywaSCpgeLBQOjzowRIxZPMBIWj0YvjNRKQSCpIWBEBq/VF6hrKdpwuKABYvXFywlDXjw5aF1gvKF0gv5F0ovvFxQxkF9ztLF8ItJF5XGAAIrfeJYtB4D7TFyQlEFwg8INgZtFF6wuCF4wAFBoPAF7ouNF8AfCF56ZFFyofEF9YgCF5z6GF9y+TC4SAFF9ZgNBgovZMAeczgRJBYovXMAtPAAIQIBYouXDAWjEYUrGBMrBYgvY/15vNVCtAADqoACCs4A/AH4A/AH4A/ABY")
|
||||
require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AH4Az4/HDDAACCywaSCpgeLBQOjzowRIxZPMBIWj0YvjNRKQSCpIWBEBq/VF6hrKdpwuKABYvXFywlDXjw5aF1gvKF0gv5F0ovvFxQxkF9ztLF8ItJF5XGAAIrfeJYtB4D7TFyQlEFwg8INgZtFF6wuCF4wAFBoPAF7ouNF8AfCF56ZFFyofEF9YgCF5z6GF9y+TC4SAFF9ZgNBgovZMAeczgRJBYovXMAtPAAIQIBYouXDAWjEYUrGBMrBYgvY/15vNVCtAADqoACCs4A/AH4A/AH4A/ABY"))
|
||||
|
|
|
@ -1 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AH4A/ACXJ5PKAQfKAAPJB4nDAAIsaEwQAJ5IrCAAYbFGyBWBFyooCGxQABPAyDEABYuHGxInFAAQGGLyoIGLxQvCFyAvJBIzjKdB6OLagYwDc5K/DFyIVBAAprHF5IsTHaAuKRoSOSABwvMXyZhPF5iNfF9nJp9PGB4vh5PD3u8X86PCFwO8AAS/mGQe9zAACF/CPdF4aPD3rwmGAu9FxRghegQuKL8IvBFxYwhFx6QdFpxedXIIuQLpHJ4YdCBoQDDFQosRLxAaB4YAEIRIQDFyQvEFhYwGCQgvX/wcOCYYuWDYSmCF6CfEF6mlz96vX+z+evVPCZwABCJYAJvVVAAVPAAYTNCJoAJFwYvPCY5gUAH4A/AH4A/AH4A2")
|
||||
require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AH4A/ACXJ5PKAQfKAAPJB4nDAAIsaEwQAJ5IrCAAYbFGyBWBFyooCGxQABPAyDEABYuHGxInFAAQGGLyoIGLxQvCFyAvJBIzjKdB6OLagYwDc5K/DFyIVBAAprHF5IsTHaAuKRoSOSABwvMXyZhPF5iNfF9nJp9PGB4vh5PD3u8X86PCFwO8AAS/mGQe9zAACF/CPdF4aPD3rwmGAu9FxRghegQuKL8IvBFxYwhFx6QdFpxedXIIuQLpHJ4YdCBoQDDFQosRLxAaB4YAEIRIQDFyQvEFhYwGCQgvX/wcOCYYuWDYSmCF6CfEF6mlz96vX+z+evVPCZwABCJYAJvVVAAVPAAYTNCJoAJFwYvPCY5gUAH4A/AH4A/AH4A2"))
|
||||
|
|
|
@ -1 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AGesAAQuuGAQ1jFQoAKF1wwdFyQycF6wwVFi4wWEiOBq1WqoABvQHBvWALsl6p4ADF4IIBGwSNjMAJdCAAVVGwQwPXjWBFoMrF4IwOFzVWp94lV4vIwNFzS8CvGi0YFCGBSNadohdCF9gAGdsgvuGJTvkGAgABFxv+wAwcAAQsLAAVPF9lPAAOIF1tWF7qMOp4DBxAABXtIADGAWB0oupGAeAvQABwJmGAwmlwQuZAAQuCF4SYDAgRtBBoeswKsDF7gsEF4+BqovfAANWF5VWFwIvZGAf+EAYuDBooOEF8ANJF/4vREIQv7BxIvZEIwvvBwQveEIIEDF9QA/AH4A/AH4ASA=")
|
||||
require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AGesAAQuuGAQ1jFQoAKF1wwdFyQycF6wwVFi4wWEiOBq1WqoABvQHBvWALsl6p4ADF4IIBGwSNjMAJdCAAVVGwQwPXjWBFoMrF4IwOFzVWp94lV4vIwNFzS8CvGi0YFCGBSNadohdCF9gAGdsgvuGJTvkGAgABFxv+wAwcAAQsLAAVPF9lPAAOIF1tWF7qMOp4DBxAABXtIADGAWB0oupGAeAvQABwJmGAwmlwQuZAAQuCF4SYDAgRtBBoeswKsDF7gsEF4+BqovfAANWF5VWFwIvZGAf+EAYuDBooOEF8ANJF/4vREIQv7BxIvZEIwvvBwQveEIIEDF9QA/AH4A/AH4ASA="))
|
||||
|
|
|
@ -3,7 +3,7 @@ E.setFlags({pretokenise:1});
|
|||
// Load settings...
|
||||
var s = require('Storage').readJSON('setting.json')||{};
|
||||
if (s.ble!==false) {
|
||||
if (s.HID) { // Humen interface device
|
||||
if (s.HID) { // Human interface device
|
||||
Bangle.HID = E.toUint8Array(atob("BQEJBqEBhQIFBxngKecVACUBdQGVCIEClQF1CIEBlQV1AQUIGQEpBZEClQF1A5EBlQZ1CBUAJXMFBxkAKXOBAAkFFQAm/wB1CJUCsQLABQwJAaEBhQEVACUBdQGVAQm1gQIJtoECCbeBAgm4gQIJzYECCeKBAgnpgQIJ6oECwA=="));
|
||||
NRF.setServices({}, {uart:true, hid:Bangle.HID});
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// This runs after a 'fresh' boot
|
||||
var settings={};
|
||||
try { settings = require("Storage").readJSON('setting.json'); } catch (e) {}
|
||||
if (!settings.welcomed && require("Storage").read("-welcome")!==undefined) {
|
||||
setTimeout(()=>load("-welcome"));
|
||||
if (!settings.welcomed && require("Storage").read("welcome.js")!==undefined) {
|
||||
setTimeout(()=>load("welcome.js"));
|
||||
} else {
|
||||
// load clock if specified
|
||||
var clockApp = settings.clock;
|
||||
|
|
|
@ -1 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwgRC/AH4A/gED/k/5/wh/wgAFCBcg7NgAVBh/zDoYLkHaAFqAH4A/AH4AW"));
|
||||
require("heatshrink").decompress(atob("mEwgRC/AH4A/gED/k/5/wh/wgAFCBcg7NgAVBh/zDoYLkHaAFqAH4A/AH4AW"))
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"recording":false,
|
||||
"file":0,
|
||||
"period":1
|
||||
}
|
|
@ -1,5 +1,3 @@
|
|||
NRF.sleep();
|
||||
var g = Graphics.getInstance();
|
||||
g.setFontAlign(1, 1, 0);
|
||||
const d = g.getWidth() - 18;
|
||||
function c(a) {
|
||||
|
@ -53,7 +51,7 @@ function logos() {
|
|||
];
|
||||
function next() {
|
||||
var n = logos.shift();
|
||||
var img = require("Storage").read("*"+n[0]);
|
||||
var img = require("Storage").read("nc-"+n[0]+".img");
|
||||
g.clear();
|
||||
g.drawImage(img, n[1], n[2]);
|
||||
n[3]();
|
||||
|
@ -117,16 +115,11 @@ function info() {
|
|||
}
|
||||
|
||||
function cleanup() {
|
||||
E.showMessage('Loading...');
|
||||
var s = require('Storage');
|
||||
s.erase('*nfr');
|
||||
s.erase('*nceu');
|
||||
s.erase('*bangle');
|
||||
s.erase('*nodew');
|
||||
s.erase('*tf');
|
||||
s.erase('+ncstart');
|
||||
s.erase('.boot3');
|
||||
s.erase('*ncstart');
|
||||
try {
|
||||
var settings = require("Storage").readJSON('setting.json');
|
||||
settings.welcomed = true;
|
||||
require("Storage").write('setting.json',settings);
|
||||
} catch (e) {}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
eval(require("Storage").read("ncstart.app.js"))
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
@ -1 +1 @@
|
|||
var img = require("heatshrink").decompress(atob("mEwxH+AC4fDDjAuSgwACGFIuBhgACGAJjmLoQvDGAJkhbAguGGYwxbRAoAMGDZZMGBAvSbIpdSGCxYCW5jpDHhKSRDYQgGAwY8ETZYvPDZBXEAAwUFNAowOF44bFNJI2ENISRQdIqzLYhAxDAoRgScZgwFdow1DF54tQdpRMDF5jjHLiDxWF44wJBZIJFF5qPGF5blDLxIvPeAjsOF7RgCc6QvId6AvUd5QACF5pyEKAwlGF5qORcIwoFBgIwHFwwvTU4gvILxYuOXwouKA5AwGFxzuIDYYvkDQ6GIABKqEL6ryGF8QbHF6QXFX6wvuYIQvnFJgMBAAQva/wgMBQT4CF5QPCeB65CABgwCHxYuOF6L5JHYYuPSAyDFBRS6TMA4AME4RdHFyhgCLRLoJLzBgDExa7JFywwVFzQwTFwIADGDC5NRohDBSTQdCGCARCGDRNCGRQuFSobAYGAYxIFwoTDGKpMGWggADA4Q1FYipNGGA7NHYawVBD44qDGIbEHIwwlEA="))
|
||||
require("heatshrink").decompress(atob("mEwxH+AC4fDDjAuSgwACGFIuBhgACGAJjmLoQvDGAJkhbAguGGYwxbRAoAMGDZZMGBAvSbIpdSGCxYCW5jpDHhKSRDYQgGAwY8ETZYvPDZBXEAAwUFNAowOF44bFNJI2ENISRQdIqzLYhAxDAoRgScZgwFdow1DF54tQdpRMDF5jjHLiDxWF44wJBZIJFF5qPGF5blDLxIvPeAjsOF7RgCc6QvId6AvUd5QACF5pyEKAwlGF5qORcIwoFBgIwHFwwvTU4gvILxYuOXwouKA5AwGFxzuIDYYvkDQ6GIABKqEL6ryGF8QbHF6QXFX6wvuYIQvnFJgMBAAQva/wgMBQT4CF5QPCeB65CABgwCHxYuOF6L5JHYYuPSAyDFBRS6TMA4AME4RdHFyhgCLRLoJLzBgDExa7JFywwVFzQwTFwIADGDC5NRohDBSTQdCGCARCGDRNCGRQuFSobAYGAYxIFwoTDGKpMGWggADA4Q1FYipNGGA7NHYawVBD44qDGIbEHIwwlEA="))
|
||||
|
|
|
@ -1 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwxH+64A/AH4A/AH4AllYADqAADugAD4QAD5wADxgADnwADF/4v/F/4vMFQg0EFScyAAYv/F/4v/F5l0AAYqEGggqOlgADF/4v/F/4vMFQnOAAYqEGggqJmgADF/4v/F/4vMFRM+AAYqEGggqEnYADF/4v/F/4vMFR0sAAYqEGglrAAYv/F/4v/F5gqTnYADFQg0EF/4v/F/4vMAH4A/AH4A/AH4AIA"));
|
||||
require("heatshrink").decompress(atob("mEwxH+64A/AH4A/AH4AllYADqAADugAD4QAD5wADxgADnwADF/4v/F/4vMFQg0EFScyAAYv/F/4v/F5l0AAYqEGggqOlgADF/4v/F/4vMFQnOAAYqEGggqJmgADF/4v/F/4vMFRM+AAYqEGggqEnYADF/4v/F/4vMFR0sAAYqEGglrAAYv/F/4v/F5gqTnYADFQg0EF/4v/F/4vMAH4A/AH4A/AH4AIA"))
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
eval(require("Storage").read("welcome.app.js"))
|
|
@ -0,0 +1,82 @@
|
|||
#!/usr/bin/nodejs
|
||||
/* Checks for any obvious problems in apps.json
|
||||
*/
|
||||
|
||||
var fs = require("fs");
|
||||
var acorn;
|
||||
try {
|
||||
acorn = require("acorn");
|
||||
} catch (e) {
|
||||
console.log("=====================================================");
|
||||
console.log(" ACORN NOT FOUND");
|
||||
console.log(" ---------------");
|
||||
console.log("");
|
||||
console.log(" This means we won't sanity-check uploaded JSON");
|
||||
console.log("=====================================================");
|
||||
}
|
||||
|
||||
var BASEDIR = __dirname+"/../";
|
||||
var APPSDIR = BASEDIR+"apps/";
|
||||
function ERROR(s) {
|
||||
console.error(s);
|
||||
process.exit(1);
|
||||
}
|
||||
function WARN(s) {
|
||||
console.log(s);
|
||||
}
|
||||
|
||||
var appsFile, apps;
|
||||
try {
|
||||
appsFile = fs.readFileSync(BASEDIR+"apps.json");
|
||||
} catch (e) {
|
||||
ERROR("apps.json not found");
|
||||
}
|
||||
try{
|
||||
apps = JSON.parse(appsFile);
|
||||
} catch (e) {
|
||||
ERROR("apps.json not valid JSON");
|
||||
}
|
||||
|
||||
apps.forEach((app,addIdx) => {
|
||||
if (!app.id) ERROR(`App ${appIdx} has no id`);
|
||||
console.log(`Checking ${app.id}...`);
|
||||
var appDir = APPSDIR+app.id+"/";
|
||||
if (!fs.existsSync(APPSDIR+app.id)) ERROR(`App ${app.id} has no directory`);
|
||||
if (!app.name) ERROR(`App ${app.id} has no name`);
|
||||
var isApp = !app.type || app.type=="app";
|
||||
if (app.name.length>20 && !app.shortName && isApp) ERROR(`App ${app.id} has a long name, but no shortName`);
|
||||
if (!app.version) WARN(`App ${app.id} has no version`);
|
||||
if (!app.description) ERROR(`App ${app.id} has no description`);
|
||||
if (!app.icon) ERROR(`App ${app.id} has no icon`);
|
||||
if (!fs.existsSync(appDir+app.icon)) ERROR(`App ${app.id} icon doesn't exist`);
|
||||
if (app.custom && !fs.existsSync(appDir+app.custom)) ERROR(`App ${app.id} custom HTML doesn't exist`);
|
||||
if (app.interface && !fs.existsSync(appDir+app.interface)) ERROR(`App ${app.id} interface HTML doesn't exist`);
|
||||
var fileNames = [];
|
||||
app.storage.forEach((file) => {
|
||||
if (!file.name) ERROR(`App ${app.id} has a file with no name`);
|
||||
if (fileNames.includes(file.name))
|
||||
ERROR(`App ${app.id} file ${file.name} is a duplicate`);
|
||||
fileNames.push(file.name);
|
||||
if (file.url) if (!fs.existsSync(appDir+file.url)) ERROR(`App ${app.id} file ${file.url} doesn't exist`);
|
||||
if (!file.url && !file.content && !app.custom) ERROR(`App ${app.id} file ${file.name} has no contents`);
|
||||
if (file.evaluate) {
|
||||
var fileContents = file.content ? file.content : fs.readFileSync(appDir+file.url).toString();
|
||||
try {
|
||||
acorn.parse("("+fileContents+")");
|
||||
} catch(e) {
|
||||
console.log("=====================================================");
|
||||
console.log(" PARSE OF "+appDir+file.url+" failed.");
|
||||
console.log("");
|
||||
console.log(e);
|
||||
console.log("=====================================================");
|
||||
console.log(fileContents);
|
||||
console.log("=====================================================");
|
||||
ERROR(`App ${app.id}'s ${file.name} has evaluate:true but is not valid JS expression`);
|
||||
}
|
||||
}
|
||||
});
|
||||
//console.log(fileNames);
|
||||
if (isApp && !fileNames.includes(app.id+".app.js")) ERROR(`App ${app.id} has no entrypoint`);
|
||||
if (isApp && !fileNames.includes(app.id+".img")) ERROR(`App ${app.id} has no JS icon`);
|
||||
if (app.type=="widget" && !fileNames.includes(app.id+".wid.js")) ERROR(`Widget ${app.id} has no entrypoint`);
|
||||
});
|
2
comms.js
2
comms.js
|
@ -3,7 +3,7 @@ Puck.debug=3;
|
|||
// FIXME: use UART lib so that we handle errors properly
|
||||
var Comms = {
|
||||
reset : () => new Promise((resolve,reject) => {
|
||||
Puck.write("\x03reset();\n", (result) => {
|
||||
Puck.write("\x03\x10reset();\n", (result) => {
|
||||
if (result===null) return reject("");
|
||||
setTimeout(resolve,500);
|
||||
});
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
|
||||
<div class="container" style="padding-top:4px">
|
||||
<p><span class="label label-error">App Loader is incompatible with 'old' Bangle.js firmwares</span>
|
||||
Please <a href="https://www.espruino.com/Bangle.js#firmware-updates" target="_blank">(<a href="http://forum.espruino.com/conversations/344251/" target="_blank">more info</a>)Update to the latest firmware</a> or
|
||||
<a href="https://www.espruino.com/Bangle.js#firmware-updates" target="_blank">(<a href="http://forum.espruino.com/conversations/344251/" target="_blank">more info</a>) Please update to the latest firmware</a> or
|
||||
<a href="https://banglejs.com/oldapps/">use the legacy apps</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue