diff --git a/README.md b/README.md index f79c8d4d4..1f985fa65 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"; +* `app-icon.js` -> `7chname.img` -require("Storage").write('*'+appname, - // place app-icon.js contents here -); +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. -// -require("Storage").write("+"+appname,{ - "name":"My Great App","type":"", - "icon":"*"+appname, - "src":"-"+appname, -}); +Now, clicking the `Send to Espruino` icon will load the app directly into +Espruino **and** will automatically run it. -require("Storage").write("-"+appname,` -// place contents of app.js here -// be aware of double-quoting templated strings -` -``` - -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 7d49647fe..151227f45 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 e1403f0f8..68c101c3e 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 9043b0058..c75f9ed7d 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 65168c5a1..000000000 --- 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 149c6a3dd..3011fe744 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 efc522dee..000000000 --- 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 dd1b7c06f..000000000 --- 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 049d47406..000000000 --- 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 153a6ef3b..c2075607d 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 25b8c6a00..000000000 --- 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 9a8bb01e7..385dd8f2b 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 38e1a4812..f92882e08 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 a2d24941f..000000000 --- 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 7215be590..000000000 --- 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 c00dd9d76..000000000 --- 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 cb5590fa7..434f0f6a9 100644 --- a/apps/beer/beercompass.html +++ b/apps/beer/beercompass.html @@ -196,20 +196,12 @@ Bangle.on('mag', function(m) { 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 7c0d6e411..000000000 --- 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 d9e7f28f1..000000000 --- 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 b548acd80..000000000 --- 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 45ceede6b..000000000 --- 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 8b34c683a..f0ad79a5f 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 fc21ee60c..12559abb1 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 dc568a319..000000000 --- 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 2d445787e..000000000 --- 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 6a2874259..000000000 --- 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 ddbb7d10c..000000000 --- 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 7abc9a733..000000000 --- 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 68fbfdb70..000000000 --- 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 440a78c72..000000000 --- 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 fab184c15..000000000 --- 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 9f3f7b46f..ab8324b43 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 db43a7cdc..000000000 --- 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 2fee14e86..000000000 --- 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 262ed2658..000000000 --- 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 f5c8f3991..000000000 --- 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 48903e978..000000000 --- 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 b86b11d58..000000000 --- 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 7e1c8ee72..000000000 --- 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 3c0da22e2..bac7e92f8 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 aa8416a77..000000000 --- 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 5ca32efde..7e25a92ad 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 813914e08..000000000 --- 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 6c595ff8e..d48d97b47 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 e2059a9c2..000000000 --- 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 01f5090f0..fe850024e 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 11653b803..000000000 --- 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 d4dbd5f45..afee7ade9 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 419ed196e..000000000 --- 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 cf276e2ac..000000000 --- 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 a21a84561..000000000 --- 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 72b86993e..000000000 --- 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 20638a2d6..000000000 --- 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 1b98ba835..e93c2a330 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 20a78cd1d..000000000 --- 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 bf629ac87..000000000 --- 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 b5396287a..000000000 --- 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 1454658dd..000000000 --- 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 bbd142c18..000000000 --- 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 b7c4faa70..000000000 --- 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 6a62f1a66..000000000 --- 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 73665eb7f..000000000 --- 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 000000000..e69de29bb diff --git a/apps/openloc/openlocation.json b/apps/openloc/openlocation.json deleted file mode 100644 index c02a5a233..000000000 --- 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 6d9d5a833..000000000 --- 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 c017048df..000000000 --- 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 abf950e47..000000000 --- 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 bdc34def5..8a0027929 100644 --- a/apps/qrcode/qrcode.html +++ b/apps/qrcode/qrcode.html @@ -41,19 +41,11 @@ g.setColor(0,0,0); 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 f44fb97c5..2417aa232 100644 --- a/apps/route/route.html +++ b/apps/route/route.html @@ -240,20 +240,12 @@ Bangle.setGPSPower(1); 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 14cea82b3..000000000 --- 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 249db6fe4..000000000 --- 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 e298c9d3a..9bedbc2d0 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 66cf827ba..000000000 --- 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 70d28e9d3..000000000 --- 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 69478c9df..568a64047 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 dcadf616a..000000000 --- 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 0a77fd60f..000000000 --- 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 ce1c8b82e..000000000 --- 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 239fffb68..000000000 --- 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 ab4d401f5..000000000 --- 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 e54d4ddb6..000000000 --- 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 594b73f17..000000000 --- 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 5d73e70e5..000000000 --- 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 fdc8f15e4..79a085b14 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 584f9fc40..000000000 --- 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 fbc51b789..000000000 --- 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 18703a2de..000000000 --- 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 f281eaf7b..84a4bb211 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 74c150c6c..0b1aab970 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 2544af001..df508f2e4 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 08f34e99b..a6923ab1c 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 0aacaf1eb..5ed83382b 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,7 @@ - Bangle.js loader + Bangle.js App Loader