1
0
Fork 0

support for 'supports:["DEVICEID"]` for files in apps, merge launchb2 and launch

master
Gordon Williams 2021-10-28 12:14:02 +01:00
parent 375cbf3166
commit eefa209af4
12 changed files with 63 additions and 43 deletions

View File

@ -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

View File

@ -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": [

View File

@ -5,3 +5,4 @@
0.05: Use g.theme for colours
0.06: Use Bangle.setUI for buttons
0.07: Theme colours fix
0.08: Merge Bangle.js 1 and 2 launchers

View File

@ -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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 899 B

View File

@ -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);
});

View File

@ -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);
});

View File

@ -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',
'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 = [];

View File

@ -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);
});

2
core

@ -1 +1 @@
Subproject commit a7d82825d3a43e1da7919591ed6fa776f1f0545a
Subproject commit 70b49d8dbd2afa76f4485aadf679dc75e0a8b4ac