diff --git a/README.md b/README.md index d60d46fd3..531114a34 100644 --- a/README.md +++ b/README.md @@ -262,6 +262,9 @@ and which gives information about the app for the Launcher. // (eg it's evaluated as JS) "noOverwrite":true // if supplied, this file will not be overwritten if it // already exists + "supports": ["BANGLEJS2"]// if supplied, this file will ONLY be uploaded to the device + // types named in the array. This allows different versions of + // the app to be uploaded for different platforms }, ] "data": [ // list of files the app writes to diff --git a/apps.json b/apps.json index d1ebe5249..7593a4b63 100644 --- a/apps.json +++ b/apps.json @@ -94,31 +94,17 @@ }, { "id": "launch", - "name": "Launcher (Bangle.js 1 default)", + "name": "Launcher", "shortName": "Launcher", - "version": "0.07", - "description": "This is needed by Bangle.js 1.0 to display a menu allowing you to choose your own applications. You can replace this with a customised launcher.", + "version": "0.08", + "description": "This is needed to display a menu allowing you to choose your own applications. You can replace this with a customised launcher.", "icon": "app.png", "type": "launch", "tags": "tool,system,launcher", "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ - {"name":"launch.app.js","url":"app.js"} - ], - "sortorder": -10 - }, - { - "id": "launchb2", - "name": "Launcher (Bangle.js 2 default)", - "shortName": "Launcher", - "version": "0.04", - "description": "This is needed by Bangle.js 2.0 to display a menu allowing you to choose your own applications.", - "icon": "app.png", - "type": "launch", - "tags": "tool,system,launcher", - "supports": ["BANGLEJS2"], - "storage": [ - {"name":"launchb2.app.js","url":"app.js"} + {"name":"launch.app.js","url":"app-bangle1.js","supports":["BANGLEJS"]}, + {"name":"launch.app.js","url":"app-bangle2.js","supports":["BANGLEJS2"]} ], "sortorder": -10 }, @@ -4114,7 +4100,7 @@ "description": "A touch based stop watch for Bangle JS 2", "icon": "stopwatch.png", "screenshots": [{"url":"screenshot1.png"},{"url":"screenshot2.png"},{"url":"screenshot3.png"}], - "tags": "tools,app,b2", + "tags": "tools,app", "supports": ["BANGLEJS2"], "readme": "README.md", "storage": [ diff --git a/apps/launch/ChangeLog b/apps/launch/ChangeLog index 09569d8da..bd8a9bd03 100644 --- a/apps/launch/ChangeLog +++ b/apps/launch/ChangeLog @@ -4,4 +4,5 @@ 0.04: Now displays widgets 0.05: Use g.theme for colours 0.06: Use Bangle.setUI for buttons -0.07: Theme colours fix \ No newline at end of file +0.07: Theme colours fix +0.08: Merge Bangle.js 1 and 2 launchers diff --git a/apps/launch/app.js b/apps/launch/app-bangle1.js similarity index 100% rename from apps/launch/app.js rename to apps/launch/app-bangle1.js diff --git a/apps/launchb2/app.js b/apps/launch/app-bangle2.js similarity index 100% rename from apps/launchb2/app.js rename to apps/launch/app-bangle2.js diff --git a/apps/launchb2/ChangeLog b/apps/launchb2/ChangeLog deleted file mode 100644 index a84587b7e..000000000 --- a/apps/launchb2/ChangeLog +++ /dev/null @@ -1,4 +0,0 @@ -0.01: New App! -0.02: Fix occasional missed image when scrolling up -0.03: Text wrapping, better font -0.04: Reduce code duplication and use new E.showScroller diff --git a/apps/launchb2/app.png b/apps/launchb2/app.png deleted file mode 100644 index 8b4e6caa2..000000000 Binary files a/apps/launchb2/app.png and /dev/null differ diff --git a/bin/firmwaremaker.js b/bin/firmwaremaker.js index 4e22dd168..4bc2a70b2 100755 --- a/bin/firmwaremaker.js +++ b/bin/firmwaremaker.js @@ -12,6 +12,7 @@ var ROOTDIR = path.join(__dirname, '..'); var APPDIR = ROOTDIR+'/apps'; var APPJSON = ROOTDIR+'/apps.json'; var OUTFILE = ROOTDIR+'/firmware.js'; +var DEVICE = "BANGLEJS"; var APPS = [ // IDs of apps to install "boot","launch","mclock","setting", "about","alarm","widbat","widbt","welcome" @@ -61,7 +62,8 @@ Promise.all(APPS.map(appid => { if (app===undefined) throw new Error(`App ${appid} not found`); return AppInfo.getFiles(app, { fileGetter : fileGetter, - settings : SETTINGS + settings : SETTINGS, + device : { id : DEVICE } }).then(files => { appfiles = appfiles.concat(files); }); diff --git a/bin/firmwaremaker_c.js b/bin/firmwaremaker_c.js index 15092ced7..7fb842755 100755 --- a/bin/firmwaremaker_c.js +++ b/bin/firmwaremaker_c.js @@ -29,7 +29,7 @@ if (DEVICE=="BANGLEJS") { } else if (DEVICE=="BANGLEJS2") { var OUTFILE = path.join(ROOTDIR, '../Espruino/libs/banglejs/banglejs2_storage_default.c'); var APPS = [ // IDs of apps to install - "boot","launchb2","s7clk","setting", + "boot","launch","s7clk","setting", "about","alarm","widlock","widbat","widbt","widid" ]; } else { @@ -132,7 +132,8 @@ Promise.all(APPS.map(appid => { if (app===undefined) throw new Error(`App ${appid} not found`); return AppInfo.getFiles(app, { fileGetter : fileGetter, - settings : SETTINGS + settings : SETTINGS, + device : { id : DEVICE } }).then(files => { appfiles = appfiles.concat(files); }); diff --git a/bin/sanitycheck.js b/bin/sanitycheck.js index dbce9c855..ef795871d 100755 --- a/bin/sanitycheck.js +++ b/bin/sanitycheck.js @@ -50,12 +50,12 @@ try{ } const APP_KEYS = [ - 'id', 'name', 'shortName', 'version', 'icon', 'description', 'tags', 'type', + 'id', 'name', 'shortName', 'version', 'icon', 'screenshots', 'description', 'tags', 'type', 'sortorder', 'readme', 'custom', 'customConnect', 'interface', 'storage', 'data', - 'supports', 'allow_emulator', + 'supports', 'allow_emulator', 'dependencies' ]; -const STORAGE_KEYS = ['name', 'url', 'content', 'evaluate', 'noOverwite']; +const STORAGE_KEYS = ['name', 'url', 'content', 'evaluate', 'noOverwite', 'supports']; const DATA_KEYS = ['name', 'wildcard', 'storageFile', 'url', 'content', 'evaluate']; const FORBIDDEN_FILE_NAME_CHARS = /[,;]/; // used as separators in appid.info const VALID_DUPLICATES = [ '.tfmodel', '.tfnames' ]; @@ -107,6 +107,13 @@ apps.forEach((app,appIdx) => { 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.screenshots) { + if (!Array.isArray(app.screenshots)) ERROR(`App ${app.id} screenshots is not an array`); + app.screenshots.forEach(screenshot => { + if (!fs.existsSync(appDir+screenshot.url)) + ERROR(`App ${app.id} screenshot file ${screenshot.url} not found`); + }); + } if (app.readme && !fs.existsSync(appDir+app.readme)) ERROR(`App ${app.id} README file doesn't exist`); if (app.custom && !fs.existsSync(appDir+app.custom)) ERROR(`App ${app.id} custom HTML doesn't exist`); if (app.customConnect && !app.custom) ERROR(`App ${app.id} has customConnect but no customn HTML`); @@ -128,13 +135,14 @@ apps.forEach((app,appIdx) => { if (char) ERROR(`App ${app.id} storage file ${file.name} contains invalid character "${char[0]}"`) if (fileNames.includes(file.name)) ERROR(`App ${app.id} file ${file.name} is a duplicate`); - fileNames.push(file.name); + if (!file.supports) fileNames.push(file.name); // assume that there aren't duplicates if 'supports' is set allFiles.push({app: app.id, file: 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`); var fileContents = ""; if (file.content) fileContents = file.content; if (file.url) fileContents = fs.readFileSync(appDir+file.url).toString(); + if (file.supports && !Array.isArray(file.supports)) ERROR(`App ${app.id} file ${file.name} supports field is not an array`); if (file.evaluate) { try { acorn.parse("("+fileContents+")"); @@ -165,7 +173,7 @@ apps.forEach((app,appIdx) => { } } for (const key in file) { - if (!STORAGE_KEYS.includes(key)) ERROR(`App ${app.id}'s ${file.name} has unknown key ${key}`); + if (!STORAGE_KEYS.includes(key)) ERROR(`App ${app.id} file ${file.name} has unknown key ${key}`); } }); let dataNames = []; diff --git a/bin/thumbnailer.js b/bin/thumbnailer.js index db658b01e..b6862741a 100755 --- a/bin/thumbnailer.js +++ b/bin/thumbnailer.js @@ -1,6 +1,11 @@ #!/usr/bin/node +/* +var EMULATOR = "banglejs2"; +var DEVICEID = "BANGLEJS2"; +*/ var EMULATOR = "banglejs1"; +var DEVICEID = "BANGLEJS"; var singleAppId; @@ -40,6 +45,10 @@ var apps = JSON.parse(require("fs").readFileSync(__dirname+"/../apps.json")); /* we factory reset ONCE, get this, then we can use it to reset state quickly for each new app */ var factoryFlashMemory = new Uint8Array(FLASH_SIZE); +// Log of messages from app +var appLog = ""; +// List of apps that errored +var erroredApps = []; jsRXCallback = function() {}; jsUpdateGfx = function() {}; @@ -49,6 +58,10 @@ function ERROR(s) { process.exit(1); } +function onConsoleOutput(txt) { + appLog += txt + "\n"; +} + function getThumbnail(appId, imageFn) { console.log("Thumbnail for "+appId); var app = apps.find(a=>a.id==appId); @@ -61,7 +74,10 @@ function getThumbnail(appId, imageFn) { fileGetter:function(url) { console.log(__dirname+"/"+url); return Promise.resolve(require("fs").readFileSync(__dirname+"/../"+url).toString("binary")); - }, settings : SETTINGS}).then(files => { + }, + settings : SETTINGS, + device : { id : DEVICEID } + }).then(files => { console.log("AppInfo returned");//, files); flashMemory.set(factoryFlashMemory); jsTransmitString("reset()\n"); @@ -69,6 +85,7 @@ function getThumbnail(appId, imageFn) { jsTransmitString("g.clear()\n"); var command = files.map(f=>f.cmd).join("\n")+"\n"; command += `load("${appId}.app.js")\n`; + appLog = ""; jsTransmitString(command); console.log("Done."); jsStopIdle(); @@ -79,6 +96,9 @@ function getThumbnail(appId, imageFn) { var firstPixel = rgba32[0]; var blankImage = rgba32.every(col=>col==firstPixel) + if (appLog.indexOf("Uncaught")>=0) + erroredApps.push( { id : app.id, log : appLog } ); + if (!blankImage) { var Jimp = require("jimp"); let image = new Jimp(GFX_WIDTH, GFX_HEIGHT, function (err, image) { @@ -113,20 +133,22 @@ setTimeout(function() { console.log("Ready!"); if (singleAppId) { - getThumbnail(singleAppId, "screenshots/"+singleAppId+".png") - + getThumbnail(singleAppId, "screenshots/"+singleAppId+"-"+EMULATOR+".png"); return; } - var appList = apps.filter(app => (!app.type || app.type=="clock") && !app.custom).map(app=>app.id); - // TODO: Work out about Bangle.js 1 or 2 + var appList = apps.filter(app => (!app.type || app.type=="clock") && !app.custom); + appList = appList.filter(app => !app.screenshots && app.supports.includes(DEVICEID)); + var promise = Promise.resolve(); - appList.forEach(appId => { + appList.forEach(app => { promise = promise.then(() => { - return getThumbnail(appId, "screenshots/"+appId+".png").then(ok => { + var imageFile = "screenshots/"+app.id+"-"+EMULATOR+".png"; + return getThumbnail(app.id, imageFile).then(ok => { screenshots.push({ - id : appId, - url : "screenshots/"+appId+".png" + id : app.id, + url : imageFile, + version: app.version }); }); }); @@ -135,6 +157,7 @@ setTimeout(function() { promise.then(function() { console.log("Complete!"); require("fs").writeFileSync("screenshots.json", JSON.stringify(screenshots,null,2)); + console.log("Errored Apps", erroredApps); }); diff --git a/core b/core index a7d82825d..70b49d8db 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit a7d82825d3a43e1da7919591ed6fa776f1f0545a +Subproject commit 70b49d8dbd2afa76f4485aadf679dc75e0a8b4ac