From 50e3c852fbd011af4b62ede4d342a4307647884b Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 28 Feb 2020 11:44:25 +0000 Subject: [PATCH] MASSIVE REFACTOR New Bangle.js firmwares remove 8 char name restriction so we're ditching the first char -> file type and using normal file extensions Took the opportunity to remove code for older Bangle.js (since the new stuff won't work anyway) Also removed the need for an 'app.json' - it's now renamed 'app.info' on the watch, and we just auto-generate it Renamed a few apps so widgets all start with 'wid' --- README.md | 101 +++--- appinfo.js | 46 ++- apps.json | 342 ++++++++---------- apps/_example_app/add_to_apps.json | 1 + apps/_example_app/app.json | 5 - apps/_example_widget/add_to_apps.json | 2 + apps/_example_widget/widget.json | 4 - apps/about/app.json | 5 - apps/aclock/clock-analog.json | 6 - apps/alarm/app.js | 14 +- apps/alarm/app.json | 5 - apps/alarm/widget.js | 2 +- apps/animals/animals.js | 2 +- apps/animals/animals.json | 5 - apps/astroid/asteroids.json | 5 - apps/bclock/clock-binary.json | 7 - apps/beer/beercompass.html | 12 +- apps/berlinc/berlin-clock.json | 6 - apps/blescan/blescan.json | 7 - apps/blobclk/clock-blob.json | 7 - apps/boldclk/bold_clock.json | 7 - apps/boot/boot0.js | 54 +-- apps/boot/bootloader.js | 4 +- apps/boot/bootloader.json | 3 - apps/clck3x2/clock3x2.json | 6 - apps/clickms/click-master.json | 5 - apps/clotris/clock-tris.json | 5 - apps/compass/compass.json | 5 - apps/ctrclk/app.json | 6 - apps/cube/cube.json | 6 - apps/demoapp/app.json | 5 - apps/files/files.js | 4 +- apps/files/files.json | 5 - apps/flagrse/app.json | 5 - apps/flappy/app.json | 5 - apps/gbridge/app.json | 5 - apps/gesture/gesture.json | 5 - apps/gpsinfo/gps-info.json | 6 - apps/gpsrec/app-settings.json | 5 - apps/gpsrec/app.js | 4 +- apps/gpsrec/app.json | 5 - apps/gpsrec/widget.js | 2 +- apps/gpstime/gpstime.json | 5 - apps/hidbkbd/hid-binary-keyboard.js | 2 +- apps/hidbkbd/hid-binary-keyboard.json | 5 - apps/hidkbd/hid-keyboard.js | 2 +- apps/hidkbd/hid-keyboard.json | 5 - apps/hidmsic/hid-music.js | 2 +- apps/hidmsic/hid-music.json | 5 - apps/horsey/horse-race.json | 5 - apps/hrings/hypno-rings.json | 5 - apps/hrm/heartrate.json | 5 - apps/jbells/jbells.json | 5 - apps/launch/app.js | 2 +- apps/launch/app.json | 4 - apps/mclock/clock-morphing.json | 6 - apps/miclock/clock-mixed.json | 6 - apps/mmonday/manic-monday.json | 5 - apps/morse/morse-code.json | 5 - apps/nceuwid/nceu-widget.json | 5 - apps/ncfrun/nceu-funrun.json | 6 - apps/ncstart/start.json | 6 - apps/nyancat/code.js | 0 apps/openloc/openlocation.json | 5 - apps/pipboy/app.json | 5 - apps/pomodo/pomodoro.json | 5 - apps/pparrot/party-parrot.json | 5 - apps/qrcode/qrcode.html | 12 +- apps/route/route.html | 12 +- apps/sbat/widget-battery.json | 4 - apps/sbt/widget-bluetooth.json | 4 - apps/sclock/clock-simple.js | 2 +- apps/sclock/clock-simple.json | 7 - apps/scolor/show-color.json | 5 - apps/setting/settings.js | 8 +- apps/setting/settings.json | 6 - apps/slevel/spiritlevel.json | 5 - apps/speedo/speedo.json | 5 - apps/stetho/stetho.json | 5 - apps/swatch/stopwatch.json | 5 - apps/trex/trex.json | 5 - apps/wclock/clock-word.json | 6 - apps/wdclk/digital_clock_widget.json | 5 - apps/welcome/app.js | 4 +- apps/welcome/app.json | 5 - apps/whrm/widget.json | 4 - apps/{sbat => widbat}/ChangeLog | 0 .../widget-battery.js => widbat/widget.js} | 0 .../widget-battery.png => widbat/widget.png} | Bin .../widget-bluetooth.js => widbt/widget.js} | 0 .../widget-bluetooth.png => widbt/widget.png} | Bin .../widget.js} | 0 .../widget.png} | Bin apps/{whrm => widhrm}/ChangeLog | 0 apps/{whrm => widhrm}/widget.js | 0 apps/{whrm => widhrm}/widget.png | Bin .../nceu-widget.js => widnceu/widget.js} | 0 .../nceu-widget.png => widnceu/widget.png} | Bin apps/wpedom/pedometer_widget.json | 5 - .../wpedom/{pedometer_widget.js => widget.js} | 2 +- .../{pedometer_widget.png => widget.png} | Bin comms.js | 30 +- defaultapps.json | 2 +- firmware.js | 10 +- index.html | 2 +- index.js | 20 +- 106 files changed, 289 insertions(+), 743 deletions(-) delete mode 100644 apps/_example_app/app.json delete mode 100644 apps/_example_widget/widget.json delete mode 100644 apps/about/app.json delete mode 100644 apps/aclock/clock-analog.json delete mode 100644 apps/alarm/app.json delete mode 100644 apps/animals/animals.json delete mode 100644 apps/astroid/asteroids.json delete mode 100644 apps/bclock/clock-binary.json delete mode 100644 apps/berlinc/berlin-clock.json delete mode 100644 apps/blescan/blescan.json delete mode 100644 apps/blobclk/clock-blob.json delete mode 100644 apps/boldclk/bold_clock.json delete mode 100644 apps/boot/bootloader.json delete mode 100644 apps/clck3x2/clock3x2.json delete mode 100644 apps/clickms/click-master.json delete mode 100644 apps/clotris/clock-tris.json delete mode 100644 apps/compass/compass.json delete mode 100644 apps/ctrclk/app.json delete mode 100644 apps/cube/cube.json delete mode 100644 apps/demoapp/app.json delete mode 100644 apps/files/files.json delete mode 100644 apps/flagrse/app.json delete mode 100644 apps/flappy/app.json delete mode 100644 apps/gbridge/app.json delete mode 100644 apps/gesture/gesture.json delete mode 100644 apps/gpsinfo/gps-info.json delete mode 100644 apps/gpsrec/app-settings.json delete mode 100644 apps/gpsrec/app.json delete mode 100644 apps/gpstime/gpstime.json delete mode 100644 apps/hidbkbd/hid-binary-keyboard.json delete mode 100644 apps/hidkbd/hid-keyboard.json delete mode 100644 apps/hidmsic/hid-music.json delete mode 100644 apps/horsey/horse-race.json delete mode 100644 apps/hrings/hypno-rings.json delete mode 100644 apps/hrm/heartrate.json delete mode 100644 apps/jbells/jbells.json delete mode 100644 apps/launch/app.json delete mode 100644 apps/mclock/clock-morphing.json delete mode 100644 apps/miclock/clock-mixed.json delete mode 100644 apps/mmonday/manic-monday.json delete mode 100644 apps/morse/morse-code.json delete mode 100644 apps/nceuwid/nceu-widget.json delete mode 100644 apps/ncfrun/nceu-funrun.json delete mode 100644 apps/ncstart/start.json create mode 100644 apps/nyancat/code.js delete mode 100644 apps/openloc/openlocation.json delete mode 100644 apps/pipboy/app.json delete mode 100644 apps/pomodo/pomodoro.json delete mode 100644 apps/pparrot/party-parrot.json delete mode 100644 apps/sbat/widget-battery.json delete mode 100644 apps/sbt/widget-bluetooth.json delete mode 100644 apps/sclock/clock-simple.json delete mode 100644 apps/scolor/show-color.json delete mode 100644 apps/setting/settings.json delete mode 100644 apps/slevel/spiritlevel.json delete mode 100644 apps/speedo/speedo.json delete mode 100644 apps/stetho/stetho.json delete mode 100644 apps/swatch/stopwatch.json delete mode 100644 apps/trex/trex.json delete mode 100644 apps/wclock/clock-word.json delete mode 100644 apps/wdclk/digital_clock_widget.json delete mode 100644 apps/welcome/app.json delete mode 100644 apps/whrm/widget.json rename apps/{sbat => widbat}/ChangeLog (100%) rename apps/{sbat/widget-battery.js => widbat/widget.js} (100%) rename apps/{sbat/widget-battery.png => widbat/widget.png} (100%) rename apps/{sbt/widget-bluetooth.js => widbt/widget.js} (100%) rename apps/{sbt/widget-bluetooth.png => widbt/widget.png} (100%) rename apps/{wdclk/digital_clock_widget.js => widclk/widget.js} (100%) rename apps/{wdclk/digital_clock_widget.png => widclk/widget.png} (100%) rename apps/{whrm => widhrm}/ChangeLog (100%) rename apps/{whrm => widhrm}/widget.js (100%) rename apps/{whrm => widhrm}/widget.png (100%) rename apps/{nceuwid/nceu-widget.js => widnceu/widget.js} (100%) rename apps/{nceuwid/nceu-widget.png => widnceu/widget.png} (100%) delete mode 100644 apps/wpedom/pedometer_widget.json rename apps/wpedom/{pedometer_widget.js => widget.js} (98%) rename apps/wpedom/{pedometer_widget.png => widget.png} (100%) diff --git a/README.md b/README.md index f79c8d4d4b..1f985fa65b 100644 --- a/README.md +++ b/README.md @@ -17,11 +17,11 @@ listed in `apps.json`, loads them, and sends them over Web Bluetooth. Filenames in storage are limited to 8 characters. To easily distinguish between file types, we use the following: -* `+stuff` is JSON for an app -* `*stuff` is an image -* `-stuff` is JS code -* `=stuff` is JS code for stuff that is run at boot time - eg. handling settings or creating widgets on the clock screen -* `@stuff` is used for JSON settings for an app +* `stuff.info` is JSON that describes an app - this is auto-generated by the App Loader +* `stuff.img` is an image +* `stuff.app.js` is JS code +* `stuff.wid.js` is JS code for widgets +* `stuff.json` is used for JSON settings for an app ## Developing your own app @@ -32,35 +32,25 @@ easily distinguish between file types, we use the following: ## Adding your app to the menu -* Come up with a unique 7 character name, we'll assume `7chname` +* Come up with a unique (all lowercase, nu spaces) name, we'll assume `7chname`. Bangle.js +is limited to 28 char filenames and appends a file extension (eg `.js`) so please +try and keep filenames short to avoid overflowing the buffer. * Create a folder called `apps/`, lets assume `apps/7chname` * We'd recommend that you copy files from 'Example Applications' (below) as a base, or... * `apps/7chname/app.png` should be a 48px icon * Use http://www.espruino.com/Image+Converter to create `apps/7chname/app-icon.js`, using a 1 bit, 4 bit or 8 bit Web Palette "Image String" -* Create an entry in `apps/7chname/app.json` as follows: - -``` -{ - "name":"Short Name", - "icon":"*7chname", - "src":"-7chname" -} -``` - -See `app.json / widget.json` below for more info on the correct format. - * Create an entry in `apps.json` as follows: ``` { "id": "7chname", "name": "My app's human readable name", + "shortName" : "Short Name", "icon": "app.png", "description": "A detailed description of my great app", "tags": "", "storage": [ - {"name":"+7chname","url":"app.json"}, - {"name":"-7chname","url":"app.js"}, - {"name":"*7chname","url":"app-icon.js","evaluate":true} + {"name":"7chname.app.js","url":"app.js"}, + {"name":"7chname.img","url":"app-icon.js","evaluate":true} ], }, ``` @@ -81,32 +71,26 @@ Be aware of the delay between commits and updates on github.io - it can take a f ### Offline -You can add the following to the Espruino Web IDE: +Using the 'Storage' icon in [the Web IDE](https://www.espruino.com/ide/) +(4 discs), upload your files into the places described in your JSON: -``` -// replace with your 7chname app name -var appname = "mygreat"; - -require("Storage").write('*'+appname, - // place app-icon.js contents here -); - -// -require("Storage").write("+"+appname,{ - "name":"My Great App","type":"", - "icon":"*"+appname, - "src":"-"+appname, -}); - -require("Storage").write("-"+appname,` -// place contents of app.js here -// be aware of double-quoting templated strings -` -``` +* `app-icon.js` -> `7chname.img` + +Now load `app.js` up in the editor, and click the down-arrow to the bottom +right of the `Send to Espruino` icon. Click `Storage` and then either choose +`7chname.app.js` (if you'd uploaded your app previously), or `New File` +and then enter `7chname.app.js` as the name. + +Now, clicking the `Send to Espruino` icon will load the app directly into +Espruino **and** will automatically run it. -When you upload code this way, your app will be uploaded to Bangle.js's menu +When you upload code this way, your app will even be uploaded to Bangle.js's menu without you having to use the `Bangle App Loader` +**Note:** Widgets need to be run inside a clock or app, so if you're +developing a widget you need to go go `Settings` -> `Communications` -> `Load after saving` +and set it to `Load default application`. + ## Example Applications To make the process easier we've come up with some example applications that you can use as a base @@ -114,21 +98,23 @@ when creating your own. Just come up with a unique 7 character name, copy `apps/ or `apps/_example_widget` to `apps/7chname`, and add `apps/_example_X/add_to_apps.json` to `apps.json`. +**If you're making a widget** please start the name with `wid` to make +it easy to find! + ### App Example The app example is available in [`apps/_example_app`](apps/_example_app) Apps are listed in the Bangle.js menu, accessible from a clock app via the middle button. -* `add_to_apps.json` - insert into `apps.json`, describes the widget to bootloader and loader +* `add_to_apps.json` - insert into `apps.json`, describes the app to bootloader and loader * `app.png` - app icon - 48x48px * `app-icon.js` - JS version of the icon (made with http://www.espruino.com/Image+Converter) for use in Bangle.js's menu -* `app.json` - short app name for Bangle.js menu and storage filenames * `app.js` - app code #### `app-icon.js` -The icon image and short description is used in the menu entry as selection posibility. +The icon image and short description is used in the menu entry as selection possibility. Use the Espruino [image converter](https://www.espruino.com/Image+Converter) and upload your `app.png` file. @@ -155,13 +141,12 @@ Keep in mind to use this converter for creating images you like to draw with `g. The widget example is available in [`apps/_example_widget`](apps/_example_widget) * `add_to_apps.json` - insert into `apps.json`, describes the widget to bootloader and loader -* `widget.json` - short widget name and storage names * `widget.js` - widget code -### `app.json` / `widget.json` format +### `app.info` format -This is the file that's loaded onto Bangle.js, which gives information -about the app. +This is the file that's **auto-generated** and loaded onto Bangle.js by the App Loader, +and which gives information about the app for the Launcher. ``` { @@ -184,9 +169,10 @@ about the app. ``` { "id": "appid", // 7 character app id "name": "Readable name", // readable name + "shortName": "Short name", // short name for launcher "icon": "icon.png", // icon in apps/ "description": "...", // long description - "type":"...", // optional(if app) - 'app'/'widget'/'launch' + "type":"...", // optional(if app) - 'app'/'widget'/'launch'/'bootloader' "tags": "", // comma separated tag list for searching "custom": "custom.html", // if supplied, apps/custom.html is loaded in an @@ -203,7 +189,7 @@ about the app. // add an icon to allow your app to be tested "storage": [ // list of files to add to storage - {"name":"-appid", // filename to use in storage + {"name":"appid.js", // filename to use in storage "url":"", // URL of file to load (currently relative to apps/) "content":"..." // if supplied, this content is loaded directly "evaluate":true // if supplied, data isn't quoted into a String before upload @@ -245,13 +231,8 @@ version of what's in `apps.json`: sendCustomizedApp({ id : "7chname", storage:[ - {name:"-7chname", content:app_source_code}, - {name:"+7chname", content:JSON.stringify({ - name:"My app's name", - icon:"*7chname", - src:"-7chname" - })}, - {name:"*7chname", content:'require("heatshrink").decompress(atob("mEwg...4"))', evaluate:true}, + {name:"7chname.app.js", content:app_source_code}, + {name:"7chname.img", content:'require("heatshrink").decompress(atob("mEwg...4"))', evaluate:true}, ] }); }); @@ -299,7 +280,7 @@ 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`, then load it at startup. +- 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" diff --git a/appinfo.js b/appinfo.js index 7d49647fe2..151227f450 100644 --- a/appinfo.js +++ b/appinfo.js @@ -20,21 +20,12 @@ var AppInfo = { })).then(fileContents => { // now we just have a list of files + contents... // filter out empty files fileContents = fileContents.filter(x=>x!==undefined); + // What about minification? + // Add app's info JSON + return AppInfo.createAppJSON(app, fileContents); + }).then(fileContents => { // then map each file to a command to load into storage fileContents.forEach(storageFile => { - // check if this is the JSON file - if (storageFile.name[0]=="+") { - storageFile.evaluate = true; - var json = {}; - try { - json = JSON.parse(storageFile.content); - } catch (e) { - reject(storageFile.name+" is not valid JSON"); - } - if (app.version) json.version = app.version; - json.files = fileContents.map(storageFile=>storageFile.name).join(","); - storageFile.content = JSON.stringify(json); - } // format ready for Espruino var js; if (storageFile.evaluate) { @@ -49,6 +40,35 @@ var AppInfo = { }).catch(err => reject(err)); }); }, + createAppJSON : (app, fileContents) => { + return new Promise((resolve,reject) => { + var appJSONName = app.id+".info"; + // Check we don't already have a JSON file! + var appJSONFile = fileContents.find(f=>f.name==appJSONName); + if (appJSONFile) reject("App JSON file explicitly specified!"); + // Now actually create the app JSON + var json = { + id : app.id + }; + if (app.shortName) json.name = app.shortName; + else json.name = app.name; + if (app.type && app.type!="app") json.type = app.type; + if (fileContents.find(f=>f.name==app.id+".app.js")) + json.src = app.id+".app.js"; + if (fileContents.find(f=>f.name==app.id+".img")) + json.icon = app.id+".img"; + if (app.sortorder) json.sortorder = app.sortorder; + if (app.version) json.version = app.version; + var fileList = fileContents.map(storageFile=>storageFile.name); + fileList.unshift(appJSONName); // do we want this? makes life easier! + json.files = fileList.join(","); + fileContents.push({ + name : appJSONName, + content : JSON.stringify(json) + }); + resolve(fileContents); + }); + } }; if ("undefined"!=typeof module) diff --git a/apps.json b/apps.json index e1403f0f85..68c101c3ee 100644 --- a/apps.json +++ b/apps.json @@ -5,22 +5,23 @@ "version":"0.06", "description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings", "tags": "tool,system", + "type":"bootloader", "storage": [ {"name":".boot0","url":"boot0.js"}, - {"name":".bootcde","url":"bootloader.js"}, - {"name":"+boot","url":"bootloader.json"} + {"name":".bootcde","url":"bootloader.js"} ], "sortorder" : -10 }, { "id": "launch", "name": "Default Launcher", + "shortName":"Launcher", "icon": "app.png", "version":"0.01", "description": "This is needed by Bangle.js to display a menu allowing you to choose your own applications. You can replace this with a customised launcher.", "tags": "tool,system,launcher", + "type":"launch", "storage": [ - {"name":"+launch","url":"app.json"}, - {"name":"-launch","url":"app.js"} + {"name":"launch.app.js","url":"app.js"} ], "sortorder" : -10 }, @@ -32,9 +33,8 @@ "tags": "tool,system", "allow_emulator":true, "storage": [ - {"name":"+about","url":"app.json"}, - {"name":"-about","url":"app.js"}, - {"name":"*about","url":"app-icon.js","evaluate":true} + {"name":"about.app.js","url":"app.js"}, + {"name":"about.img","url":"app-icon.js","evaluate":true} ] }, { "id": "welcome", @@ -45,9 +45,8 @@ "tags": "welcome", "allow_emulator":true, "storage": [ - {"name":"+welcome","url":"app.json"}, - {"name":"-welcome","url":"app.js"}, - {"name":"*welcome","url":"app-icon.js","evaluate":true} + {"name":"welcome.app.js","url":"app.js"}, + {"name":"welcome.img","url":"app-icon.js","evaluate":true} ] }, { "id": "gbridge", @@ -57,10 +56,9 @@ "description": "The default notification handler for Gadgetbridge notifications from Android", "tags": "tool,system,android,widget", "storage": [ - {"name":"+gbridge","url":"app.json"}, - {"name":"-gbridge","url":"app.js"}, - {"name":"*gbridge","url":"app-icon.js","evaluate":true}, - {"name":"=gbridge","url":"widget.js"} + {"name":"gbridge.app.js","url":"app.js"}, + {"name":"gbridge.img","url":"app-icon.js","evaluate":true}, + {"name":"gbridge.wid.js","url":"widget.js"} ] }, { "id": "mclock", @@ -72,9 +70,8 @@ "type":"clock", "allow_emulator":true, "storage": [ - {"name":"+mclock","url":"clock-morphing.json"}, - {"name":"-mclock","url":"clock-morphing.js"}, - {"name":"*mclock","url":"clock-morphing-icon.js","evaluate":true} + {"name":"mclock.app.js","url":"clock-morphing.js"}, + {"name":"mclock.img","url":"clock-morphing-icon.js","evaluate":true} ], "sortorder" : -9 }, @@ -85,25 +82,24 @@ "description": "A menu for setting up Bangle.js", "tags": "tool,system", "storage": [ - {"name":"+setting","url":"settings.json"}, - {"name":"-setting","url":"settings.js"}, - {"name":"@setting","url":"settings-default.json","evaluate":true}, - {"name":"*setting","url":"settings-icon.js","evaluate":true} + {"name":"setting.app.js","url":"settings.js"}, + {"name":"setting.json","url":"settings-default.json","evaluate":true}, + {"name":"setting.img","url":"settings-icon.js","evaluate":true} ], "sortorder" : -2 }, { "id": "alarm", "name": "Default Alarm", + "shortName":"Alarms", "icon": "app.png", "version":"0.01", "description": "Set and respond to alarms", "tags": "tool,alarm,widget", "storage": [ - {"name":"+alarm","url":"app.json"}, - {"name":"-alarm","url":"app.js"}, - {"name":"@alarm","content":"[]"}, - {"name":"*alarm","url":"app-icon.js","evaluate":true}, - {"name":"=alarm","url":"widget.js"} + {"name":"alarm.app.js","url":"app.js"}, + {"name":"alarm.json","content":"[]"}, + {"name":"alarm.img","url":"app-icon.js","evaluate":true}, + {"name":"alarm.wid.js","url":"widget.js"} ] }, { "id": "wclock", @@ -115,9 +111,8 @@ "type":"clock", "allow_emulator":true, "storage": [ - {"name":"+wclock","url":"clock-word.json"}, - {"name":"-wclock","url":"clock-word.js"}, - {"name":"*wclock","url":"clock-word-icon.js","evaluate":true} + {"name":"wclock.app.js","url":"clock-word.js"}, + {"name":"wclock.img","url":"clock-word-icon.js","evaluate":true} ] }, { "id": "aclock", @@ -129,9 +124,8 @@ "type":"clock", "allow_emulator":true, "storage": [ - {"name":"+aclock","url":"clock-analog.json"}, - {"name":"-aclock","url":"clock-analog.js"}, - {"name":"*aclock","url":"clock-analog-icon.js","evaluate":true} + {"name":"aclock.app.js","url":"clock-analog.js"}, + {"name":"aclock.img","url":"clock-analog-icon.js","evaluate":true} ] }, { "id": "clck3x2", @@ -142,9 +136,8 @@ "tags": "clock", "allow_emulator":true, "storage": [ - {"name":"+clck3x2","url":"clock3x2.json"}, - {"name":"-clck3x2","url":"clock3x2.js"}, - {"name":"*clck3x2","url":"clock3x2-icon.js","evaluate":true} + {"name":"clck3x2.app.js","url":"clock3x2.js"}, + {"name":"clck3x2.img","url":"clock3x2-icon.js","evaluate":true} ] }, { "id": "trex", @@ -155,9 +148,8 @@ "tags": "game", "allow_emulator":true, "storage": [ - {"name":"+trex","url":"trex.json"}, - {"name":"-trex","url":"trex.js"}, - {"name":"*trex","url":"trex-icon.js","evaluate":true} + {"name":"trex.app.js","url":"trex.js"}, + {"name":"trex.img","url":"trex-icon.js","evaluate":true} ] }, { "id": "astroid", @@ -168,9 +160,8 @@ "tags": "game", "allow_emulator":true, "storage": [ - {"name":"+astroid","url":"asteroids.json"}, - {"name":"-astroid","url":"asteroids.js"}, - {"name":"*astroid","url":"asteroids-icon.js","evaluate":true} + {"name":"astroid.app.js","url":"asteroids.js"}, + {"name":"astroid.img","url":"asteroids-icon.js","evaluate":true} ] }, { "id": "clickms", @@ -180,9 +171,8 @@ "description": "Get several friends to start the game, then compete to see who can press BTN1 the most!", "tags": "game", "storage": [ - {"name":"+clickms","url":"click-master.json"}, - {"name":"-clickms","url":"click-master.js"}, - {"name":"*clickms","url":"click-master-icon.js","evaluate":true} + {"name":"clickms.app.js","url":"click-master.js"}, + {"name":"clickms.img","url":"click-master-icon.js","evaluate":true} ] }, { "id": "horsey", @@ -192,9 +182,8 @@ "description": "Get several friends to start the game, then compete to see who can press BTN1 the most!", "tags": "game", "storage": [ - {"name":"+horsey","url":"horse-race.json"}, - {"name":"-horsey","url":"horse-race.js"}, - {"name":"*horsey","url":"horse-race-icon.js","evaluate":true} + {"name":"horsey.app.js","url":"horse-race.js"}, + {"name":"horsey.img","url":"horse-race-icon.js","evaluate":true} ] }, { "id": "compass", @@ -204,9 +193,8 @@ "description": "Simple compass that points North", "tags": "tool,outdoors", "storage": [ - {"name":"+compass","url":"compass.json"}, - {"name":"-compass","url":"compass.js"}, - {"name":"*compass","url":"compass-icon.js","evaluate":true} + {"name":"compass.app.js","url":"compass.js"}, + {"name":"compass.img","url":"compass-icon.js","evaluate":true} ] }, { "id": "gpstime", @@ -216,9 +204,8 @@ "description": "Update the Bangle.js's clock based on the time from the GPS receiver", "tags": "tool,gps", "storage": [ - {"name":"+gpstime","url":"gpstime.json"}, - {"name":"-gpstime","url":"gpstime.js"}, - {"name":"*gpstime","url":"gpstime-icon.js","evaluate":true} + {"name":"gpstime.app.js","url":"gpstime.js"}, + {"name":"gpstime.img","url":"gpstime-icon.js","evaluate":true} ] }, { "id": "openloc", @@ -228,8 +215,7 @@ "description": "Convert your current GPS location to a series of characters", "tags": "tool,outdoors,gps", "storage": [ - {"name":"+openloc","url":"openlocation.json"}, - {"name":"-openloc","url":"openlocation.js","evaluate":true} + {"name":"openloc.app.js","url":"openlocation.js","evaluate":true} ] }, { "id": "speedo", @@ -239,9 +225,8 @@ "description": "Show the current speed according to the GPS", "tags": "tool,outdoors,gps", "storage": [ - {"name":"+speedo","url":"speedo.json"}, - {"name":"-speedo","url":"speedo.js"}, - {"name":"*speedo","url":"speedo-icon.js","evaluate":true} + {"name":"speedo.app.js","url":"speedo.js"}, + {"name":"speedo.img","url":"speedo-icon.js","evaluate":true} ] }, { "id": "gpsrec", @@ -252,11 +237,10 @@ "description": "Application that allows you to record a GPS track. Can run in background", "tags": "tool,outdoors,gps,widget", "storage": [ - {"name":"+gpsrec","url":"app.json"}, - {"name":"-gpsrec","url":"app.js"}, - {"name":"@gpsrec","url":"app-settings.json","evaluate":true}, - {"name":"*gpsrec","url":"app-icon.js","evaluate":true}, - {"name":"=gpsrec","url":"widget.js"} + {"name":"gpsrec.app.js","url":"app.js"}, + {"name":"gpsrec.json","url":"app-settings.json","evaluate":true}, + {"name":"gpsrec.img","url":"app-icon.js","evaluate":true}, + {"name":"gpsrec.wid.js","url":"widget.js"} ] }, { "id": "slevel", @@ -266,9 +250,8 @@ "description": "Show the current angle of the watch, so you can use it to make sure something is absolutely flat", "tags": "tool", "storage": [ - {"name":"+slevel","url":"spiritlevel.json"}, - {"name":"-slevel","url":"spiritlevel.js"}, - {"name":"*slevel","url":"spiritlevel-icon.js","evaluate":true} + {"name":"slevel.app.js","url":"spiritlevel.js"}, + {"name":"slevel.img","url":"spiritlevel-icon.js","evaluate":true} ] }, { "id": "files", @@ -278,33 +261,30 @@ "description": "Show currently installed apps, free space, and allow their deletion from the watch", "tags": "tool,system", "storage": [ - {"name":"+files","url":"files.json"}, - {"name":"-files","url":"files.js"}, - {"name":"*files","url":"files-icon.js","evaluate":true} + {"name":"files.app.js","url":"files.js"}, + {"name":"files.img","url":"files-icon.js","evaluate":true} ] }, - { "id": "sbat", + { "id": "widbat", "name": "Battery Level Widget", - "icon": "widget-battery.png", + "icon": "widget.png", "version":"0.02", "description": "Show the current battery level and charging status in the top right of the clock", "tags": "widget,battery", "type":"widget", "storage": [ - {"name":"+sbat","url":"widget-battery.json"}, - {"name":"=sbat","url":"widget-battery.js"} + {"name":"widbat.wid.js","url":"widget.js"} ] }, - { "id": "sbt", + { "id": "widbt", "name": "Bluetooth Widget", - "icon": "widget-bluetooth.png", + "icon": "widget.png", "version":"0.01", "description": "Show the current Bluetooth connection status in the top right of the clock", "tags": "widget,bluetooth", "type":"widget", "storage": [ - {"name":"+sbt","url":"widget-bluetooth.json"}, - {"name":"=sbt","url":"widget-bluetooth.js"} + {"name":"widbt.wid.js","url":"widget.js"} ] }, { "id": "hrm", @@ -314,20 +294,18 @@ "description": "Measure your current heart rate", "tags": "health", "storage": [ - {"name":"+hrm","url":"heartrate.json"}, - {"name":"-hrm","url":"heartrate.js"}, - {"name":"*hrm","url":"heartrate-icon.js","evaluate":true} + {"name":"hrm.app.js","url":"heartrate.js"}, + {"name":"hrm.img","url":"heartrate-icon.js","evaluate":true} ] }, - { "id": "whrm", + { "id": "widhrm", "name": "Simple Heart Rate widget", "icon": "widget.png", "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", "storage": [ - {"name":"+whrm","url":"widget.json"}, - {"name":"=whrm","url":"widget.js"} + {"name":"widhrm.wid.js","url":"widget.js"} ] }, { "id": "stetho", @@ -337,9 +315,8 @@ "description": "Hear your heart rate", "tags": "health", "storage": [ - {"name":"+stetho","url":"stetho.json"}, - {"name":"-stetho","url":"stetho.js"}, - {"name":"*stetho","url":"stetho-icon.js","evaluate":true} + {"name":"stetho.app.js","url":"stetho.js"}, + {"name":"stetho.img","url":"stetho-icon.js","evaluate":true} ] }, { "id": "swatch", @@ -350,9 +327,8 @@ "tags": "health", "allow_emulator":true, "storage": [ - {"name":"+swatch","url":"stopwatch.json"}, - {"name":"-swatch","url":"stopwatch.js"}, - {"name":"*swatch","url":"stopwatch-icon.js","evaluate":true} + {"name":"swatch.app.js","url":"stopwatch.js"}, + {"name":"swatch.img","url":"stopwatch-icon.js","evaluate":true} ] }, { "id": "hidmsic", @@ -362,9 +338,8 @@ "description": "Enable HID in settings, pair with your phone, then use this app to control music from your watch!", "tags": "bluetooth", "storage": [ - {"name":"+hidmsic","url":"hid-music.json"}, - {"name":"-hidmsic","url":"hid-music.js"}, - {"name":"*hidmsic","url":"hid-music-icon.js","evaluate":true} + {"name":"hidmsic.app.js","url":"hid-music.js"}, + {"name":"hidmsic.img","url":"hid-music-icon.js","evaluate":true} ] }, { "id": "hidkbd", @@ -374,9 +349,8 @@ "description": "Enable HID in settings, pair with your phone/PC, then use this app to control other apps", "tags": "bluetooth", "storage": [ - {"name":"+hidkbd","url":"hid-keyboard.json"}, - {"name":"-hidkbd","url":"hid-keyboard.js"}, - {"name":"*hidkbd","url":"hid-keyboard-icon.js","evaluate":true} + {"name":"hidkbd.app.js","url":"hid-keyboard.js"}, + {"name":"hidkbd.img","url":"hid-keyboard-icon.js","evaluate":true} ] }, { "id": "hidbkbd", @@ -386,9 +360,8 @@ "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", "tags": "bluetooth", "storage": [ - {"name":"+hidbkbd","url":"hid-binary-keyboard.json"}, - {"name":"-hidbkbd","url":"hid-binary-keyboard.js"}, - {"name":"*hidbkbd","url":"hid-binary-keyboard-icon.js","evaluate":true} + {"name":"hidbkbd.app.js","url":"hid-binary-keyboard.js"}, + {"name":"hidbkbd.img","url":"hid-binary-keyboard-icon.js","evaluate":true} ] }, { "id": "animals", @@ -398,17 +371,16 @@ "description": "Simple toddler's game - displays a different number of animals each time the screen is pressed", "tags": "game", "storage": [ - {"name":"+animals","url":"animals.json"}, - {"name":"-animals","url":"animals.js"}, - {"name":"*animals","url":"animals-icon.js","evaluate":true}, - {"name":"*snake","url":"animals-snake.js","evaluate":true}, - {"name":"*duck","url":"animals-duck.js","evaluate":true}, - {"name":"*swan","url":"animals-swan.js","evaluate":true}, - {"name":"*fox","url":"animals-fox.js","evaluate":true}, - {"name":"*camel","url":"animals-camel.js","evaluate":true}, - {"name":"*pig","url":"animals-pig.js","evaluate":true}, - {"name":"*sheep","url":"animals-sheep.js","evaluate":true}, - {"name":"*mouse","url":"animals-mouse.js","evaluate":true} + {"name":"animals.app.js","url":"animals.js"}, + {"name":"animals.img","url":"animals-icon.js","evaluate":true}, + {"name":"animals-snake.img","url":"animals-snake.js","evaluate":true}, + {"name":"animals-duck.img","url":"animals-duck.js","evaluate":true}, + {"name":"animals-swan.img","url":"animals-swan.js","evaluate":true}, + {"name":"animals-fox.img","url":"animals-fox.js","evaluate":true}, + {"name":"animals-camel.img","url":"animals-camel.js","evaluate":true}, + {"name":"animals-pig.img","url":"animals-pig.js","evaluate":true}, + {"name":"animals-sheep.img","url":"animals-sheep.js","evaluate":true}, + {"name":"animals-mouse.img","url":"animals-mouse.js","evaluate":true} ] }, { "id": "qrcode", @@ -419,9 +391,8 @@ "tags": "", "custom": "qrcode.html", "storage": [ - {"name":"-qrcode"}, - {"name":"+qrcode"}, - {"name":"=qrcode"} + {"name":"qrcode.app.js"}, + {"name":"qrcode.wid.js"} ] }, { "id": "beer", @@ -432,9 +403,8 @@ "tags": "", "custom": "beercompass.html", "storage": [ - {"name":"-beer"}, - {"name":"+beer"}, - {"name":"=beer"} + {"name":"beer.app.js"}, + {"name":"beer.wid.js"} ] }, { "id": "route", @@ -445,9 +415,8 @@ "tags": "", "custom": "route.html", "storage": [ - {"name":"-route"}, - {"name":"+route"}, - {"name":"=route"} + {"name":"route.app.js"}, + {"name":"route.wid.js"} ] }, @@ -461,14 +430,13 @@ "description": "NodeConfEU 2019 'First Start' Sequence", "tags": "start", "storage": [ - {"name":"+ncstart","url":"start.json"}, {"name":".boot3","url":"start.js"}, - {"name":"*ncstart","url":"start-icon.js","evaluate":true}, - {"name":"*bangle","url":"start-bangle.js","evaluate":true}, - {"name":"*nceu","url":"start-nceu.js","evaluate":true}, - {"name":"*nfr","url":"start-nfr.js","evaluate":true}, - {"name":"*nodew","url":"start-nodew.js","evaluate":true}, - {"name":"*tf","url":"start-tf.js","evaluate":true} + {"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} ] }, { "id": "ncfrun", @@ -478,21 +446,19 @@ "description": "Display a map of the NodeConf EU 2019 5K Fun Run route and your location on it", "tags": "health", "storage": [ - {"name":"+ncfrun","url":"nceu-funrun.json"}, - {"name":"-ncfrun","url":"nceu-funrun.js"}, - {"name":"*ncfrun","url":"nceu-funrun-icon.js","evaluate":true} + {"name":"ncfrun.app.js","url":"nceu-funrun.js"}, + {"name":"ncfrun.img","url":"nceu-funrun-icon.js","evaluate":true} ] }, - { "id": "nceuwid", + { "id": "widnceu", "name": "NCEU Logo Widget", - "icon": "nceu-widget.png", + "icon": "widget.png", "version":"0.01", "description": "Show the NodeConf EU logo in the top left", "tags": "widget", "type":"widget", "storage": [ - {"name":"+nceuwid","url":"nceu-widget.json"}, - {"name":"=nceuwid","url":"nceu-widget.js"} + {"name":"widnceu.wid.js","url":"widget.js"} ] }, @@ -507,9 +473,8 @@ "type":"clock", "allow_emulator":true, "storage": [ - {"name":"+sclock","url":"clock-simple.json"}, - {"name":"-sclock","url":"clock-simple.js"}, - {"name":"*sclock","url":"clock-simple-icon.js","evaluate":true} + {"name":"sclock.app.js","url":"clock-simple.js"}, + {"name":"sclock.img","url":"clock-simple-icon.js","evaluate":true} ] }, { "id": "gesture", @@ -520,11 +485,10 @@ "tags": "gesture,ai", "type":"app", "storage": [ - {"name":"+gesture","url":"gesture.json"}, - {"name":"-gesture","url":"gesture.js"}, + {"name":"gesture.app.js","url":"gesture.js"}, {"name":".tfnames","url":"gesture-tfnames.js","evaluate":true}, {"name":".tfmodel","url":"gesture-tfmodel.js","evaluate":true}, - {"name":"*gesture","url":"gesture-icon.js","evaluate":true} + {"name":"gesture.img","url":"gesture-icon.js","evaluate":true} ] }, { "id": "pparrot", @@ -536,9 +500,8 @@ "type":"app", "allow_emulator":true, "storage": [ - {"name":"+pparrot","url":"party-parrot.json"}, - {"name":"-pparrot","url":"party-parrot.js"}, - {"name":"*pparrot","url":"party-parrot-icon.js","evaluate":true} + {"name":"pparrot.app.js","url":"party-parrot.js"}, + {"name":"pparrot.img","url":"party-parrot-icon.js","evaluate":true} ] }, { "id": "hrings", @@ -550,9 +513,8 @@ "type":"app", "allow_emulator":true, "storage": [ - {"name":"+hrings","url":"hypno-rings.json"}, - {"name":"-hrings","url":"hypno-rings.js"}, - {"name":"*hrings","url":"hypno-rings-icon.js","evaluate":true} + {"name":"hrings.app.js","url":"hypno-rings.js"}, + {"name":"hrings.img","url":"hypno-rings-icon.js","evaluate":true} ] }, { "id": "morse", @@ -563,9 +525,8 @@ "tags": "morse,sound,visual,input", "type":"app", "storage": [ - {"name":"+morse","url":"morse-code.json"}, - {"name":"-morse","url":"morse-code.js"}, - {"name":"*morse","url":"morse-code-icon.js","evaluate":true} + {"name":"morse.app.js","url":"morse-code.js"}, + {"name":"morse.img","url":"morse-code-icon.js","evaluate":true} ] }, { @@ -576,9 +537,8 @@ "description": "Scan for advertising BLE devices", "tags" : "bluetooth", "storage" : [ - {"name":"+blescan","url":"blescan.json"}, - {"name":"-blescan","url":"blescan.js"}, - {"name":"*blescan","url":"blescan-icon.js", "evaluate":true} + {"name":"blescan.app.js","url":"blescan.js"}, + {"name":"blescan.img","url":"blescan-icon.js", "evaluate":true} ] }, { "id": "mmonday", @@ -588,9 +548,8 @@ "description": "The Bangles make a comeback", "tags": "sound", "storage": [ - {"name":"+mmonday","url":"manic-monday.json"}, - {"name":"-mmonday","url":"manic-monday.js"}, - {"name":"*mmonday","url":"manic-monday-icon.js","evaluate":true} + {"name":"mmonday.app.js","url":"manic-monday.js"}, + {"name":"mmonday.img","url":"manic-monday-icon.js","evaluate":true} ] }, { "id": "jbells", @@ -601,9 +560,8 @@ "tags": "sound", "type":"app", "storage": [ - {"name":"+jbells","url":"jbells.json"}, - {"name":"-jbells","url":"jbells.js"}, - {"name":"*jbells","url":"jbells-icon.js","evaluate":true} + {"name":"jbells.app.js","url":"jbells.js"}, + {"name":"jbells.img","url":"jbells-icon.js","evaluate":true} ] }, { "id": "scolor", @@ -615,9 +573,8 @@ "type":"app", "allow_emulator":true, "storage": [ - {"name":"+scolor","url":"show-color.json"}, - {"name":"-scolor","url":"show-color.js"}, - {"name":"*scolor","url":"show-color-icon.js","evaluate":true} + {"name":"scolor.app.js","url":"show-color.js"}, + {"name":"scolor.img","url":"show-color-icon.js","evaluate":true} ] }, { "id": "miclock", @@ -629,9 +586,8 @@ "type":"clock", "allow_emulator":true, "storage": [ - {"name":"+miclock","url":"clock-mixed.json"}, - {"name":"-miclock","url":"clock-mixed.js"}, - {"name":"*miclock","url":"clock-mixed-icon.js","evaluate":true} + {"name":"miclock.app.js","url":"clock-mixed.js"}, + {"name":"miclock.img","url":"clock-mixed-icon.js","evaluate":true} ] }, { "id": "bclock", @@ -643,9 +599,8 @@ "type":"clock", "allow_emulator":true, "storage": [ - {"name":"+bclock","url":"clock-binary.json"}, - {"name":"-bclock","url":"clock-binary.js"}, - {"name":"*bclock","url":"clock-binary-icon.js","evaluate":true} + {"name":"bclock.app.js","url":"clock-binary.js"}, + {"name":"bclock.img","url":"clock-binary-icon.js","evaluate":true} ] }, { "id": "clotris", @@ -656,9 +611,8 @@ "tags": "game", "allow_emulator":true, "storage": [ - {"name":"+clotris","url":"clock-tris.json"}, - {"name":"-clotris","url":"clock-tris.js"}, - {"name":"*clotris","url":"clock-tris-icon.js","evaluate":true}, + {"name":"clotris.app.js","url":"clock-tris.js"}, + {"name":"clotris.img","url":"clock-tris-icon.js","evaluate":true}, {"name":".trishig","url":"clock-tris-high"} ] }, @@ -670,9 +624,8 @@ "tags": "game", "allow_emulator":true, "storage": [ - {"name":"+flappy","url":"app.json"}, - {"name":"-flappy","url":"app.js"}, - {"name":"*flappy","url":"app-icon.js","evaluate":true} + {"name":"flappy.app.js","url":"app.js"}, + {"name":"flappy.img","url":"app-icon.js","evaluate":true} ] }, { @@ -713,9 +666,8 @@ "type":"clock", "allow_emulator":true, "storage": [ - {"name":"+blobclk","url":"clock-blob.json"}, - {"name":"-blobclk","url":"clock-blob.js"}, - {"name":"*blobclk","url":"clock-blob-icon.js","evaluate":true} + {"name":"blobclk.app.js","url":"clock-blob.js"}, + {"name":"blobclk.img","url":"clock-blob-icon.js","evaluate":true} ] }, { "id": "boldclk", @@ -727,33 +679,30 @@ "type":"clock", "allow_emulator":true, "storage": [ - {"name":"+boldclk","url":"bold_clock.json"}, - {"name":"-boldclk","url":"bold_clock.js"}, - {"name":"*boldclk","url":"bold_clock-icon.js","evaluate":true} + {"name":"boldclk.app.js","url":"bold_clock.js"}, + {"name":"boldclk.img","url":"bold_clock-icon.js","evaluate":true} ] }, - { "id": "wdclk", + { "id": "widclk", "name": "Digital clock widget", - "icon": "digital_clock_widget.png", + "icon": "widget.png", "version":"0.01", "description": "A simple digital clock widget", "tags": "widget,clock", "type":"widget", "storage": [ - {"name":"+wdclk","url":"digital_clock_widget.json"}, - {"name":"=wdclk","url":"digital_clock_widget.js"} + {"name":"widclk.wid.js","url":"widget.js"} ] }, { "id": "wpedom", "name": "Pedometer widget", - "icon": "pedometer_widget.png", + "icon": "widget.png", "version":"0.06", "description": "Daily pedometer widget", "tags": "widget", "type":"widget", "storage": [ - {"name":"+wpedom","url":"pedometer_widget.json"}, - {"name":"=wpedom","url":"pedometer_widget.js"} + {"name":"wpedom.wid.js","url":"widget.js"} ] }, { "id": "berlinc", @@ -765,9 +714,8 @@ "type":"clock", "allow_emulator":true, "storage": [ - {"name":"+berlinc","url":"berlin-clock.json"}, - {"name":"-berlinc","url":"berlin-clock.js"}, - {"name":"*berlinc","url":"berlin-clock-icon.js","evaluate":true} + {"name":"berlinc.app.js","url":"berlin-clock.js"}, + {"name":"berlinc.img","url":"berlin-clock-icon.js","evaluate":true} ] }, { "id": "ctrclk", @@ -779,9 +727,8 @@ "type":"clock", "allow_emulator":true, "storage": [ - {"name":"+ctrclk","url":"app.json"}, - {"name":"-ctrclk","url":"app.js"}, - {"name":"*ctrclk","url":"app-icon.js","evaluate":true} + {"name":"ctrclk.app.js","url":"app.js"}, + {"name":"ctrclk.img","url":"app-icon.js","evaluate":true} ] }, { "id": "demoapp", @@ -793,9 +740,8 @@ "type":"app", "allow_emulator":true, "storage": [ - {"name":"+demoapp","url":"app.json"}, - {"name":"-demoapp","url":"app.js"}, - {"name":"*demoapp","url":"app-icon.js","evaluate":true} + {"name":"demoapp.app.js","url":"app.js"}, + {"name":"demoapp.img","url":"app-icon.js","evaluate":true} ], "sortorder" : -9 }, @@ -805,9 +751,8 @@ "description": "App to send a command to another Espruino to cause it to raise a flag", "tags": "", "storage": [ - {"name":"+flagrse","url":"app.json"}, - {"name":"-flagrse","url":"app.js"}, - {"name":"*flagrse","url":"app-icon.js","evaluate":true} + {"name":"flagrse.app.js","url":"app.js"}, + {"name":"flagrse.img","url":"app-icon.js","evaluate":true} ] }, { @@ -820,9 +765,8 @@ "type":"clock", "allow_emulator":true, "storage": [ - {"name":"+pipboy","url":"app.json"}, - {"name":"-pipboy","url":"app.js"}, - {"name":"*pipboy","url":"app-icon.js","evaluate":true} + {"name":"pipboy.app.js","url":"app.js"}, + {"name":"pipboy.img","url":"app-icon.js","evaluate":true} ] } ] diff --git a/apps/_example_app/add_to_apps.json b/apps/_example_app/add_to_apps.json index 9043b0058c..c75f9ed7de 100644 --- a/apps/_example_app/add_to_apps.json +++ b/apps/_example_app/add_to_apps.json @@ -1,6 +1,7 @@ // Create an entry in apps.json as follows: { "id": "7chname", "name": "My app's human readable name", + "shortName":"Short Name", "icon": "app.png", "version":"0.01", "description": "A detailed description of my great app", diff --git a/apps/_example_app/app.json b/apps/_example_app/app.json deleted file mode 100644 index 65168c5a15..0000000000 --- a/apps/_example_app/app.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Short Name", - "icon":"*7chname", - "src":"-7chname" -} diff --git a/apps/_example_widget/add_to_apps.json b/apps/_example_widget/add_to_apps.json index 149c6a3ddd..3011fe7446 100644 --- a/apps/_example_widget/add_to_apps.json +++ b/apps/_example_widget/add_to_apps.json @@ -1,10 +1,12 @@ // Create an entry in apps.json as follows: { "id": "7chname", "name": "My widget's human readable name", + "shortName":"Short Name", "icon": "widget.png", "version":"0.01", "description": "A detailed description of my great widget", "tags": "widget", + "type": "widget", "storage": [ {"name":"+7chname","url":"widget.json"}, {"name":"=7chname","url":"widget.js"} diff --git a/apps/_example_widget/widget.json b/apps/_example_widget/widget.json deleted file mode 100644 index efc522dee1..0000000000 --- a/apps/_example_widget/widget.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name":"widgetname", "type":"widget", - "src":"=7chname" -} diff --git a/apps/about/app.json b/apps/about/app.json deleted file mode 100644 index dd1b7c06ff..0000000000 --- a/apps/about/app.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"About", - "icon":"*about", - "src":"-about" -} diff --git a/apps/aclock/clock-analog.json b/apps/aclock/clock-analog.json deleted file mode 100644 index 049d474063..0000000000 --- a/apps/aclock/clock-analog.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name":"Analog Clock","type":"clock", - "icon":"*aclock", - "src":"-aclock", - "sortorder":-10 -} diff --git a/apps/alarm/app.js b/apps/alarm/app.js index 153a6ef3b9..c2075607d0 100644 --- a/apps/alarm/app.js +++ b/apps/alarm/app.js @@ -1,7 +1,7 @@ Bangle.loadWidgets(); Bangle.drawWidgets(); -var alarms = require("Storage").readJSON("@alarm")||[]; +var alarms = require("Storage").readJSON("alarm.json")||[]; /*alarms = [ { on : true, hr : 6.5, // hours + minutes/60 @@ -57,13 +57,11 @@ function editAlarm(alarmIndex) { value: hrs, min: 0, max: 23, - onchange: v=>hrs=v + onchange: v=>{if (v<0)v=23;if (v>23)v=0;hrs=v;this.value=v;} }, 'Minutes': { value: mins, - min: 0, - max: 60, - onchange: v=>mins=v + onchange: v=>{if (v<0)v=59;if (v>59)v=0;mins=v;this.value=v;} }, 'Enabled': { value: en, @@ -91,13 +89,13 @@ function editAlarm(alarmIndex) { if (newAlarm) { menu["> New Alarm"] = function() { alarms.push(getAlarm()); - require("Storage").write("@alarm",JSON.stringify(alarms)); + require("Storage").write("alarm.json",JSON.stringify(alarms)); showMainMenu(); }; } else { menu["> Save"] = function() { alarms[alarmIndex] = getAlarm(); - require("Storage").write("@alarm",JSON.stringify(alarms)); + require("Storage").write("alarm.json",JSON.stringify(alarms)); showMainMenu(); }; } @@ -121,7 +119,7 @@ function showAlarm(alarm) { alarm.last = (new Date()).getDate(); if (!alarm.rp) alarm.on = false; } - require("Storage").write("@alarm",JSON.stringify(alarms)); + require("Storage").write("alarm.json",JSON.stringify(alarms)); load(); }); function buzz() { diff --git a/apps/alarm/app.json b/apps/alarm/app.json deleted file mode 100644 index 25b8c6a009..0000000000 --- a/apps/alarm/app.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Alarms", - "icon":"*alarm", - "src":"-alarm" -} diff --git a/apps/alarm/widget.js b/apps/alarm/widget.js index 9a8bb01e73..385dd8f2b9 100644 --- a/apps/alarm/widget.js +++ b/apps/alarm/widget.js @@ -1,5 +1,5 @@ (() => { - var alarms = require('Storage').readJSON('@alarm')||[]; + var alarms = require('Storage').readJSON('alarm.json')||[]; alarms = alarms.filter(alarm=>alarm.on); if (!alarms.length) return; delete alarms; diff --git a/apps/animals/animals.js b/apps/animals/animals.js index 38e1a48120..f92882e080 100644 --- a/apps/animals/animals.js +++ b/apps/animals/animals.js @@ -13,7 +13,7 @@ function next(e) { } while (current && current==last); g.clear(); var n = 1 + (0|(Math.random()*3.9)); - var img = require("Storage").read("*"+current); + var img = require("Storage").read("animals-"+current+".img"); if (n==1) g.drawImage(img,120,120,{scale:4,rotate:Math.random()-0.5}); else diff --git a/apps/animals/animals.json b/apps/animals/animals.json deleted file mode 100644 index a2d24941f4..0000000000 --- a/apps/animals/animals.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Animals Game", "type":"app", - "icon":"*animals", - "src":"-animals" -} diff --git a/apps/astroid/asteroids.json b/apps/astroid/asteroids.json deleted file mode 100644 index 7215be590c..0000000000 --- a/apps/astroid/asteroids.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Asteroids!","type":"app", - "icon":"*astroid", - "src":"-astroid" -} diff --git a/apps/bclock/clock-binary.json b/apps/bclock/clock-binary.json deleted file mode 100644 index c00dd9d763..0000000000 --- a/apps/bclock/clock-binary.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name":"Binary Clock", - "type":"clock", - "icon":"*bclock", - "src":"-bclock" - } - \ No newline at end of file diff --git a/apps/beer/beercompass.html b/apps/beer/beercompass.html index cb5590fa77..434f0f6a93 100644 --- a/apps/beer/beercompass.html +++ b/apps/beer/beercompass.html @@ -196,20 +196,12 @@ Bangle.setCompassPower(1); Bangle.setGPSPower(1); g.clear();`; - var json = JSON.stringify({ - name:"Beer Compass", - icon:"*beer", - src:"-beer" -}); var icon = `require("heatshrink").decompress(atob("mEwghC/AB0O/4AG8AXNgYXHmAXl94XH+AXNn4XH/wXW+YX/C6oWHAAIXN7sz9vdAAoXN9sznvuAAXf/vuC53jC4Xd7wXQ93jn3u9vv9vt7wXT/4tBAgIXQ7wvCC4PgC5sO6czIQJfBC6PumaPDC6wwCC50NYAJcBVgIDBCxrAFbgYXP7yoDF6TADL4YXPVAIXCRyAXC7wXW9zwBC6cNC9zABC4gWQC653CR4fQC6x3TF6gXXI4M9d6wAEC9EN73dAAZfQgczAAkwC/4XXAH4"))`; sendCustomizedApp({ - id : "beer", - storage:[ - {name:"-beer", content:app}, - {name:"+beer", content:json}, - {name:"*beer", content:icon, evaluate:true}, + {name:"beer.app.js", content:app}, + {name:"beer.img", content:icon, evaluate:true}, ] }); }); diff --git a/apps/berlinc/berlin-clock.json b/apps/berlinc/berlin-clock.json deleted file mode 100644 index 7c0d6e4113..0000000000 --- a/apps/berlinc/berlin-clock.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name":"Berlin Clock", - "type":"clock", - "icon":"*berlinc", - "src":"-berlinc" -} diff --git a/apps/blescan/blescan.json b/apps/blescan/blescan.json deleted file mode 100644 index d9e7f28f14..0000000000 --- a/apps/blescan/blescan.json +++ /dev/null @@ -1,7 +0,0 @@ - -{ - "name": "BLE Scanner", - "type":"app", - "icon": "*blescan", - "src": "-blescan" -} diff --git a/apps/blobclk/clock-blob.json b/apps/blobclk/clock-blob.json deleted file mode 100644 index b548acd80c..0000000000 --- a/apps/blobclk/clock-blob.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name":"Large Clock", - "type":"clock", - "icon":"*blobclk", - "src":"-blobclk", - "sortorder":-10 -} diff --git a/apps/boldclk/bold_clock.json b/apps/boldclk/bold_clock.json deleted file mode 100644 index 45ceede6b6..0000000000 --- a/apps/boldclk/bold_clock.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name":"Bold Clock", - "type":"clock", - "icon":"*boldclk", - "src":"-boldclk", - "sortorder":-10 -} \ No newline at end of file diff --git a/apps/boot/boot0.js b/apps/boot/boot0.js index 8b34c683a9..f0ad79a5fe 100644 --- a/apps/boot/boot0.js +++ b/apps/boot/boot0.js @@ -1,7 +1,7 @@ // This ALWAYS runs at boot E.setFlags({pretokenise:1}); // Load settings... -var s = require('Storage').readJSON('@setting')||{}; +var s = require('Storage').readJSON('setting.json')||{}; if (s.ble!==false) { if (s.HID) { // Humen interface device Bangle.HID = E.toUint8Array(atob("BQEJBqEBhQIFBxngKecVACUBdQGVCIEClQF1CIEBlQV1AQUIGQEpBZEClQF1A5EBlQZ1CBUAJXMFBxkAKXOBAAkFFQAm/wB1CJUCsQLABQwJAaEBhQEVACUBdQGVAQm1gQIJtoECCbeBAgm4gQIJzYECCeKBAgnpgQIJ6oECwA==")); @@ -10,8 +10,7 @@ if (s.ble!==false) { } if (s.blerepl===false) { // If not programmable, force terminal off Bluetooth if (s.log) Terminal.setConsole(true); // if showing debug, force REPL onto terminal - else if (E.setConsole) E.setConsole(null,{force:true}); // on new (2v05+) firmware we have E.setConsole which allows a 'null' console - else LoopbackA.setConsole(true); // for old builds, doing this will use some data as LoopbackB stores some of the chars + else E.setConsole(null,{force:true}); // on new (2v05+) firmware we have E.setConsole which allows a 'null' console } else { if (s.log) Terminal.setConsole(); // if showing debug, put REPL on terminal (until connection) else Bluetooth.setConsole(true); // else if no debug, force REPL to Bluetooth @@ -27,23 +26,23 @@ E.setTimeZone(s.timezone); delete s; // check for alarms function checkAlarm() { - var alarms = require('Storage').readJSON('@alarm')||[]; + var alarms = require('Storage').readJSON('alarm.json')||[]; var time = new Date(); var active = alarms.filter(a=>a.on&&(a.last!=time.getDate())); if (active.length) { active = active.sort((a,b)=>a.hr-b.hr); var hr = time.getHours()+(time.getMinutes()/60); - if (!require('Storage').read("-alarm")) { + if (!require('Storage').read("alarm.app.js")) { console.log("No alarm app!"); - require('Storage').write('@alarm',"[]") + require('Storage').write('alarm.json',"[]") } else { if (active[0].hr < hr) { // fire alarm now - load("-alarm"); + load("alarm.app.js"); } else { // execute alarm at the correct time setTimeout(function() { - load("-alarm"); + load("alarm.app.js"); },3600000*(active[0].hr-hr)); } } @@ -67,42 +66,3 @@ if ((new Date()).getFullYear()==1970) { Bangle.setGPSPower(1); } else checkAlarm(); delete checkAlarm; -// Check for -// All of this is just shim for older Bangles -if (!Bangle.loadWidgets) { - Bangle.loadWidgets = function(){ - global.WIDGETPOS={tl:32,tr:g.getWidth()-32,bl:32,br:g.getWidth()-32}; - global.WIDGETS={}; - require("Storage").list().filter(a=>a[0]=='=').forEach(widget=>eval(require("Storage").read(widget))); - }; - Bangle.drawWidgets = function(){ - for(var w of WIDGETS)w.draw() - }; - Bangle.showLauncher = function(){ - var l = require("Storage").list().filter(a=>a[0]=='+').map(app=>{ - try { return require("Storage").readJSON(app); } catch (e) {} - }).find(app=>app.type=="launch"); - if (l) load(l.src); - else E.showMessage("Launcher\nnot found"); - }; - var _load = load; - global.load = function(x) { - if (!x) _load(x); - else setTimeout(function(){ - // attempt to remove any currently-running code - delete Bangle.buzz; - delete Bangle.beep; - Bangle.setLCDOffset&&Bangle.setLCDOffset(0); - Bangle.setLCDMode("direct"); - g.clear(); - clearInterval(); - clearWatch(); - Bangle.removeAllListeners(); - NRF.removeAllListeners(); - Bluetooth.removeAllListeners(); - E.removeAllListeners(); - for (var i in global) if (i!="g") delete global[i]; - setTimeout('eval(require("Storage").read("'+x+'"));',20); - },20); - } -} diff --git a/apps/boot/bootloader.js b/apps/boot/bootloader.js index fc21ee60cb..12559abb16 100644 --- a/apps/boot/bootloader.js +++ b/apps/boot/bootloader.js @@ -1,6 +1,6 @@ // This runs after a 'fresh' boot var settings={}; -try { settings = require("Storage").readJSON('@setting'); } catch (e) {} +try { settings = require("Storage").readJSON('setting.json'); } catch (e) {} if (!settings.welcomed && require("Storage").read("-welcome")!==undefined) { setTimeout(()=>load("-welcome")); } else { @@ -8,7 +8,7 @@ if (!settings.welcomed && require("Storage").read("-welcome")!==undefined) { var clockApp = settings.clock; if (clockApp) clockApp = require("Storage").read(clockApp) if (!clockApp) { - var clockApps = require("Storage").list().filter(a=>a[0]=='+').map(app=>{ + var clockApps = require("Storage").list(/\.info$/).map(app=>{ try { return require("Storage").readJSON(app); } catch (e) {} }).filter(app=>app.type=="clock").sort((a, b) => a.sortorder - b.sortorder); diff --git a/apps/boot/bootloader.json b/apps/boot/bootloader.json deleted file mode 100644 index dc568a3194..0000000000 --- a/apps/boot/bootloader.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name":"Bootloader","type":"boot" -} diff --git a/apps/clck3x2/clock3x2.json b/apps/clck3x2/clock3x2.json deleted file mode 100644 index 2d445787e4..0000000000 --- a/apps/clck3x2/clock3x2.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name":"Clock 3x2 Pix", - "type":"clock", - "icon":"*clck3x2", - "src":"-clck3x2" -} diff --git a/apps/clickms/click-master.json b/apps/clickms/click-master.json deleted file mode 100644 index 6a2874259a..0000000000 --- a/apps/clickms/click-master.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Click Master", - "icon": "*clickms", - "src":"-clickms" -} diff --git a/apps/clotris/clock-tris.json b/apps/clotris/clock-tris.json deleted file mode 100644 index ddbb7d10cf..0000000000 --- a/apps/clotris/clock-tris.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Clock-Tris", - "icon":"*clotris", - "src":"-clotris" -} \ No newline at end of file diff --git a/apps/compass/compass.json b/apps/compass/compass.json deleted file mode 100644 index 7abc9a7333..0000000000 --- a/apps/compass/compass.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Compass","type":"app", - "icon":"*compass", - "src":"-compass" -} diff --git a/apps/ctrclk/app.json b/apps/ctrclk/app.json deleted file mode 100644 index 68fbfdb704..0000000000 --- a/apps/ctrclk/app.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "Centerclock", - "type": "clock", - "icon": "*ctrclk", - "src": "-ctrclk" -} diff --git a/apps/cube/cube.json b/apps/cube/cube.json deleted file mode 100644 index 440a78c724..0000000000 --- a/apps/cube/cube.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name":"Cube", - "type":"app", - "icon":"*cube", - "src":"-cube" - } diff --git a/apps/demoapp/app.json b/apps/demoapp/app.json deleted file mode 100644 index fab184c15c..0000000000 --- a/apps/demoapp/app.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Demo Loop", - "icon":"*demoapp", - "src":"-demoapp" -} diff --git a/apps/files/files.js b/apps/files/files.js index 9f3f7b46fb..ab8324b43a 100644 --- a/apps/files/files.js +++ b/apps/files/files.js @@ -66,8 +66,8 @@ function showApps() { '< Back': () => m = showMainMenu(), }; - var list = storage.list().filter((a)=> { - return a[0]=='+' && a !== '+setting'; + var list = storage.list(/\.info$/).filter((a)=> { + return a !== 'setting.info'; }).sort().map((app) => { var ret = storage.readJSON(app); ret[''] = app; diff --git a/apps/files/files.json b/apps/files/files.json deleted file mode 100644 index db43a7cdc3..0000000000 --- a/apps/files/files.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"App Manager","type":"app", - "icon":"*files", - "src":"-files" -} diff --git a/apps/flagrse/app.json b/apps/flagrse/app.json deleted file mode 100644 index 2fee14e86d..0000000000 --- a/apps/flagrse/app.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Flag Raiser", - "icon":"*flagrse", - "src":"-flagrse" -} diff --git a/apps/flappy/app.json b/apps/flappy/app.json deleted file mode 100644 index 262ed2658c..0000000000 --- a/apps/flappy/app.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Flappy Bird", - "icon":"*flappy", - "src":"-flappy" -} diff --git a/apps/gbridge/app.json b/apps/gbridge/app.json deleted file mode 100644 index f5c8f39915..0000000000 --- a/apps/gbridge/app.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Gadgetbridge", - "icon":"*gbridge", - "src":"-gbridge" -} diff --git a/apps/gesture/gesture.json b/apps/gesture/gesture.json deleted file mode 100644 index 48903e978e..0000000000 --- a/apps/gesture/gesture.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Gesture Test", "type":"app", - "icon":"*gesture", - "src":"-gesture" -} diff --git a/apps/gpsinfo/gps-info.json b/apps/gpsinfo/gps-info.json deleted file mode 100644 index b86b11d582..0000000000 --- a/apps/gpsinfo/gps-info.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "GPS Info", - "type": "app", - "icon": "*gpsinfo", - "src": "-gpsinfo" -} diff --git a/apps/gpsrec/app-settings.json b/apps/gpsrec/app-settings.json deleted file mode 100644 index 7e1c8ee727..0000000000 --- a/apps/gpsrec/app-settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "recording":false, - "file":0, - "period":1 -} diff --git a/apps/gpsrec/app.js b/apps/gpsrec/app.js index 3c0da22e2e..bac7e92f80 100644 --- a/apps/gpsrec/app.js +++ b/apps/gpsrec/app.js @@ -1,14 +1,14 @@ Bangle.loadWidgets(); Bangle.drawWidgets(); -var settings = require("Storage").readJSON("@gpsrec")||{}; +var settings = require("Storage").readJSON("gpsrec.json")||{}; function getFN(n) { return ".gpsrc"+n.toString(36); } function updateSettings() { - require("Storage").write("@gpsrec", settings); + require("Storage").write("gpsrec.json", settings); if (WIDGETS["gpsrec"]) WIDGETS["gpsrec"].reload(); } diff --git a/apps/gpsrec/app.json b/apps/gpsrec/app.json deleted file mode 100644 index aa8416a77c..0000000000 --- a/apps/gpsrec/app.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"GPS Recorder", - "icon":"*gpsrec", - "src":"-gpsrec" -} diff --git a/apps/gpsrec/widget.js b/apps/gpsrec/widget.js index 5ca32efdec..7e25a92add 100644 --- a/apps/gpsrec/widget.js +++ b/apps/gpsrec/widget.js @@ -55,7 +55,7 @@ // Called by the GPS app to reload settings and decide what's function reload() { - settings = require("Storage").readJSON("@gpsrec")||{}; + settings = require("Storage").readJSON("gpsrec.json")||{}; settings.period = settings.period||1; settings.file |= 0; diff --git a/apps/gpstime/gpstime.json b/apps/gpstime/gpstime.json deleted file mode 100644 index 813914e08b..0000000000 --- a/apps/gpstime/gpstime.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"GPS Time","type":"app", - "icon":"*gpstime", - "src":"-gpstime" -} diff --git a/apps/hidbkbd/hid-binary-keyboard.js b/apps/hidbkbd/hid-binary-keyboard.js index 6c595ff8e4..d48d97b473 100644 --- a/apps/hidbkbd/hid-binary-keyboard.js +++ b/apps/hidbkbd/hid-binary-keyboard.js @@ -5,7 +5,7 @@ the touchscreen var storage = require('Storage'); -const settings = storage.readJSON('@setting') || { HID: false }; +const settings = storage.readJSON('setting.json') || { HID: false }; const KEY = { A : 4 , B : 5 , diff --git a/apps/hidbkbd/hid-binary-keyboard.json b/apps/hidbkbd/hid-binary-keyboard.json deleted file mode 100644 index e2059a9c20..0000000000 --- a/apps/hidbkbd/hid-binary-keyboard.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Binary Keyboard","type":"app", - "icon": "*hidbkbd", - "src": "-hidbkbd" -} diff --git a/apps/hidkbd/hid-keyboard.js b/apps/hidkbd/hid-keyboard.js index 01f5090f0d..fe850024e0 100644 --- a/apps/hidkbd/hid-keyboard.js +++ b/apps/hidkbd/hid-keyboard.js @@ -1,6 +1,6 @@ var storage = require('Storage'); -const settings = storage.readJSON('@setting') || { HID: false }; +const settings = storage.readJSON('setting.json') || { HID: false }; var sendHid, next, prev, toggle, up, down, profile; diff --git a/apps/hidkbd/hid-keyboard.json b/apps/hidkbd/hid-keyboard.json deleted file mode 100644 index 11653b8036..0000000000 --- a/apps/hidkbd/hid-keyboard.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Keyboard Control","type":"app", - "icon": "*hidkbd", - "src": "-hidkbd" -} diff --git a/apps/hidmsic/hid-music.js b/apps/hidmsic/hid-music.js index d4dbd5f450..afee7ade90 100644 --- a/apps/hidmsic/hid-music.js +++ b/apps/hidmsic/hid-music.js @@ -1,6 +1,6 @@ var storage = require('Storage'); -const settings = storage.readJSON('@setting') || { HID: false }; +const settings = storage.readJSON('setting.json') || { HID: false }; var sendHid, next, prev, toggle, up, down, profile; diff --git a/apps/hidmsic/hid-music.json b/apps/hidmsic/hid-music.json deleted file mode 100644 index 419ed196e7..0000000000 --- a/apps/hidmsic/hid-music.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "Music Control","type":"app", - "icon": "*hidmsic", - "src": "-hidmsic" -} diff --git a/apps/horsey/horse-race.json b/apps/horsey/horse-race.json deleted file mode 100644 index cf276e2ac2..0000000000 --- a/apps/horsey/horse-race.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Horse Race", - "icon": "*horsey", - "src":"-horsey" -} diff --git a/apps/hrings/hypno-rings.json b/apps/hrings/hypno-rings.json deleted file mode 100644 index a21a845614..0000000000 --- a/apps/hrings/hypno-rings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Hypno Rings","type":"app", - "icon":"*hrings", - "src":"-hrings" -} \ No newline at end of file diff --git a/apps/hrm/heartrate.json b/apps/hrm/heartrate.json deleted file mode 100644 index 72b86993e3..0000000000 --- a/apps/hrm/heartrate.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Heart Rate","type":"app", - "icon":"*hrm", - "src":"-hrm" -} diff --git a/apps/jbells/jbells.json b/apps/jbells/jbells.json deleted file mode 100644 index 20638a2d6a..0000000000 --- a/apps/jbells/jbells.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Jingle Bells","type":"app", - "icon":"*jbells", - "src":"-jbells" -} \ No newline at end of file diff --git a/apps/launch/app.js b/apps/launch/app.js index 1b98ba8353..e93c2a3302 100644 --- a/apps/launch/app.js +++ b/apps/launch/app.js @@ -1,5 +1,5 @@ var s = require("Storage"); -var apps = s.list().filter(a=>a[0]=='+').map(app=>{ +var apps = s.list(/\.info$/).map(app=>{ try { return s.readJSON(app); } catch (e) { return {name:"DEAD: "+app.substr(1)} } }).filter(app=>app.type=="app" || app.type=="clock" || !app.type); diff --git a/apps/launch/app.json b/apps/launch/app.json deleted file mode 100644 index 20a78cd1df..0000000000 --- a/apps/launch/app.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name":"Launcher","type":"launch", - "src":"-launch" -} diff --git a/apps/mclock/clock-morphing.json b/apps/mclock/clock-morphing.json deleted file mode 100644 index bf629ac87d..0000000000 --- a/apps/mclock/clock-morphing.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name":"Morphing Clock","type":"clock", - "icon":"*mclock", - "src":"-mclock", - "sortorder":-10 -} diff --git a/apps/miclock/clock-mixed.json b/apps/miclock/clock-mixed.json deleted file mode 100644 index b5396287ad..0000000000 --- a/apps/miclock/clock-mixed.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name":"Mixed Clock","type":"clock", - "icon":"*miclock", - "src":"-miclock", - "sortorder":-10 -} diff --git a/apps/mmonday/manic-monday.json b/apps/mmonday/manic-monday.json deleted file mode 100644 index 1454658dde..0000000000 --- a/apps/mmonday/manic-monday.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Manic Monday tone", - "icon": "*mmonday", - "src":"-mmonday" -} diff --git a/apps/morse/morse-code.json b/apps/morse/morse-code.json deleted file mode 100644 index bbd142c185..0000000000 --- a/apps/morse/morse-code.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Morse Code","type":"app", - "icon":"*morse", - "src":"-morse" -} \ No newline at end of file diff --git a/apps/nceuwid/nceu-widget.json b/apps/nceuwid/nceu-widget.json deleted file mode 100644 index b7c4faa706..0000000000 --- a/apps/nceuwid/nceu-widget.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"nceuwid", - "type":"widget", - "src":"=nceuwid" -} diff --git a/apps/ncfrun/nceu-funrun.json b/apps/ncfrun/nceu-funrun.json deleted file mode 100644 index 6a62f1a667..0000000000 --- a/apps/ncfrun/nceu-funrun.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name":"5K Fun Run","type":"app", - "icon":"*ncfrun", - "src":"-ncfrun", - "sortorder":-1 -} diff --git a/apps/ncstart/start.json b/apps/ncstart/start.json deleted file mode 100644 index 73665eb7f2..0000000000 --- a/apps/ncstart/start.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "NCEU Start", - "type": "app", - "icon": "*ncstart", - "src": ".boot3" -} diff --git a/apps/nyancat/code.js b/apps/nyancat/code.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/openloc/openlocation.json b/apps/openloc/openlocation.json deleted file mode 100644 index c02a5a233d..0000000000 --- a/apps/openloc/openlocation.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Open Location","type":"app", - "icon":"*openloc", - "src":"-openloc" -} diff --git a/apps/pipboy/app.json b/apps/pipboy/app.json deleted file mode 100644 index 6d9d5a8334..0000000000 --- a/apps/pipboy/app.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Pipboy", - "icon":"*pipboy", - "src":"-pipboy" -} diff --git a/apps/pomodo/pomodoro.json b/apps/pomodo/pomodoro.json deleted file mode 100644 index c017048dfa..0000000000 --- a/apps/pomodo/pomodoro.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Pomodoro","type":"app", - "icon":"*pomodo", - "src":"-pomodo" -} diff --git a/apps/pparrot/party-parrot.json b/apps/pparrot/party-parrot.json deleted file mode 100644 index abf950e471..0000000000 --- a/apps/pparrot/party-parrot.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Party Parrot","type":"app", - "icon":"*pparrot", - "src":"-pparrot" -} \ No newline at end of file diff --git a/apps/qrcode/qrcode.html b/apps/qrcode/qrcode.html index bdc34def5a..8a00279299 100644 --- a/apps/qrcode/qrcode.html +++ b/apps/qrcode/qrcode.html @@ -41,19 +41,11 @@ g.drawString(url,120,230); g.setColor(1,1,1); `; - var json = JSON.stringify({ - name:"QR Code", - icon:"*qrcode", - src:"-qrcode" - }); var icon = `require("heatshrink").decompress(atob("mEwgP/AEX8gE8nkAn4FSngCWF6xfYDgIABHAQFPDQXD4YgDApxNDMooFOAQIdDAqIvWfcYA="))`; sendCustomizedApp({ - id : "qrcode", - storage:[ - {name:"-qrcode", content:app}, - {name:"+qrcode", content:json}, - {name:"*qrcode", content:icon, evaluate:true}, + {name:"qrcode.app.js", content:app}, + {name:"qrcode.img", content:icon, evaluate:true}, ] }); diff --git a/apps/route/route.html b/apps/route/route.html index f44fb97c58..2417aa2328 100644 --- a/apps/route/route.html +++ b/apps/route/route.html @@ -240,20 +240,12 @@ Bangle.setCompassPower(1); g.clear(); `; -var json = JSON.stringify({ -name:"Run Route", -icon:"*route", -src:"-route" -}); var icon = `require("heatshrink").decompress(atob("mEwgIkhvgFE/wEDgOHAocDgYFEgOAAp4XEEYsB4w1E5hBKnByFKw8/AQNAAQP/4EAAIMB4HggBABHoNwCwUGE4kOgEYBAMAhk+hgIBAoM/hkEAoMIv8MC4QFChARCAoIMCDoQXChkcjA1EAoJBBg5dCJoJHDKYWAsCGD4AJBAAXBDYIlCsYFBGwUzPok+AokcsOOmIUCAogAWA=="))`; sendCustomizedApp({ - id : "route", - storage:[ - {name:"-route", content:app}, - {name:"+route", content:json}, - {name:"*route", content:icon, evaluate:true}, + {name:"route.app.js", content:app}, + {name:"route.img", content:icon, evaluate:true}, ] }); }); diff --git a/apps/sbat/widget-battery.json b/apps/sbat/widget-battery.json deleted file mode 100644 index 14cea82b33..0000000000 --- a/apps/sbat/widget-battery.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name":"Battery Level","type":"widget", - "src":"=sbat" -} diff --git a/apps/sbt/widget-bluetooth.json b/apps/sbt/widget-bluetooth.json deleted file mode 100644 index 249db6fe4f..0000000000 --- a/apps/sbt/widget-bluetooth.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name":"bluetooth","type":"widget", - "src":"=sbt" -} diff --git a/apps/sclock/clock-simple.js b/apps/sclock/clock-simple.js index e298c9d3a3..9bedbc2d06 100644 --- a/apps/sclock/clock-simple.js +++ b/apps/sclock/clock-simple.js @@ -11,7 +11,7 @@ const yposYear = 175; const yposGMT = 220; // Check settings for what type our clock should be -var is12Hour = (require("Storage").readJSON("@setting")||{})["12hour"]; +var is12Hour = (require("Storage").readJSON("setting.json")||{})["12hour"]; function drawSimpleClock() { // get date diff --git a/apps/sclock/clock-simple.json b/apps/sclock/clock-simple.json deleted file mode 100644 index 66cf827baf..0000000000 --- a/apps/sclock/clock-simple.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name":"Simple Clock", - "type":"clock", - "icon":"*sclock", - "src":"-sclock", - "sortorder":-10 -} diff --git a/apps/scolor/show-color.json b/apps/scolor/show-color.json deleted file mode 100644 index 70d28e9d37..0000000000 --- a/apps/scolor/show-color.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Show Color","type":"app", - "icon":"*scolor", - "src":"-scolor" -} diff --git a/apps/setting/settings.js b/apps/setting/settings.js index 69478c9df7..568a64047b 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -5,8 +5,8 @@ const storage = require('Storage'); let settings; function updateSettings() { - //storage.erase('@setting'); // - not needed, just causes extra writes if settings were the same - storage.write('@setting', settings); + //storage.erase('setting.json'); // - not needed, just causes extra writes if settings were the same + storage.write('setting.json', settings); } function resetSettings() { @@ -28,7 +28,7 @@ function resetSettings() { } try { - settings = storage.readJSON('@setting'); + settings = storage.readJSON('setting.json'); } catch (e) {} if (!settings) resetSettings(); @@ -187,7 +187,7 @@ function makeConnectable() { }); } function showClockMenu() { - var clockApps = require("Storage").list().filter(a=>a[0]=='+').map(app=>{ + var clockApps = require("Storage").list(/\.info$/).map(app=>{ try { return require("Storage").readJSON(app); } catch (e) {} }).filter(app=>app.type=="clock").sort((a, b) => a.sortorder - b.sortorder); diff --git a/apps/setting/settings.json b/apps/setting/settings.json deleted file mode 100644 index dcadf616ab..0000000000 --- a/apps/setting/settings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "Settings","type":"app", - "icon": "*setting", - "src": "-setting", - "sortorder": -15 -} diff --git a/apps/slevel/spiritlevel.json b/apps/slevel/spiritlevel.json deleted file mode 100644 index 0a77fd60fb..0000000000 --- a/apps/slevel/spiritlevel.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Spirit Level","type":"app", - "icon":"*slevel", - "src":"-slevel" -} diff --git a/apps/speedo/speedo.json b/apps/speedo/speedo.json deleted file mode 100644 index ce1c8b82e7..0000000000 --- a/apps/speedo/speedo.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Speedo","type":"app", - "icon":"*speedo", - "src":"-speedo" -} diff --git a/apps/stetho/stetho.json b/apps/stetho/stetho.json deleted file mode 100644 index 239fffb684..0000000000 --- a/apps/stetho/stetho.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Stethoscope","type":"app", - "icon":"*stetho", - "src":"-stetho" -} diff --git a/apps/swatch/stopwatch.json b/apps/swatch/stopwatch.json deleted file mode 100644 index ab4d401f54..0000000000 --- a/apps/swatch/stopwatch.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Stopwatch","type":"app", - "icon":"*swatch", - "src":"-swatch" -} diff --git a/apps/trex/trex.json b/apps/trex/trex.json deleted file mode 100644 index e54d4ddb64..0000000000 --- a/apps/trex/trex.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"T-Rex","type":"app", - "icon":"*trex", - "src":"-trex" -} diff --git a/apps/wclock/clock-word.json b/apps/wclock/clock-word.json deleted file mode 100644 index 594b73f174..0000000000 --- a/apps/wclock/clock-word.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name":"Word Clock","type":"clock", - "icon":"*wclock", - "src":"-wclock", - "sortorder":-10 -} diff --git a/apps/wdclk/digital_clock_widget.json b/apps/wdclk/digital_clock_widget.json deleted file mode 100644 index 5d73e70e52..0000000000 --- a/apps/wdclk/digital_clock_widget.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Digital Clock Widget", "type":"widget", - "src":"=wdclk" - } - \ No newline at end of file diff --git a/apps/welcome/app.js b/apps/welcome/app.js index fdc8f15e43..79a085b142 100644 --- a/apps/welcome/app.js +++ b/apps/welcome/app.js @@ -284,9 +284,9 @@ setWatch(()=>{ // If we're on the last page if (sceneNumber == scenes.length-1) { try { - var settings = require("Storage").readJSON('@setting'); + var settings = require("Storage").readJSON('setting.json'); settings.welcomed = true; - require("Storage").write('@setting',settings); + require("Storage").write('setting.json',settings); } catch (e) {} load(); } diff --git a/apps/welcome/app.json b/apps/welcome/app.json deleted file mode 100644 index 584f9fc40b..0000000000 --- a/apps/welcome/app.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Welcome", - "icon":"*welcome", - "src":"-welcome" -} diff --git a/apps/whrm/widget.json b/apps/whrm/widget.json deleted file mode 100644 index fbc51b789b..0000000000 --- a/apps/whrm/widget.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name":"Heart Rate Widget", "type":"widget", - "src":"=whrm" -} diff --git a/apps/sbat/ChangeLog b/apps/widbat/ChangeLog similarity index 100% rename from apps/sbat/ChangeLog rename to apps/widbat/ChangeLog diff --git a/apps/sbat/widget-battery.js b/apps/widbat/widget.js similarity index 100% rename from apps/sbat/widget-battery.js rename to apps/widbat/widget.js diff --git a/apps/sbat/widget-battery.png b/apps/widbat/widget.png similarity index 100% rename from apps/sbat/widget-battery.png rename to apps/widbat/widget.png diff --git a/apps/sbt/widget-bluetooth.js b/apps/widbt/widget.js similarity index 100% rename from apps/sbt/widget-bluetooth.js rename to apps/widbt/widget.js diff --git a/apps/sbt/widget-bluetooth.png b/apps/widbt/widget.png similarity index 100% rename from apps/sbt/widget-bluetooth.png rename to apps/widbt/widget.png diff --git a/apps/wdclk/digital_clock_widget.js b/apps/widclk/widget.js similarity index 100% rename from apps/wdclk/digital_clock_widget.js rename to apps/widclk/widget.js diff --git a/apps/wdclk/digital_clock_widget.png b/apps/widclk/widget.png similarity index 100% rename from apps/wdclk/digital_clock_widget.png rename to apps/widclk/widget.png diff --git a/apps/whrm/ChangeLog b/apps/widhrm/ChangeLog similarity index 100% rename from apps/whrm/ChangeLog rename to apps/widhrm/ChangeLog diff --git a/apps/whrm/widget.js b/apps/widhrm/widget.js similarity index 100% rename from apps/whrm/widget.js rename to apps/widhrm/widget.js diff --git a/apps/whrm/widget.png b/apps/widhrm/widget.png similarity index 100% rename from apps/whrm/widget.png rename to apps/widhrm/widget.png diff --git a/apps/nceuwid/nceu-widget.js b/apps/widnceu/widget.js similarity index 100% rename from apps/nceuwid/nceu-widget.js rename to apps/widnceu/widget.js diff --git a/apps/nceuwid/nceu-widget.png b/apps/widnceu/widget.png similarity index 100% rename from apps/nceuwid/nceu-widget.png rename to apps/widnceu/widget.png diff --git a/apps/wpedom/pedometer_widget.json b/apps/wpedom/pedometer_widget.json deleted file mode 100644 index 18703a2dee..0000000000 --- a/apps/wpedom/pedometer_widget.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Pedometer Widget", "type":"widget", - "src":"=wpedom" - } - \ No newline at end of file diff --git a/apps/wpedom/pedometer_widget.js b/apps/wpedom/widget.js similarity index 98% rename from apps/wpedom/pedometer_widget.js rename to apps/wpedom/widget.js index f281eaf7bd..84a4bb2112 100644 --- a/apps/wpedom/pedometer_widget.js +++ b/apps/wpedom/widget.js @@ -1,5 +1,5 @@ (() => { - const PEDOMFILE = "@wpedom"; + const PEDOMFILE = "wpedom.json"; // add the width // WIDGETPOS.tr is originally 208 without any widgets var xpos = WIDGETPOS.tl; diff --git a/apps/wpedom/pedometer_widget.png b/apps/wpedom/widget.png similarity index 100% rename from apps/wpedom/pedometer_widget.png rename to apps/wpedom/widget.png diff --git a/comms.js b/comms.js index 74c150c6c9..0b1aab9709 100644 --- a/comms.js +++ b/comms.js @@ -2,26 +2,15 @@ Puck.debug=3; // FIXME: use UART lib so that we handle errors properly var Comms = { -reset : () => { - return new Promise((resolve,reject) => { - Puck.write("\x03reset();\n", (result) => { - if (result===null) return reject(""); - setTimeout(resolve,500); - }); +reset : () => new Promise((resolve,reject) => { + Puck.write("\x03reset();\n", (result) => { + if (result===null) return reject(""); + setTimeout(resolve,500); }); -}, +}), uploadApp : (app,skipReset) => { return AppInfo.getFiles(app, httpGet).then(fileContents => { return new Promise((resolve,reject) => { - var appJSONFile = fileContents.find(f=>f.name=="+"+app.id); - var appJSON = undefined; - if (appJSONFile) - try { - appJSON=JSON.parse(appJSONFile.content); - appJSON.id = app.id; - } catch(e) { - console.log("Error decoding app JSON for",app.id,e); - } fileContents = fileContents.map(storageFile=>storageFile.cmd).join("\n")+"\n"; console.log("uploadApp",fileContents); function doUpload() { @@ -43,7 +32,8 @@ getInstalledApps : () => { return new Promise((resolve,reject) => { Puck.write("\x03",(result) => { if (result===null) return reject(""); - Puck.eval('require("Storage").list().filter(f=>f[0]=="+").map(f=>{var j=require("Storage").readJSON(f)||{};j.id=f.substr(1);return j})', (appList,err) => { + // could use .list(/\.info$/) on new Espruino firmwares... + Puck.eval('require("Storage").list().filter(f=>f.endsWith(".info")).map(f=>{var j=require("Storage").readJSON(f)||{};j.id=f.substr(1);return j})', (appList,err) => { if (appList===null) return reject(err || ""); console.log("getInstalledApps", appList); resolve(appList); @@ -64,10 +54,10 @@ removeApp : app => { // expects an app structure })); }, removeAllApps : () => { - return Comms.reset().then(new Promise((resolve,reject) => { + return Comms.reset().then(() => new Promise((resolve,reject) => { // Use write with newline here so we wait for it to finish Puck.write('\x10E.showMessage("Erasing...");require("Storage").eraseAll();Bluetooth.println("OK")\n', (result,err) => { - if (result===null) return reject(err || ""); + if (!result || result.trim()!="OK") return reject(err || ""); resolve(); }, true /* wait for newline */); })); @@ -79,7 +69,7 @@ setTime : () => { var cmd = '\x03\x10setTime('+(d.getTime()/1000)+');'; // in 1v93 we have timezones too cmd += 'E.setTimeZone('+tz+');'; - cmd += "(s=>{s&&(s.timezone="+tz+")&&require('Storage').write('@setting',s);})(require('Storage').readJSON('@setting'))\n"; + cmd += "(s=>{s&&(s.timezone="+tz+")&&require('Storage').write('setting.json',s);})(require('Storage').readJSON('setting.json'))\n"; Puck.write(cmd, (result) => { if (result===null) return reject(""); resolve(); diff --git a/defaultapps.json b/defaultapps.json index 2544af0014..df508f2e47 100644 --- a/defaultapps.json +++ b/defaultapps.json @@ -1 +1 @@ -["boot","launch","mclock","setting","about","alarm","sbat","sbt","welcome"] +["boot","launch","mclock","setting","about","alarm","widbat","widbt","welcome"] diff --git a/firmware.js b/firmware.js index 08f34e99b1..a6923ab1c9 100644 --- a/firmware.js +++ b/firmware.js @@ -1,12 +1,12 @@ // Generated by BangleApps/bin/firmwaremaker.js -require('Storage').write(".bootcde","E.setFlags({pretokenise:1});\nvar startapp;\ntry {\n startapp = require('Storage').readJSON('+start');\n} catch (e) {}\nif (startapp) {\n eval(require(\"Storage\").read(startapp.src));\n} else {\n setWatch(function displayMenu() {\n Bangle.setLCDOffset(0); // remove notifications\n Bangle.setLCDMode(\"direct\");\n g.clear();\n // attempt to remove any currently-running code\n clearInterval();\n clearWatch();\n Bangle.removeAllListeners();\n NRF.removeAllListeners();\n Bluetooth.removeAllListeners();\n E.removeAllListeners();\n delete GB;\n delete WIDGETS;\n delete WIDGETPOS;\n delete drawWidgets;\n var s = require(\"Storage\");\n var apps = s.list().filter(a=>a[0]=='+').map(app=>{\n try { return s.readJSON(app); }\n catch (e) { return {name:\"DEAD: \"+app.substr(1)} }\n }).filter(app=>app.type==\"app\" || app.type==\"clock\" || !app.type);\n apps.sort((a,b)=>{\n var n=(0|a.sortorder)-(0|b.sortorder);\n if (n) return n; // do sortorder first\n if (a.nameb.name) return 1;\n return 0;\n });\n var selected = 0;\n var menuScroll = 0;\n var menuShowing = false;\n\n function drawMenu() {\n g.setFont(\"6x8\",2);\n g.setFontAlign(-1,0);\n var n = 3;\n if (selected>=n+menuScroll) menuScroll = 1+selected-n;\n if (selectedn+menuScroll) g.fillPoly([120,239,100,219,140,219]);\n else g.clearRect(100,219,140,239);\n for (var i=0;i0) {\n selected--;\n drawMenu();\n }\n }, BTN1, {repeat:true});\n setWatch(function() {\n if (selected+1a[0]=='=').forEach(widget=>eval(require(\"Storage\").read(widget)));\n setTimeout(drawWidgets,100);\n // load clock if specified\n var clockApp = settings.clock;\n if (clockApp) clockApp = require(\"Storage\").read(clockApp)\n if (!clockApp) {\n var clockApps = require(\"Storage\").list().filter(a=>a[0]=='+').map(app=>{\n try { return require(\"Storage\").readJSON(app); }\n catch (e) {}\n }).filter(app=>app.type==\"clock\").sort((a, b) => a.sortorder - b.sortorder);\n if (clockApps && clockApps.length > 0)\n clockApp = require(\"Storage\").read(clockApps[0].src);\n delete clockApps;\n }\n if (clockApp) eval(clockApp);\n else E.showMessage(\"No Clock Found\");\n delete clockApp;\n}\n"); +require('Storage').write(".bootcde","E.setFlags({pretokenise:1});\nvar startapp;\ntry {\n startapp = require('Storage').readJSON('+start');\n} catch (e) {}\nif (startapp) {\n eval(require(\"Storage\").read(startapp.src));\n} else {\n setWatch(function displayMenu() {\n Bangle.setLCDOffset(0); // remove notifications\n Bangle.setLCDMode(\"direct\");\n g.clear();\n // attempt to remove any currently-running code\n clearInterval();\n clearWatch();\n Bangle.removeAllListeners();\n NRF.removeAllListeners();\n Bluetooth.removeAllListeners();\n E.removeAllListeners();\n delete GB;\n delete WIDGETS;\n delete WIDGETPOS;\n delete drawWidgets;\n var s = require(\"Storage\");\n var apps = s.list().filter(a=>a[0]=='+').map(app=>{\n try { return s.readJSON(app); }\n catch (e) { return {name:\"DEAD: \"+app.substr(1)} }\n }).filter(app=>app.type==\"app\" || app.type==\"clock\" || !app.type);\n apps.sort((a,b)=>{\n var n=(0|a.sortorder)-(0|b.sortorder);\n if (n) return n; // do sortorder first\n if (a.nameb.name) return 1;\n return 0;\n });\n var selected = 0;\n var menuScroll = 0;\n var menuShowing = false;\n\n function drawMenu() {\n g.setFont(\"6x8\",2);\n g.setFontAlign(-1,0);\n var n = 3;\n if (selected>=n+menuScroll) menuScroll = 1+selected-n;\n if (selectedn+menuScroll) g.fillPoly([120,239,100,219,140,219]);\n else g.clearRect(100,219,140,239);\n for (var i=0;i0) {\n selected--;\n drawMenu();\n }\n }, BTN1, {repeat:true});\n setWatch(function() {\n if (selected+1a[0]=='=').forEach(widget=>eval(require(\"Storage\").read(widget)));\n setTimeout(drawWidgets,100);\n // load clock if specified\n var clockApp = settings.clock;\n if (clockApp) clockApp = require(\"Storage\").read(clockApp)\n if (!clockApp) {\n var clockApps = require(\"Storage\").list().filter(a=>a[0]=='+').map(app=>{\n try { return require(\"Storage\").readJSON(app); }\n catch (e) {}\n }).filter(app=>app.type==\"clock\").sort((a, b) => a.sortorder - b.sortorder);\n if (clockApps && clockApps.length > 0)\n clockApp = require(\"Storage\").read(clockApps[0].src);\n delete clockApps;\n }\n if (clockApp) eval(clockApp);\n else E.showMessage(\"No Clock Found\");\n delete clockApp;\n}\n"); require('Storage').write("+mclock",{"name":"Morphing Clock","type":"clock","icon":"*mclock","src":"-mclock","sortorder":-10,"version":"0.01","files":"+mclock,-mclock,*mclock"}); require('Storage').write("-mclock","(function(){ // make our own scope so this is GC'd when intervals are cleared\n// Offscreen buffer\nvar buf = Graphics.createArrayBuffer(240,86,1,{msb:true});\nfunction flip() {\n g.setColor(1,1,1);\n g.drawImage({width:buf.getWidth(),height:buf.getHeight(),buffer:buf.buffer},0,50);\n}\n// The last time that we displayed\nvar lastTime = \" \";\n// If animating, this is the interval's id\nvar animInterval;\n\n/* Get array of lines from digit d to d+1.\n n is the amount (0..1)\n maxFive is true is this digit only counts 0..5 */\nconst DIGITS = {\n\" \":n=>[],\n\"0\":n=>[\n[n,0,1,0],\n[1,0,1,1],\n[1,1,1,2],\n[n,2,1,2],\n[n,1,n,2],\n[n,0,n,1]],\n\"1\":n=>[\n[1-n,0,1,0],\n[1,0,1,1],\n[1-n,1,1,1],\n[1-n,1,1-n,2],\n[1-n,2,1,2]],\n\"2\":n=>[\n[0,0,1,0],\n[1,0,1,1],\n[0,1,1,1],\n[0,1+n,0,2],\n[1,2-n,1,2],\n[0,2,1,2]],\n\"3\":n=>[\n[0,0,1-n,0],\n[0,0,0,n],\n[1,0,1,1],\n[0,1,1,1],\n[1,1,1,2],\n[n,2,1,2]],\n\"4\":n=>[\n[0,0,0,1],\n[1,0,1-n,0],\n[1,0,1,1-n],\n[0,1,1,1],\n[1,1,1,2],\n[1-n,2,1,2]],\n\"5\": (n,maxFive)=>maxFive ? [ // 5 -> 0\n[0,0,0,1],\n[0,0,1,0],\n[n,1,1,1],\n[1,1,1,2],\n[0,2,1,2],\n[0,2,0,2],\n[1,1-n,1,1],\n[0,1,0,1+n]] : [ // 5 -> 6\n[0,0,0,1],\n[0,0,1,0],\n[0,1,1,1],\n[1,1,1,2],\n[0,2,1,2],\n[0,2-n,0,2]],\n\"6\":n=>[\n[0,0,0,1-n],\n[0,0,1,0],\n[n,1,1,1],\n[1,1-n,1,1],\n[1,1,1,2],\n[n,2,1,2],\n[0,1-n,0,2-2*n]],\n\"7\":n=>[\n[0,0,0,n],\n[0,0,1,0],\n[1,0,1,1],\n[1-n,1,1,1],\n[1,1,1,2],\n[1-n,2,1,2],\n[1-n,1,1-n,2]],\n\"8\":n=>[\n[0,0,0,1],\n[0,0,1,0],\n[1,0,1,1],\n[0,1,1,1],\n[1,1,1,2],\n[0,2,1,2],\n[0,1,0,2-n]],\n\"9\":n=>[\n[0,0,0,1],\n[0,0,1,0],\n[1,0,1,1],\n[0,1,1-n,1],\n[0,1,0,1+n],\n[1,1,1,2],\n[0,2,1,2]],\n\":\":n=>[\n[0.4,0.4,0.6,0.4],\n[0.6,0.4,0.6,0.6],\n[0.6,0.6,0.4,0.6],\n[0.4,0.4,0.4,0.6],\n[0.4,1.4,0.6,1.4],\n[0.6,1.4,0.6,1.6],\n[0.6,1.6,0.4,1.6],\n[0.4,1.4,0.4,1.6]]\n};\n\n/* Draw a transition between lastText and thisText.\n 'n' is the amount - 0..1 */\nfunction draw(lastText,thisText,n) {\n buf.clear();\n var x = 1; // x offset\n const p = 2; // padding around digits\n var y = p; // y offset\n const s = 34; // character size\n for (var i=0;i{\n if (c[0]!=c[2]) // horiz\n buf.fillRect(x+c[0]*s,y+c[1]*s-p,x+c[2]*s,y+c[3]*s+p);\n else if (c[1]!=c[3]) // vert\n buf.fillRect(x+c[0]*s-p,y+c[1]*s,x+c[2]*s+p,y+c[3]*s);\n });\n if (thisCh==\":\") x-=4;\n x+=s+p+7;\n }\n y += 2*s;\n var d = new Date();\n buf.setFont(\"6x8\");\n buf.setFontAlign(-1,-1);\n buf.drawString((\"0\"+d.getSeconds()).substr(-2), x, y-8);\n // date\n buf.setFontAlign(0,-1);\n var date = d.toString().substr(0,15);\n buf.drawString(date, buf.getWidth()/2, y+8);\n flip();\n}\n\n/* Show the current time, and animate if needed */\nfunction showTime() {\n if (!Bangle.isLCDOn()) return;\n if (animInterval) return; // in animation - quit\n var d = new Date();\n var t = (\" \"+d.getHours()).substr(-2)+\":\"+\n (\"0\"+d.getMinutes()).substr(-2);\n var l = lastTime;\n // same - don't animate\n if (t==l) {\n draw(t,l,0);\n return;\n }\n var n = 0;\n animInterval = setInterval(function() {\n n += 1/10;\n if (n>=1) {\n n=1;\n clearInterval(animInterval);\n animInterval=0;\n }\n draw(l,t,n);\n }, 20);\n lastTime = t;\n}\n\nBangle.on('lcdPower',function(on) {\n if (on) {\n showTime();\n drawWidgets();\n }\n});\n\ng.clear();\n// Update time once a second\nsetInterval(showTime, 1000);\nshowTime();\n})();\n"); require('Storage').write("*mclock",require("heatshrink").decompress(atob("mEwghC/AE8IxAAEwAWVDB4WIDBwWJAAIWPmf//8zDBpFDwYVBAAc4JJYWJDAoXKn4SC+EPAgXzC5JGCx4qDC4n//BIIEIRCEC4v/GBBdHC4xhCIw5dDC5BhCJAgXCRQoXGJAQXEUhAXHJAyNGC5KRCC7p2FC5B4CC5kggQXOBwvyBQMvSA4XL+EIwCoIC8ZHCgYXNO44LBBIiPPCAIwFC5DXGAAMwGAjvPGA4XIwYXHGALBDnAXFhCQHGAaOFwAXGPA4bFC4xIMIxIXDJBJGEC4xICSJCNEIwowEMJBdCFwwXEMJBdCC5BICDA4WDIw4wEAAMzCoMzBAgWIDAwAGCxRJEAAxFJDBgWNDBAWPAH4AYA=="))); -require('Storage').write("+setting",{"name":"Settings","type":"app","icon":"*settings","src":"-settings","version":"0.01","files":"+setting,-setting,=setting,@setting,*setting"}); -require('Storage').write("-setting","Bangle.setLCDPower(1);\nBangle.setLCDTimeout(0);\n\ng.clear();\nconst storage = require('Storage');\nlet settings;\n\nfunction debug(msg, arg) {\n if (settings.debug)\n console.log(msg, arg);\n}\n\nfunction updateSettings() {\n debug('updating settings', settings);\n //storage.erase('@setting'); // - not needed, just causes extra writes if settings were the same\n storage.write('@setting', settings);\n}\n\nfunction resetSettings() {\n settings = {\n ble: true,\n dev: true,\n timeout: 10,\n vibrate: true,\n beep: true,\n timezone: 0,\n HID : false,\n HIDGestures: false,\n debug: false,\n clock: null\n };\n setLCDTimeout(settings.timeout);\n updateSettings();\n}\n\ntry {\n settings = storage.readJSON('@setting');\n} catch (e) {}\nif (!settings) resetSettings();\n\nconst boolFormat = (v) => v ? \"On\" : \"Off\";\n\nfunction showMainMenu() {\n const mainmenu = {\n '': { 'title': 'Settings' },\n 'BLE': {\n value: settings.ble,\n format: boolFormat,\n onchange: () => {\n settings.ble = !settings.ble;\n updateSettings();\n }\n },\n 'Programmable': {\n value: settings.dev,\n format: boolFormat,\n onchange: () => {\n settings.dev = !settings.dev;\n updateSettings();\n }\n },\n 'LCD Timeout': {\n value: settings.timeout,\n min: 0,\n max: 60,\n step: 5,\n onchange: v => {\n settings.timeout = 0 | v;\n updateSettings();\n Bangle.setLCDTimeout(settings.timeout);\n }\n },\n 'Beep': {\n value: settings.beep,\n format: boolFormat,\n onchange: () => {\n settings.beep = !settings.beep;\n updateSettings();\n if (settings.beep) {\n Bangle.beep(1);\n }\n }\n },\n 'Vibration': {\n value: settings.vibrate,\n format: boolFormat,\n onchange: () => {\n settings.vibrate = !settings.vibrate;\n updateSettings();\n if (settings.vibrate) {\n VIBRATE.write(1);\n setTimeout(()=>VIBRATE.write(0), 10);\n }\n }\n },\n 'Select Clock': showClockMenu,\n 'Time Zone': {\n value: settings.timezone,\n min: -11,\n max: 12,\n step: 1,\n onchange: v => {\n settings.timezone = 0 | v;\n updateSettings();\n }\n },\n 'HID': {\n value: settings.HID,\n format: boolFormat,\n onchange: () => {\n settings.HID = !settings.HID;\n updateSettings();\n }\n },\n 'HID Gestures': {\n value: settings.HIDGestures,\n format: boolFormat,\n onchange: () => {\n settings.HIDGestures = !settings.HIDGestures;\n updateSettings();\n }\n },\n 'Debug': {\n value: settings.debug,\n format: boolFormat,\n onchange: () => {\n settings.debug = !settings.debug;\n updateSettings();\n }\n },\n 'Set Time': showSetTimeMenu,\n 'Make Connectable': makeConnectable,\n 'Reset Settings': showResetMenu,\n 'Turn Off': Bangle.off,\n '< Back': load\n };\n return Bangle.menu(mainmenu);\n}\n\nfunction showResetMenu() {\n const resetmenu = {\n '': { 'title': 'Reset' },\n '< Back': showMainMenu,\n 'Reset Settings': () => {\n E.showPrompt('Reset Settings?').then((v) => {\n if (v) {\n E.showMessage('Resetting');\n resetSettings();\n }\n setTimeout(showMainMenu, 50);\n });\n },\n // this is include for debugging. remove for production\n /*'Erase': () => {\n storage.erase('=setting');\n storage.erase('-setting');\n storage.erase('@setting');\n storage.erase('*setting');\n storage.erase('+setting');\n E.reboot();\n }*/\n };\n return Bangle.menu(resetmenu);\n}\n\nfunction makeConnectable() {\n try { NRF.wake(); } catch(e) {}\n Bluetooth.setConsole(1);\n var name=\"Bangle.js \"+NRF.getAddress().substr(-5).replace(\":\",\"\");\n E.showPrompt(name+\"\\nStay Connectable?\",{title:\"Connectable\"}).then(r=>{\n if (settings.ble!=r) {\n settings.ble = r;\n updateSettings();\n }\n if (!r) try { NRF.sleep(); } catch(e) {}\n showMainMenu();\n });\n}\nfunction showClockMenu() {\n var clockApps = require(\"Storage\").list().filter(a=>a[0]=='+').map(app=>{\n try { return require(\"Storage\").readJSON(app); }\n catch (e) {}\n }).filter(app=>app.type==\"clock\").sort((a, b) => a.sortorder - b.sortorder);\n const clockMenu = {\n '': {\n 'title': 'Select Clock',\n },\n '< Back': showMainMenu,\n };\n clockApps.forEach((app,index) => {\n var label = app.name;\n if ((!settings.clock && index === 0) || (settings.clock === app.src)) {\n label = \"* \"+label;\n }\n clockMenu[label] = () => {\n if (settings.clock !== app.src) {\n settings.clock = app.src;\n updateSettings();\n showMainMenu();\n }\n };\n });\n if (clockApps.length === 0) {\n clockMenu[\"No Clocks Found\"] = () => {};\n }\n return Bangle.menu(clockMenu);\n}\n\n\n\nfunction showSetTimeMenu() {\n d = new Date();\n const timemenu = {\n '': {\n 'title': 'Set Time',\n 'predraw': function() {\n d = new Date();\n timemenu.Hour.value = d.getHours();\n timemenu.Minute.value = d.getMinutes();\n timemenu.Second.value = d.getSeconds();\n timemenu.Date.value = d.getDate();\n timemenu.Month.value = d.getMonth() + 1;\n timemenu.Year.value = d.getFullYear();\n }\n },\n '< Back': showMainMenu,\n 'Hour': {\n value: d.getHours(),\n min: 0,\n max: 23,\n step: 1,\n onchange: v => {\n d = new Date();\n d.setHours(v);\n setTime(d.getTime()/1000);\n }\n },\n 'Minute': {\n value: d.getMinutes(),\n min: 0,\n max: 59,\n step: 1,\n onchange: v => {\n d = new Date();\n d.setMinutes(v);\n setTime(d.getTime()/1000);\n }\n },\n 'Second': {\n value: d.getSeconds(),\n min: 0,\n max: 59,\n step: 1,\n onchange: v => {\n d = new Date();\n d.setSeconds(v);\n setTime(d.getTime()/1000);\n }\n },\n 'Date': {\n value: d.getDate(),\n min: 1,\n max: 31,\n step: 1,\n onchange: v => {\n d = new Date();\n d.setDate(v);\n setTime(d.getTime()/1000);\n }\n },\n 'Month': {\n value: d.getMonth() + 1,\n min: 1,\n max: 12,\n step: 1,\n onchange: v => {\n d = new Date();\n d.setMonth(v - 1);\n setTime(d.getTime()/1000);\n }\n },\n 'Year': {\n value: d.getFullYear(),\n min: 2019,\n max: 2100,\n step: 1,\n onchange: v => {\n d = new Date();\n d.setFullYear(v);\n setTime(d.getTime()/1000);\n }\n }\n };\n return Bangle.menu(timemenu);\n}\n\nshowMainMenu();\n"); -require('Storage').write("=setting","Bangle.HID = E.toUint8Array(atob(\"BQEJBqEBhQIFBxngKecVACUBdQGVCIEClQF1CIEBlQV1AQUIGQEpBZEClQF1A5EBlQZ1CBUAJXMFBxkAKXOBAAkFFQAm/wB1CJUCsQLABQwJAaEBhQEVACUBdQGVAQm1gQIJtoECCbeBAgm4gQIJzYECCeKBAgnpgQIJ6oECwA==\"));\n\n(function() {\n var s = require('Storage').readJSON('@setting');\n var adv = { uart: true };\n if (s.ble) {\n if (s.dev)\n Bluetooth.setConsole(true);\n else\n Terminal.setConsole(true);\n if (s.HID) {\n adv.hid = Bangle.HID;\n } else\n delete Bangle.HID;\n }\n NRF.setServices({}, adv);\n // we just reset, so BLE should be on\n try { // disable advertising if BLE should be off\n if (!s.ble) NRF.sleep();\n else NRF.wake();\n } catch(e) {}\n if (!s.vibrate) Bangle.buzz=Promise.resolve;\n if (!s.beep) Bangle.beep=Promise.resolve;\n Bangle.setLCDTimeout(s.timeout);\n if (!s.timeout) Bangle.setLCDPower(1);\n E.setTimeZone(s.timezone);\n})()\n"); -require('Storage').write("@setting",{ +require('Storage').write("+setting",{"name":"Settings","type":"app","icon":"*settings","src":"-settings","version":"0.01","files":"+setting,-setting,=setting,setting.json,*setting"}); +require('Storage').write("-setting","Bangle.setLCDPower(1);\nBangle.setLCDTimeout(0);\n\ng.clear();\nconst storage = require('Storage');\nlet settings;\n\nfunction debug(msg, arg) {\n if (settings.debug)\n console.log(msg, arg);\n}\n\nfunction updateSettings() {\n debug('updating settings', settings);\n //storage.erase('setting.json'); // - not needed, just causes extra writes if settings were the same\n storage.write('setting.json', settings);\n}\n\nfunction resetSettings() {\n settings = {\n ble: true,\n dev: true,\n timeout: 10,\n vibrate: true,\n beep: true,\n timezone: 0,\n HID : false,\n HIDGestures: false,\n debug: false,\n clock: null\n };\n setLCDTimeout(settings.timeout);\n updateSettings();\n}\n\ntry {\n settings = storage.readJSON('setting.json');\n} catch (e) {}\nif (!settings) resetSettings();\n\nconst boolFormat = (v) => v ? \"On\" : \"Off\";\n\nfunction showMainMenu() {\n const mainmenu = {\n '': { 'title': 'Settings' },\n 'BLE': {\n value: settings.ble,\n format: boolFormat,\n onchange: () => {\n settings.ble = !settings.ble;\n updateSettings();\n }\n },\n 'Programmable': {\n value: settings.dev,\n format: boolFormat,\n onchange: () => {\n settings.dev = !settings.dev;\n updateSettings();\n }\n },\n 'LCD Timeout': {\n value: settings.timeout,\n min: 0,\n max: 60,\n step: 5,\n onchange: v => {\n settings.timeout = 0 | v;\n updateSettings();\n Bangle.setLCDTimeout(settings.timeout);\n }\n },\n 'Beep': {\n value: settings.beep,\n format: boolFormat,\n onchange: () => {\n settings.beep = !settings.beep;\n updateSettings();\n if (settings.beep) {\n Bangle.beep(1);\n }\n }\n },\n 'Vibration': {\n value: settings.vibrate,\n format: boolFormat,\n onchange: () => {\n settings.vibrate = !settings.vibrate;\n updateSettings();\n if (settings.vibrate) {\n VIBRATE.write(1);\n setTimeout(()=>VIBRATE.write(0), 10);\n }\n }\n },\n 'Select Clock': showClockMenu,\n 'Time Zone': {\n value: settings.timezone,\n min: -11,\n max: 12,\n step: 1,\n onchange: v => {\n settings.timezone = 0 | v;\n updateSettings();\n }\n },\n 'HID': {\n value: settings.HID,\n format: boolFormat,\n onchange: () => {\n settings.HID = !settings.HID;\n updateSettings();\n }\n },\n 'HID Gestures': {\n value: settings.HIDGestures,\n format: boolFormat,\n onchange: () => {\n settings.HIDGestures = !settings.HIDGestures;\n updateSettings();\n }\n },\n 'Debug': {\n value: settings.debug,\n format: boolFormat,\n onchange: () => {\n settings.debug = !settings.debug;\n updateSettings();\n }\n },\n 'Set Time': showSetTimeMenu,\n 'Make Connectable': makeConnectable,\n 'Reset Settings': showResetMenu,\n 'Turn Off': Bangle.off,\n '< Back': load\n };\n return Bangle.menu(mainmenu);\n}\n\nfunction showResetMenu() {\n const resetmenu = {\n '': { 'title': 'Reset' },\n '< Back': showMainMenu,\n 'Reset Settings': () => {\n E.showPrompt('Reset Settings?').then((v) => {\n if (v) {\n E.showMessage('Resetting');\n resetSettings();\n }\n setTimeout(showMainMenu, 50);\n });\n },\n // this is include for debugging. remove for production\n /*'Erase': () => {\n storage.erase('=setting');\n storage.erase('-setting');\n storage.erase('setting.json');\n storage.erase('*setting');\n storage.erase('+setting');\n E.reboot();\n }*/\n };\n return Bangle.menu(resetmenu);\n}\n\nfunction makeConnectable() {\n try { NRF.wake(); } catch(e) {}\n Bluetooth.setConsole(1);\n var name=\"Bangle.js \"+NRF.getAddress().substr(-5).replace(\":\",\"\");\n E.showPrompt(name+\"\\nStay Connectable?\",{title:\"Connectable\"}).then(r=>{\n if (settings.ble!=r) {\n settings.ble = r;\n updateSettings();\n }\n if (!r) try { NRF.sleep(); } catch(e) {}\n showMainMenu();\n });\n}\nfunction showClockMenu() {\n var clockApps = require(\"Storage\").list().filter(a=>a[0]=='+').map(app=>{\n try { return require(\"Storage\").readJSON(app); }\n catch (e) {}\n }).filter(app=>app.type==\"clock\").sort((a, b) => a.sortorder - b.sortorder);\n const clockMenu = {\n '': {\n 'title': 'Select Clock',\n },\n '< Back': showMainMenu,\n };\n clockApps.forEach((app,index) => {\n var label = app.name;\n if ((!settings.clock && index === 0) || (settings.clock === app.src)) {\n label = \"* \"+label;\n }\n clockMenu[label] = () => {\n if (settings.clock !== app.src) {\n settings.clock = app.src;\n updateSettings();\n showMainMenu();\n }\n };\n });\n if (clockApps.length === 0) {\n clockMenu[\"No Clocks Found\"] = () => {};\n }\n return Bangle.menu(clockMenu);\n}\n\n\n\nfunction showSetTimeMenu() {\n d = new Date();\n const timemenu = {\n '': {\n 'title': 'Set Time',\n 'predraw': function() {\n d = new Date();\n timemenu.Hour.value = d.getHours();\n timemenu.Minute.value = d.getMinutes();\n timemenu.Second.value = d.getSeconds();\n timemenu.Date.value = d.getDate();\n timemenu.Month.value = d.getMonth() + 1;\n timemenu.Year.value = d.getFullYear();\n }\n },\n '< Back': showMainMenu,\n 'Hour': {\n value: d.getHours(),\n min: 0,\n max: 23,\n step: 1,\n onchange: v => {\n d = new Date();\n d.setHours(v);\n setTime(d.getTime()/1000);\n }\n },\n 'Minute': {\n value: d.getMinutes(),\n min: 0,\n max: 59,\n step: 1,\n onchange: v => {\n d = new Date();\n d.setMinutes(v);\n setTime(d.getTime()/1000);\n }\n },\n 'Second': {\n value: d.getSeconds(),\n min: 0,\n max: 59,\n step: 1,\n onchange: v => {\n d = new Date();\n d.setSeconds(v);\n setTime(d.getTime()/1000);\n }\n },\n 'Date': {\n value: d.getDate(),\n min: 1,\n max: 31,\n step: 1,\n onchange: v => {\n d = new Date();\n d.setDate(v);\n setTime(d.getTime()/1000);\n }\n },\n 'Month': {\n value: d.getMonth() + 1,\n min: 1,\n max: 12,\n step: 1,\n onchange: v => {\n d = new Date();\n d.setMonth(v - 1);\n setTime(d.getTime()/1000);\n }\n },\n 'Year': {\n value: d.getFullYear(),\n min: 2019,\n max: 2100,\n step: 1,\n onchange: v => {\n d = new Date();\n d.setFullYear(v);\n setTime(d.getTime()/1000);\n }\n }\n };\n return Bangle.menu(timemenu);\n}\n\nshowMainMenu();\n"); +require('Storage').write("=setting","Bangle.HID = E.toUint8Array(atob(\"BQEJBqEBhQIFBxngKecVACUBdQGVCIEClQF1CIEBlQV1AQUIGQEpBZEClQF1A5EBlQZ1CBUAJXMFBxkAKXOBAAkFFQAm/wB1CJUCsQLABQwJAaEBhQEVACUBdQGVAQm1gQIJtoECCbeBAgm4gQIJzYECCeKBAgnpgQIJ6oECwA==\"));\n\n(function() {\n var s = require('Storage').readJSON('setting.json');\n var adv = { uart: true };\n if (s.ble) {\n if (s.dev)\n Bluetooth.setConsole(true);\n else\n Terminal.setConsole(true);\n if (s.HID) {\n adv.hid = Bangle.HID;\n } else\n delete Bangle.HID;\n }\n NRF.setServices({}, adv);\n // we just reset, so BLE should be on\n try { // disable advertising if BLE should be off\n if (!s.ble) NRF.sleep();\n else NRF.wake();\n } catch(e) {}\n if (!s.vibrate) Bangle.buzz=Promise.resolve;\n if (!s.beep) Bangle.beep=Promise.resolve;\n Bangle.setLCDTimeout(s.timeout);\n if (!s.timeout) Bangle.setLCDPower(1);\n E.setTimeZone(s.timezone);\n})()\n"); +require('Storage').write("setting.json",{ ble: true, // Bluetooth enabled by default dev: true, // Espruino IDE enabled by default timeout: 10, // Default LCD timeout in seconds diff --git a/index.html b/index.html index 0aacaf1eba..5ed83382b2 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,7 @@ - Bangle.js loader + Bangle.js App Loader