Merge remote-tracking branch 'upstream/master'
commit
a2bcc84bea
|
|
@ -0,0 +1,3 @@
|
||||||
|
.htaccess
|
||||||
|
node_modules
|
||||||
|
package-lock.json
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- "node"
|
||||||
110
README.md
110
README.md
|
|
@ -1,6 +1,8 @@
|
||||||
Bangle.js App Loader (and Apps)
|
Bangle.js App Loader (and Apps)
|
||||||
================================
|
================================
|
||||||
|
|
||||||
|
[](https://travis-ci.org/espruino/BangleApps)
|
||||||
|
|
||||||
Try it live at [banglejs.com/apps](https://banglejs.com/apps)
|
Try it live at [banglejs.com/apps](https://banglejs.com/apps)
|
||||||
|
|
||||||
## How does it work?
|
## How does it work?
|
||||||
|
|
@ -17,11 +19,11 @@ listed in `apps.json`, loads them, and sends them over Web Bluetooth.
|
||||||
Filenames in storage are limited to 8 characters. To
|
Filenames in storage are limited to 8 characters. To
|
||||||
easily distinguish between file types, we use the following:
|
easily distinguish between file types, we use the following:
|
||||||
|
|
||||||
* `+stuff` is JSON for an app
|
* `stuff.info` is JSON that describes an app - this is auto-generated by the App Loader
|
||||||
* `*stuff` is an image
|
* `stuff.img` is an image
|
||||||
* `-stuff` is JS code
|
* `stuff.app.js` 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.wid.js` is JS code for widgets
|
||||||
* `@stuff` is used for JSON settings for an app
|
* `stuff.json` is used for JSON settings for an app
|
||||||
|
|
||||||
## Developing your own app
|
## Developing your own app
|
||||||
|
|
||||||
|
|
@ -32,35 +34,25 @@ easily distinguish between file types, we use the following:
|
||||||
|
|
||||||
## Adding your app to the menu
|
## 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/<id>`, lets assume `apps/7chname`
|
* Create a folder called `apps/<id>`, lets assume `apps/7chname`
|
||||||
* We'd recommend that you copy files from 'Example Applications' (below) as a base, or...
|
* We'd recommend that you copy files from 'Example Applications' (below) as a base, or...
|
||||||
* `apps/7chname/app.png` should be a 48px icon
|
* `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"
|
* 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:
|
* Create an entry in `apps.json` as follows:
|
||||||
|
|
||||||
```
|
```
|
||||||
{ "id": "7chname",
|
{ "id": "7chname",
|
||||||
"name": "My app's human readable name",
|
"name": "My app's human readable name",
|
||||||
|
"shortName" : "Short Name",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"description": "A detailed description of my great app",
|
"description": "A detailed description of my great app",
|
||||||
"tags": "",
|
"tags": "",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+7chname","url":"app.json"},
|
{"name":"7chname.app.js","url":"app.js"},
|
||||||
{"name":"-7chname","url":"app.js"},
|
{"name":"7chname.img","url":"app-icon.js","evaluate":true}
|
||||||
{"name":"*7chname","url":"app-icon.js","evaluate":true}
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
@ -77,36 +69,34 @@ This is the best way to test...
|
||||||
* Run your personal `Bangle App Loader` at https://\<your-github-username\>.github.io/BangleApps/index.html to load apps onto your device
|
* Run your personal `Bangle App Loader` at https://\<your-github-username\>.github.io/BangleApps/index.html to load apps onto your device
|
||||||
* Your apps should be inside it - if there are problems, check your web browser's 'developer console' for errors
|
* Your apps should be inside it - if there are problems, check your web browser's 'developer console' for errors
|
||||||
|
|
||||||
|
**Note:** It's a great idea to get a local copy of the repository on your PC,
|
||||||
|
then run `bin/sanitycheck.js` - it'll run through a bunch of common issues
|
||||||
|
that there might be.
|
||||||
|
|
||||||
Be aware of the delay between commits and updates on github.io - it can take a few minutes (and a 'hard refresh' of your browser) for changes to take effect.
|
Be aware of the delay between commits and updates on github.io - it can take a few minutes (and a 'hard refresh' of your browser) for changes to take effect.
|
||||||
|
|
||||||
### Offline
|
### 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:
|
||||||
|
|
||||||
```
|
* `app-icon.js` -> `7chname.img`
|
||||||
// replace with your 7chname app name
|
|
||||||
var appname = "mygreat";
|
|
||||||
|
|
||||||
require("Storage").write('*'+appname,
|
Now load `app.js` up in the editor, and click the down-arrow to the bottom
|
||||||
// place app-icon.js contents here
|
right of the `Send to Espruino` icon. Click `Storage` and then either choose
|
||||||
);
|
`7chname.app.js` (if you'd uploaded your app previously), or `New File`
|
||||||
|
and then enter `7chname.app.js` as the name.
|
||||||
|
|
||||||
//
|
Now, clicking the `Send to Espruino` icon will load the app directly into
|
||||||
require("Storage").write("+"+appname,{
|
Espruino **and** will automatically run it.
|
||||||
"name":"My Great App","type":"",
|
|
||||||
"icon":"*"+appname,
|
|
||||||
"src":"-"+appname,
|
|
||||||
});
|
|
||||||
|
|
||||||
require("Storage").write("-"+appname,`
|
When you upload code this way, your app will even be uploaded to Bangle.js's menu
|
||||||
// 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
|
|
||||||
without you having to use the `Bangle App Loader`
|
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
|
## Example Applications
|
||||||
|
|
||||||
To make the process easier we've come up with some example applications that you can use as a base
|
To make the process easier we've come up with some example applications that you can use as a base
|
||||||
|
|
@ -114,21 +104,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
|
or `apps/_example_widget` to `apps/7chname`, and add `apps/_example_X/add_to_apps.json` to
|
||||||
`apps.json`.
|
`apps.json`.
|
||||||
|
|
||||||
|
**If you're making a widget** please start the name with `wid` to make
|
||||||
|
it easy to find!
|
||||||
|
|
||||||
### App Example
|
### App Example
|
||||||
|
|
||||||
The app example is available in [`apps/_example_app`](apps/_example_app)
|
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.
|
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.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-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.js` - app code
|
||||||
|
|
||||||
#### `app-icon.js`
|
#### `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.
|
Use the Espruino [image converter](https://www.espruino.com/Image+Converter) and upload your `app.png` file.
|
||||||
|
|
||||||
|
|
@ -155,13 +147,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)
|
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
|
* `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
|
* `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
|
This is the file that's **auto-generated** and loaded onto Bangle.js by the App Loader,
|
||||||
about the app.
|
and which gives information about the app for the Launcher.
|
||||||
|
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
|
|
@ -184,9 +175,10 @@ about the app.
|
||||||
```
|
```
|
||||||
{ "id": "appid", // 7 character app id
|
{ "id": "appid", // 7 character app id
|
||||||
"name": "Readable name", // readable name
|
"name": "Readable name", // readable name
|
||||||
|
"shortName": "Short name", // short name for launcher
|
||||||
"icon": "icon.png", // icon in apps/
|
"icon": "icon.png", // icon in apps/
|
||||||
"description": "...", // long description
|
"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
|
"tags": "", // comma separated tag list for searching
|
||||||
|
|
||||||
"custom": "custom.html", // if supplied, apps/custom.html is loaded in an
|
"custom": "custom.html", // if supplied, apps/custom.html is loaded in an
|
||||||
|
|
@ -203,7 +195,7 @@ about the app.
|
||||||
// add an icon to allow your app to be tested
|
// add an icon to allow your app to be tested
|
||||||
|
|
||||||
"storage": [ // list of files to add to storage
|
"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/)
|
"url":"", // URL of file to load (currently relative to apps/)
|
||||||
"content":"..." // if supplied, this content is loaded directly
|
"content":"..." // if supplied, this content is loaded directly
|
||||||
"evaluate":true // if supplied, data isn't quoted into a String before upload
|
"evaluate":true // if supplied, data isn't quoted into a String before upload
|
||||||
|
|
@ -245,13 +237,8 @@ version of what's in `apps.json`:
|
||||||
sendCustomizedApp({
|
sendCustomizedApp({
|
||||||
id : "7chname",
|
id : "7chname",
|
||||||
storage:[
|
storage:[
|
||||||
{name:"-7chname", content:app_source_code},
|
{name:"7chname.app.js", content:app_source_code},
|
||||||
{name:"+7chname", content:JSON.stringify({
|
{name:"7chname.img", content:'require("heatshrink").decompress(atob("mEwg...4"))', evaluate:true},
|
||||||
name:"My app's name",
|
|
||||||
icon:"*7chname",
|
|
||||||
src:"-7chname"
|
|
||||||
})},
|
|
||||||
{name:"*7chname", content:'require("heatshrink").decompress(atob("mEwg...4"))', evaluate:true},
|
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -299,8 +286,6 @@ See [apps/gpsrec/interface.html](the GPS Recorder) for a full example.
|
||||||
|
|
||||||
## Coding hints
|
## 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.
|
|
||||||
|
|
||||||
- use `g.setFont(.., size)` to multiply the font size, eg ("6x8",3) : "18x24"
|
- use `g.setFont(.., size)` to multiply the font size, eg ("6x8",3) : "18x24"
|
||||||
|
|
||||||
- use `g.drawString(text,x,y,true)` to draw with background color to overwrite existing text
|
- use `g.drawString(text,x,y,true)` to draw with background color to overwrite existing text
|
||||||
|
|
@ -315,6 +300,13 @@ See [apps/gpsrec/interface.html](the GPS Recorder) for a full example.
|
||||||
|
|
||||||
- chaining graphics methods, eg `g.setColor(0xFD20).setFontAlign(0,0).setfont("6x8",3)`
|
- chaining graphics methods, eg `g.setColor(0xFD20).setFontAlign(0,0).setfont("6x8",3)`
|
||||||
|
|
||||||
|
### Misc Notes
|
||||||
|
|
||||||
|
- Need to save state? Use the `E.on('kill',...)` event to save JSON to a file called `7chname.json`, then load it at startup.
|
||||||
|
|
||||||
|
- 'Welcome' apps define a file called `welcome.js` which the booloader picks up. This then chain-loads the welcome app itself.
|
||||||
|
|
||||||
|
|
||||||
### Graphic areas
|
### Graphic areas
|
||||||
|
|
||||||
The screen is parted in a widget and app area for lcd mode `direct`(default).
|
The screen is parted in a widget and app area for lcd mode `direct`(default).
|
||||||
|
|
|
||||||
46
appinfo.js
46
appinfo.js
|
|
@ -20,21 +20,12 @@ var AppInfo = {
|
||||||
})).then(fileContents => { // now we just have a list of files + contents...
|
})).then(fileContents => { // now we just have a list of files + contents...
|
||||||
// filter out empty files
|
// filter out empty files
|
||||||
fileContents = fileContents.filter(x=>x!==undefined);
|
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
|
// then map each file to a command to load into storage
|
||||||
fileContents.forEach(storageFile => {
|
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
|
// format ready for Espruino
|
||||||
var js;
|
var js;
|
||||||
if (storageFile.evaluate) {
|
if (storageFile.evaluate) {
|
||||||
|
|
@ -49,6 +40,35 @@ var AppInfo = {
|
||||||
}).catch(err => reject(err));
|
}).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)
|
if ("undefined"!=typeof module)
|
||||||
|
|
|
||||||
396
apps.json
396
apps.json
|
|
@ -2,25 +2,26 @@
|
||||||
{ "id": "boot",
|
{ "id": "boot",
|
||||||
"name": "Bootloader",
|
"name": "Bootloader",
|
||||||
"icon": "bootloader.png",
|
"icon": "bootloader.png",
|
||||||
"version":"0.05",
|
"version":"0.07",
|
||||||
"description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings",
|
"description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings",
|
||||||
"tags": "tool,system",
|
"tags": "tool,system",
|
||||||
|
"type":"bootloader",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":".boot0","url":"boot0.js"},
|
{"name":".boot0","url":"boot0.js"},
|
||||||
{"name":".bootcde","url":"bootloader.js"},
|
{"name":".bootcde","url":"bootloader.js"}
|
||||||
{"name":"+boot","url":"bootloader.json"}
|
|
||||||
],
|
],
|
||||||
"sortorder" : -10
|
"sortorder" : -10
|
||||||
},
|
},
|
||||||
{ "id": "launch",
|
{ "id": "launch",
|
||||||
"name": "Default Launcher",
|
"name": "Default Launcher",
|
||||||
|
"shortName":"Launcher",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.01",
|
"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.",
|
"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",
|
"tags": "tool,system,launcher",
|
||||||
|
"type":"launch",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+launch","url":"app.json"},
|
{"name":"launch.app.js","url":"app.js"}
|
||||||
{"name":"-launch","url":"app.js"}
|
|
||||||
],
|
],
|
||||||
"sortorder" : -10
|
"sortorder" : -10
|
||||||
},
|
},
|
||||||
|
|
@ -32,22 +33,21 @@
|
||||||
"tags": "tool,system",
|
"tags": "tool,system",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+about","url":"app.json"},
|
{"name":"about.app.js","url":"app.js"},
|
||||||
{"name":"-about","url":"app.js"},
|
{"name":"about.img","url":"app-icon.js","evaluate":true}
|
||||||
{"name":"*about","url":"app-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "welcome",
|
{ "id": "welcome",
|
||||||
"name": "Welcome",
|
"name": "Welcome",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"description": "Appears at first boot and explains how to use Bangle.js",
|
"description": "Appears at first boot and explains how to use Bangle.js",
|
||||||
"tags": "welcome",
|
"tags": "start,welcome",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+welcome","url":"app.json"},
|
{"name":"welcome.js","url":"welcome.js"},
|
||||||
{"name":"-welcome","url":"app.js"},
|
{"name":"welcome.app.js","url":"app.js"},
|
||||||
{"name":"*welcome","url":"app-icon.js","evaluate":true}
|
{"name":"welcome.img","url":"app-icon.js","evaluate":true}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "gbridge",
|
{ "id": "gbridge",
|
||||||
|
|
@ -57,10 +57,9 @@
|
||||||
"description": "The default notification handler for Gadgetbridge notifications from Android",
|
"description": "The default notification handler for Gadgetbridge notifications from Android",
|
||||||
"tags": "tool,system,android,widget",
|
"tags": "tool,system,android,widget",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+gbridge","url":"app.json"},
|
{"name":"gbridge.app.js","url":"app.js"},
|
||||||
{"name":"-gbridge","url":"app.js"},
|
{"name":"gbridge.img","url":"app-icon.js","evaluate":true},
|
||||||
{"name":"*gbridge","url":"app-icon.js","evaluate":true},
|
{"name":"gbridge.wid.js","url":"widget.js"}
|
||||||
{"name":"=gbridge","url":"widget.js"}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "mclock",
|
{ "id": "mclock",
|
||||||
|
|
@ -72,38 +71,37 @@
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+mclock","url":"clock-morphing.json"},
|
{"name":"mclock.app.js","url":"clock-morphing.js"},
|
||||||
{"name":"-mclock","url":"clock-morphing.js"},
|
{"name":"mclock.img","url":"clock-morphing-icon.js","evaluate":true}
|
||||||
{"name":"*mclock","url":"clock-morphing-icon.js","evaluate":true}
|
|
||||||
],
|
],
|
||||||
"sortorder" : -9
|
"sortorder" : -9
|
||||||
},
|
},
|
||||||
{ "id": "setting",
|
{ "id": "setting",
|
||||||
"name": "Settings",
|
"name": "Settings",
|
||||||
"icon": "settings.png",
|
"icon": "settings.png",
|
||||||
"version":"0.03",
|
"version":"0.05",
|
||||||
"description": "A menu for setting up Bangle.js",
|
"description": "A menu for setting up Bangle.js",
|
||||||
"tags": "tool,system",
|
"tags": "tool,system",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+setting","url":"settings.json"},
|
{"name":"setting.app.js","url":"settings.js"},
|
||||||
{"name":"-setting","url":"settings.js"},
|
{"name":"setting.json","url":"settings-default.json","evaluate":true},
|
||||||
{"name":"@setting","url":"settings-default.json","evaluate":true},
|
{"name":"setting.img","url":"settings-icon.js","evaluate":true}
|
||||||
{"name":"*setting","url":"settings-icon.js","evaluate":true}
|
|
||||||
],
|
],
|
||||||
"sortorder" : -2
|
"sortorder" : -2
|
||||||
},
|
},
|
||||||
{ "id": "alarm",
|
{ "id": "alarm",
|
||||||
"name": "Default Alarm",
|
"name": "Default Alarm",
|
||||||
|
"shortName":"Alarms",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.01",
|
"version":"0.02",
|
||||||
"description": "Set and respond to alarms",
|
"description": "Set and respond to alarms",
|
||||||
"tags": "tool,alarm,widget",
|
"tags": "tool,alarm,widget",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+alarm","url":"app.json"},
|
{"name":"alarm.app.js","url":"app.js"},
|
||||||
{"name":"-alarm","url":"app.js"},
|
{"name":"alarm.js","url":"alarm.js"},
|
||||||
{"name":"@alarm","content":"[]"},
|
{"name":"alarm.json","content":"[]"},
|
||||||
{"name":"*alarm","url":"app-icon.js","evaluate":true},
|
{"name":"alarm.img","url":"app-icon.js","evaluate":true},
|
||||||
{"name":"=alarm","url":"widget.js"}
|
{"name":"alarm.wid.js","url":"widget.js"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "wclock",
|
{ "id": "wclock",
|
||||||
|
|
@ -115,9 +113,8 @@
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+wclock","url":"clock-word.json"},
|
{"name":"wclock.app.js","url":"clock-word.js"},
|
||||||
{"name":"-wclock","url":"clock-word.js"},
|
{"name":"wclock.img","url":"clock-word-icon.js","evaluate":true}
|
||||||
{"name":"*wclock","url":"clock-word-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "aclock",
|
{ "id": "aclock",
|
||||||
|
|
@ -129,9 +126,8 @@
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+aclock","url":"clock-analog.json"},
|
{"name":"aclock.app.js","url":"clock-analog.js"},
|
||||||
{"name":"-aclock","url":"clock-analog.js"},
|
{"name":"aclock.img","url":"clock-analog-icon.js","evaluate":true}
|
||||||
{"name":"*aclock","url":"clock-analog-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "clck3x2",
|
{ "id": "clck3x2",
|
||||||
|
|
@ -142,9 +138,8 @@
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+clck3x2","url":"clock3x2.json"},
|
{"name":"clck3x2.app.js","url":"clock3x2.js"},
|
||||||
{"name":"-clck3x2","url":"clock3x2.js"},
|
{"name":"clck3x2.img","url":"clock3x2-icon.js","evaluate":true}
|
||||||
{"name":"*clck3x2","url":"clock3x2-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "trex",
|
{ "id": "trex",
|
||||||
|
|
@ -155,9 +150,8 @@
|
||||||
"tags": "game",
|
"tags": "game",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+trex","url":"trex.json"},
|
{"name":"trex.app.js","url":"trex.js"},
|
||||||
{"name":"-trex","url":"trex.js"},
|
{"name":"trex.img","url":"trex-icon.js","evaluate":true}
|
||||||
{"name":"*trex","url":"trex-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "astroid",
|
{ "id": "astroid",
|
||||||
|
|
@ -168,9 +162,8 @@
|
||||||
"tags": "game",
|
"tags": "game",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+astroid","url":"asteroids.json"},
|
{"name":"astroid.app.js","url":"asteroids.js"},
|
||||||
{"name":"-astroid","url":"asteroids.js"},
|
{"name":"astroid.img","url":"asteroids-icon.js","evaluate":true}
|
||||||
{"name":"*astroid","url":"asteroids-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "clickms",
|
{ "id": "clickms",
|
||||||
|
|
@ -180,9 +173,8 @@
|
||||||
"description": "Get several friends to start the game, then compete to see who can press BTN1 the most!",
|
"description": "Get several friends to start the game, then compete to see who can press BTN1 the most!",
|
||||||
"tags": "game",
|
"tags": "game",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+clickms","url":"click-master.json"},
|
{"name":"clickms.app.js","url":"click-master.js"},
|
||||||
{"name":"-clickms","url":"click-master.js"},
|
{"name":"clickms.img","url":"click-master-icon.js","evaluate":true}
|
||||||
{"name":"*clickms","url":"click-master-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "horsey",
|
{ "id": "horsey",
|
||||||
|
|
@ -192,9 +184,8 @@
|
||||||
"description": "Get several friends to start the game, then compete to see who can press BTN1 the most!",
|
"description": "Get several friends to start the game, then compete to see who can press BTN1 the most!",
|
||||||
"tags": "game",
|
"tags": "game",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+horsey","url":"horse-race.json"},
|
{"name":"horsey.app.js","url":"horse-race.js"},
|
||||||
{"name":"-horsey","url":"horse-race.js"},
|
{"name":"horsey.img","url":"horse-race-icon.js","evaluate":true}
|
||||||
{"name":"*horsey","url":"horse-race-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "compass",
|
{ "id": "compass",
|
||||||
|
|
@ -204,32 +195,31 @@
|
||||||
"description": "Simple compass that points North",
|
"description": "Simple compass that points North",
|
||||||
"tags": "tool,outdoors",
|
"tags": "tool,outdoors",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+compass","url":"compass.json"},
|
{"name":"compass.app.js","url":"compass.js"},
|
||||||
{"name":"-compass","url":"compass.js"},
|
{"name":"compass.img","url":"compass-icon.js","evaluate":true}
|
||||||
{"name":"*compass","url":"compass-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "gpstime",
|
{ "id": "gpstime",
|
||||||
"name": "GPS Time",
|
"name": "GPS Time",
|
||||||
"icon": "gpstime.png",
|
"icon": "gpstime.png",
|
||||||
"version":"0.02",
|
"version":"0.03",
|
||||||
"description": "Update the Bangle.js's clock based on the time from the GPS receiver",
|
"description": "Update the Bangle.js's clock based on the time from the GPS receiver",
|
||||||
"tags": "tool,gps",
|
"tags": "tool,gps",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+gpstime","url":"gpstime.json"},
|
{"name":"gpstime.app.js","url":"gpstime.js"},
|
||||||
{"name":"-gpstime","url":"gpstime.js"},
|
{"name":"gpstime.img","url":"gpstime-icon.js","evaluate":true}
|
||||||
{"name":"*gpstime","url":"gpstime-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "openloc",
|
{ "id": "openloc",
|
||||||
"name": "Open Location / Plus Codes",
|
"name": "Open Location / Plus Codes",
|
||||||
"icon": "openlocation.png",
|
"shortName": "Open Location",
|
||||||
|
"icon": "app.png",
|
||||||
"version":"0.01",
|
"version":"0.01",
|
||||||
"description": "Convert your current GPS location to a series of characters",
|
"description": "Convert your current GPS location to a series of characters",
|
||||||
"tags": "tool,outdoors,gps",
|
"tags": "tool,outdoors,gps",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+openloc","url":"openlocation.json"},
|
{"name":"openloc.app.js","url":"app.js"},
|
||||||
{"name":"-openloc","url":"openlocation.js","evaluate":true}
|
{"name":"openloc.img","url":"app-icon.js","evaluate":true}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "speedo",
|
{ "id": "speedo",
|
||||||
|
|
@ -239,24 +229,22 @@
|
||||||
"description": "Show the current speed according to the GPS",
|
"description": "Show the current speed according to the GPS",
|
||||||
"tags": "tool,outdoors,gps",
|
"tags": "tool,outdoors,gps",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+speedo","url":"speedo.json"},
|
{"name":"speedo.app.js","url":"speedo.js"},
|
||||||
{"name":"-speedo","url":"speedo.js"},
|
{"name":"speedo.img","url":"speedo-icon.js","evaluate":true}
|
||||||
{"name":"*speedo","url":"speedo-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "gpsrec",
|
{ "id": "gpsrec",
|
||||||
"name": "GPS Recorder",
|
"name": "GPS Recorder",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.01",
|
"version":"0.04",
|
||||||
"interface": "interface.html",
|
"interface": "interface.html",
|
||||||
"description": "Application that allows you to record a GPS track. Can run in background",
|
"description": "Application that allows you to record a GPS track. Can run in background",
|
||||||
"tags": "tool,outdoors,gps,widget",
|
"tags": "tool,outdoors,gps,widget",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+gpsrec","url":"app.json"},
|
{"name":"gpsrec.app.js","url":"app.js"},
|
||||||
{"name":"-gpsrec","url":"app.js"},
|
{"name":"gpsrec.json","url":"app-settings.json","evaluate":true},
|
||||||
{"name":"@gpsrec","url":"app-settings.json","evaluate":true},
|
{"name":"gpsrec.img","url":"app-icon.js","evaluate":true},
|
||||||
{"name":"*gpsrec","url":"app-icon.js","evaluate":true},
|
{"name":"gpsrec.wid.js","url":"widget.js"}
|
||||||
{"name":"=gpsrec","url":"widget.js"}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "slevel",
|
{ "id": "slevel",
|
||||||
|
|
@ -266,9 +254,8 @@
|
||||||
"description": "Show the current angle of the watch, so you can use it to make sure something is absolutely flat",
|
"description": "Show the current angle of the watch, so you can use it to make sure something is absolutely flat",
|
||||||
"tags": "tool",
|
"tags": "tool",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+slevel","url":"spiritlevel.json"},
|
{"name":"slevel.app.js","url":"spiritlevel.js"},
|
||||||
{"name":"-slevel","url":"spiritlevel.js"},
|
{"name":"slevel.img","url":"spiritlevel-icon.js","evaluate":true}
|
||||||
{"name":"*slevel","url":"spiritlevel-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "files",
|
{ "id": "files",
|
||||||
|
|
@ -278,33 +265,30 @@
|
||||||
"description": "Show currently installed apps, free space, and allow their deletion from the watch",
|
"description": "Show currently installed apps, free space, and allow their deletion from the watch",
|
||||||
"tags": "tool,system",
|
"tags": "tool,system",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+files","url":"files.json"},
|
{"name":"files.app.js","url":"files.js"},
|
||||||
{"name":"-files","url":"files.js"},
|
{"name":"files.img","url":"files-icon.js","evaluate":true}
|
||||||
{"name":"*files","url":"files-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "sbat",
|
{ "id": "widbat",
|
||||||
"name": "Battery Level Widget",
|
"name": "Battery Level Widget",
|
||||||
"icon": "widget-battery.png",
|
"icon": "widget.png",
|
||||||
"version":"0.02",
|
"version":"0.02",
|
||||||
"description": "Show the current battery level and charging status in the top right of the clock",
|
"description": "Show the current battery level and charging status in the top right of the clock",
|
||||||
"tags": "widget,battery",
|
"tags": "widget,battery",
|
||||||
"type":"widget",
|
"type":"widget",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+sbat","url":"widget-battery.json"},
|
{"name":"widbat.wid.js","url":"widget.js"}
|
||||||
{"name":"=sbat","url":"widget-battery.js"}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "sbt",
|
{ "id": "widbt",
|
||||||
"name": "Bluetooth Widget",
|
"name": "Bluetooth Widget",
|
||||||
"icon": "widget-bluetooth.png",
|
"icon": "widget.png",
|
||||||
"version":"0.01",
|
"version":"0.01",
|
||||||
"description": "Show the current Bluetooth connection status in the top right of the clock",
|
"description": "Show the current Bluetooth connection status in the top right of the clock",
|
||||||
"tags": "widget,bluetooth",
|
"tags": "widget,bluetooth",
|
||||||
"type":"widget",
|
"type":"widget",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+sbt","url":"widget-bluetooth.json"},
|
{"name":"widbt.wid.js","url":"widget.js"}
|
||||||
{"name":"=sbt","url":"widget-bluetooth.js"}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "hrm",
|
{ "id": "hrm",
|
||||||
|
|
@ -314,20 +298,19 @@
|
||||||
"description": "Measure your current heart rate",
|
"description": "Measure your current heart rate",
|
||||||
"tags": "health",
|
"tags": "health",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+hrm","url":"heartrate.json"},
|
{"name":"hrm.app.js","url":"heartrate.js"},
|
||||||
{"name":"-hrm","url":"heartrate.js"},
|
{"name":"hrm.img","url":"heartrate-icon.js","evaluate":true}
|
||||||
{"name":"*hrm","url":"heartrate-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "whrm",
|
{ "id": "widhrm",
|
||||||
"name": "Simple Heart Rate widget",
|
"name": "Simple Heart Rate widget",
|
||||||
"icon": "widget.png",
|
"icon": "widget.png",
|
||||||
"version":"0.01",
|
"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.",
|
"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",
|
"tags": "health,widget",
|
||||||
|
"type": "widget",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+whrm","url":"widget.json"},
|
{"name":"widhrm.wid.js","url":"widget.js"}
|
||||||
{"name":"=whrm","url":"widget.js"}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "stetho",
|
{ "id": "stetho",
|
||||||
|
|
@ -337,9 +320,8 @@
|
||||||
"description": "Hear your heart rate",
|
"description": "Hear your heart rate",
|
||||||
"tags": "health",
|
"tags": "health",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+stetho","url":"stetho.json"},
|
{"name":"stetho.app.js","url":"stetho.js"},
|
||||||
{"name":"-stetho","url":"stetho.js"},
|
{"name":"stetho.img","url":"stetho-icon.js","evaluate":true}
|
||||||
{"name":"*stetho","url":"stetho-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "swatch",
|
{ "id": "swatch",
|
||||||
|
|
@ -350,45 +332,44 @@
|
||||||
"tags": "health",
|
"tags": "health",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+swatch","url":"stopwatch.json"},
|
{"name":"swatch.app.js","url":"stopwatch.js"},
|
||||||
{"name":"-swatch","url":"stopwatch.js"},
|
{"name":"swatch.img","url":"stopwatch-icon.js","evaluate":true}
|
||||||
{"name":"*swatch","url":"stopwatch-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "hidmsic",
|
{ "id": "hidmsic",
|
||||||
"name": "Bluetooth Music Controls",
|
"name": "Bluetooth Music Controls",
|
||||||
|
"shortName": "Music Control",
|
||||||
"icon": "hid-music.png",
|
"icon": "hid-music.png",
|
||||||
"version":"0.01",
|
"version":"0.01",
|
||||||
"description": "Enable HID in settings, pair with your phone, then use this app to control music from your watch!",
|
"description": "Enable HID in settings, pair with your phone, then use this app to control music from your watch!",
|
||||||
"tags": "bluetooth",
|
"tags": "bluetooth",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+hidmsic","url":"hid-music.json"},
|
{"name":"hidmsic.app.js","url":"hid-music.js"},
|
||||||
{"name":"-hidmsic","url":"hid-music.js"},
|
{"name":"hidmsic.img","url":"hid-music-icon.js","evaluate":true}
|
||||||
{"name":"*hidmsic","url":"hid-music-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "hidkbd",
|
{ "id": "hidkbd",
|
||||||
"name": "Bluetooth Keyboard",
|
"name": "Bluetooth Keyboard",
|
||||||
|
"shortName": "Bluetooth Kbd",
|
||||||
"icon": "hid-keyboard.png",
|
"icon": "hid-keyboard.png",
|
||||||
"version":"0.01",
|
"version":"0.01",
|
||||||
"description": "Enable HID in settings, pair with your phone/PC, then use this app to control other apps",
|
"description": "Enable HID in settings, pair with your phone/PC, then use this app to control other apps",
|
||||||
"tags": "bluetooth",
|
"tags": "bluetooth",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+hidkbd","url":"hid-keyboard.json"},
|
{"name":"hidkbd.app.js","url":"hid-keyboard.js"},
|
||||||
{"name":"-hidkbd","url":"hid-keyboard.js"},
|
{"name":"hidkbd.img","url":"hid-keyboard-icon.js","evaluate":true}
|
||||||
{"name":"*hidkbd","url":"hid-keyboard-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "hidbkbd",
|
{ "id": "hidbkbd",
|
||||||
"name": "Binary Bluetooth Keyboard",
|
"name": "Binary Bluetooth Keyboard",
|
||||||
|
"shortName": "Binary BT Kbd",
|
||||||
"icon": "hid-binary-keyboard.png",
|
"icon": "hid-binary-keyboard.png",
|
||||||
"version":"0.01",
|
"version":"0.01",
|
||||||
"description": "Enable HID in settings, pair with your phone/PC, then type messages using the onscreen keyboard by tapping repeatedly on the key you want",
|
"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",
|
"tags": "bluetooth",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+hidbkbd","url":"hid-binary-keyboard.json"},
|
{"name":"hidbkbd.app.js","url":"hid-binary-keyboard.js"},
|
||||||
{"name":"-hidbkbd","url":"hid-binary-keyboard.js"},
|
{"name":"hidbkbd.img","url":"hid-binary-keyboard-icon.js","evaluate":true}
|
||||||
{"name":"*hidbkbd","url":"hid-binary-keyboard-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "animals",
|
{ "id": "animals",
|
||||||
|
|
@ -398,17 +379,16 @@
|
||||||
"description": "Simple toddler's game - displays a different number of animals each time the screen is pressed",
|
"description": "Simple toddler's game - displays a different number of animals each time the screen is pressed",
|
||||||
"tags": "game",
|
"tags": "game",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+animals","url":"animals.json"},
|
{"name":"animals.app.js","url":"animals.js"},
|
||||||
{"name":"-animals","url":"animals.js"},
|
{"name":"animals.img","url":"animals-icon.js","evaluate":true},
|
||||||
{"name":"*animals","url":"animals-icon.js","evaluate":true},
|
{"name":"animals-snake.img","url":"animals-snake.js","evaluate":true},
|
||||||
{"name":"*snake","url":"animals-snake.js","evaluate":true},
|
{"name":"animals-duck.img","url":"animals-duck.js","evaluate":true},
|
||||||
{"name":"*duck","url":"animals-duck.js","evaluate":true},
|
{"name":"animals-swan.img","url":"animals-swan.js","evaluate":true},
|
||||||
{"name":"*swan","url":"animals-swan.js","evaluate":true},
|
{"name":"animals-fox.img","url":"animals-fox.js","evaluate":true},
|
||||||
{"name":"*fox","url":"animals-fox.js","evaluate":true},
|
{"name":"animals-camel.img","url":"animals-camel.js","evaluate":true},
|
||||||
{"name":"*camel","url":"animals-camel.js","evaluate":true},
|
{"name":"animals-pig.img","url":"animals-pig.js","evaluate":true},
|
||||||
{"name":"*pig","url":"animals-pig.js","evaluate":true},
|
{"name":"animals-sheep.img","url":"animals-sheep.js","evaluate":true},
|
||||||
{"name":"*sheep","url":"animals-sheep.js","evaluate":true},
|
{"name":"animals-mouse.img","url":"animals-mouse.js","evaluate":true}
|
||||||
{"name":"*mouse","url":"animals-mouse.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "qrcode",
|
{ "id": "qrcode",
|
||||||
|
|
@ -419,9 +399,8 @@
|
||||||
"tags": "",
|
"tags": "",
|
||||||
"custom": "qrcode.html",
|
"custom": "qrcode.html",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"-qrcode"},
|
{"name":"qrcode.app.js"},
|
||||||
{"name":"+qrcode"},
|
{"name":"qrcode.img"}
|
||||||
{"name":"=qrcode"}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "beer",
|
{ "id": "beer",
|
||||||
|
|
@ -432,9 +411,8 @@
|
||||||
"tags": "",
|
"tags": "",
|
||||||
"custom": "beercompass.html",
|
"custom": "beercompass.html",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"-beer"},
|
{"name":"beer.app.js"},
|
||||||
{"name":"+beer"},
|
{"name":"beer.img"}
|
||||||
{"name":"=beer"}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "route",
|
{ "id": "route",
|
||||||
|
|
@ -445,30 +423,26 @@
|
||||||
"tags": "",
|
"tags": "",
|
||||||
"custom": "route.html",
|
"custom": "route.html",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"-route"},
|
{"name":"route.app.js"},
|
||||||
{"name":"+route"},
|
{"name":"route.img"}
|
||||||
{"name":"=route"}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
"id": "ncstart",
|
"id": "ncstart",
|
||||||
"name": "NCEU Startup",
|
"name": "NCEU Startup",
|
||||||
"icon": "start.png",
|
"icon": "start.png",
|
||||||
"version":"0.02",
|
"version":"0.02",
|
||||||
"description": "NodeConfEU 2019 'First Start' Sequence",
|
"description": "NodeConfEU 2019 'First Start' Sequence",
|
||||||
"tags": "start",
|
"tags": "start,welcome",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+ncstart","url":"start.json"},
|
{"name":"welcome.js","url":"welcome.js"},
|
||||||
{"name":".boot3","url":"start.js"},
|
{"name":"ncstart.app.js","url":"start.js"},
|
||||||
{"name":"*ncstart","url":"start-icon.js","evaluate":true},
|
{"name":"ncstart.img","url":"start-icon.js","evaluate":true},
|
||||||
{"name":"*bangle","url":"start-bangle.js","evaluate":true},
|
{"name":"nc-bangle.img","url":"start-bangle.js","evaluate":true},
|
||||||
{"name":"*nceu","url":"start-nceu.js","evaluate":true},
|
{"name":"nc-nceu.img","url":"start-nceu.js","evaluate":true},
|
||||||
{"name":"*nfr","url":"start-nfr.js","evaluate":true},
|
{"name":"nc-nfr.img","url":"start-nfr.js","evaluate":true},
|
||||||
{"name":"*nodew","url":"start-nodew.js","evaluate":true},
|
{"name":"nc-nodew.img","url":"start-nodew.js","evaluate":true},
|
||||||
{"name":"*tf","url":"start-tf.js","evaluate":true}
|
{"name":"nc-tf.img","url":"start-tf.js","evaluate":true}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "ncfrun",
|
{ "id": "ncfrun",
|
||||||
|
|
@ -478,21 +452,19 @@
|
||||||
"description": "Display a map of the NodeConf EU 2019 5K Fun Run route and your location on it",
|
"description": "Display a map of the NodeConf EU 2019 5K Fun Run route and your location on it",
|
||||||
"tags": "health",
|
"tags": "health",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+ncfrun","url":"nceu-funrun.json"},
|
{"name":"ncfrun.app.js","url":"nceu-funrun.js"},
|
||||||
{"name":"-ncfrun","url":"nceu-funrun.js"},
|
{"name":"ncfrun.img","url":"nceu-funrun-icon.js","evaluate":true}
|
||||||
{"name":"*ncfrun","url":"nceu-funrun-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "nceuwid",
|
{ "id": "widnceu",
|
||||||
"name": "NCEU Logo Widget",
|
"name": "NCEU Logo Widget",
|
||||||
"icon": "nceu-widget.png",
|
"icon": "widget.png",
|
||||||
"version":"0.01",
|
"version":"0.01",
|
||||||
"description": "Show the NodeConf EU logo in the top left",
|
"description": "Show the NodeConf EU logo in the top left",
|
||||||
"tags": "widget",
|
"tags": "widget",
|
||||||
"type":"widget",
|
"type":"widget",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+nceuwid","url":"nceu-widget.json"},
|
{"name":"widnceu.wid.js","url":"widget.js"}
|
||||||
{"name":"=nceuwid","url":"nceu-widget.js"}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -507,9 +479,8 @@
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+sclock","url":"clock-simple.json"},
|
{"name":"sclock.app.js","url":"clock-simple.js"},
|
||||||
{"name":"-sclock","url":"clock-simple.js"},
|
{"name":"sclock.img","url":"clock-simple-icon.js","evaluate":true}
|
||||||
{"name":"*sclock","url":"clock-simple-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "gesture",
|
{ "id": "gesture",
|
||||||
|
|
@ -520,11 +491,10 @@
|
||||||
"tags": "gesture,ai",
|
"tags": "gesture,ai",
|
||||||
"type":"app",
|
"type":"app",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+gesture","url":"gesture.json"},
|
{"name":"gesture.app.js","url":"gesture.js"},
|
||||||
{"name":"-gesture","url":"gesture.js"},
|
|
||||||
{"name":".tfnames","url":"gesture-tfnames.js","evaluate":true},
|
{"name":".tfnames","url":"gesture-tfnames.js","evaluate":true},
|
||||||
{"name":".tfmodel","url":"gesture-tfmodel.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",
|
{ "id": "pparrot",
|
||||||
|
|
@ -536,9 +506,8 @@
|
||||||
"type":"app",
|
"type":"app",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+pparrot","url":"party-parrot.json"},
|
{"name":"pparrot.app.js","url":"party-parrot.js"},
|
||||||
{"name":"-pparrot","url":"party-parrot.js"},
|
{"name":"pparrot.img","url":"party-parrot-icon.js","evaluate":true}
|
||||||
{"name":"*pparrot","url":"party-parrot-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "hrings",
|
{ "id": "hrings",
|
||||||
|
|
@ -550,9 +519,8 @@
|
||||||
"type":"app",
|
"type":"app",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+hrings","url":"hypno-rings.json"},
|
{"name":"hrings.app.js","url":"hypno-rings.js"},
|
||||||
{"name":"-hrings","url":"hypno-rings.js"},
|
{"name":"hrings.img","url":"hypno-rings-icon.js","evaluate":true}
|
||||||
{"name":"*hrings","url":"hypno-rings-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "morse",
|
{ "id": "morse",
|
||||||
|
|
@ -563,9 +531,8 @@
|
||||||
"tags": "morse,sound,visual,input",
|
"tags": "morse,sound,visual,input",
|
||||||
"type":"app",
|
"type":"app",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+morse","url":"morse-code.json"},
|
{"name":"morse.app.js","url":"morse-code.js"},
|
||||||
{"name":"-morse","url":"morse-code.js"},
|
{"name":"morse.img","url":"morse-code-icon.js","evaluate":true}
|
||||||
{"name":"*morse","url":"morse-code-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -576,9 +543,8 @@
|
||||||
"description": "Scan for advertising BLE devices",
|
"description": "Scan for advertising BLE devices",
|
||||||
"tags" : "bluetooth",
|
"tags" : "bluetooth",
|
||||||
"storage" : [
|
"storage" : [
|
||||||
{"name":"+blescan","url":"blescan.json"},
|
{"name":"blescan.app.js","url":"blescan.js"},
|
||||||
{"name":"-blescan","url":"blescan.js"},
|
{"name":"blescan.img","url":"blescan-icon.js", "evaluate":true}
|
||||||
{"name":"*blescan","url":"blescan-icon.js", "evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "mmonday",
|
{ "id": "mmonday",
|
||||||
|
|
@ -588,9 +554,8 @@
|
||||||
"description": "The Bangles make a comeback",
|
"description": "The Bangles make a comeback",
|
||||||
"tags": "sound",
|
"tags": "sound",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+mmonday","url":"manic-monday.json"},
|
{"name":"mmonday.app.js","url":"manic-monday.js"},
|
||||||
{"name":"-mmonday","url":"manic-monday.js"},
|
{"name":"mmonday.img","url":"manic-monday-icon.js","evaluate":true}
|
||||||
{"name":"*mmonday","url":"manic-monday-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "jbells",
|
{ "id": "jbells",
|
||||||
|
|
@ -601,9 +566,8 @@
|
||||||
"tags": "sound",
|
"tags": "sound",
|
||||||
"type":"app",
|
"type":"app",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+jbells","url":"jbells.json"},
|
{"name":"jbells.app.js","url":"jbells.js"},
|
||||||
{"name":"-jbells","url":"jbells.js"},
|
{"name":"jbells.img","url":"jbells-icon.js","evaluate":true}
|
||||||
{"name":"*jbells","url":"jbells-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "scolor",
|
{ "id": "scolor",
|
||||||
|
|
@ -615,9 +579,8 @@
|
||||||
"type":"app",
|
"type":"app",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+scolor","url":"show-color.json"},
|
{"name":"scolor.app.js","url":"show-color.js"},
|
||||||
{"name":"-scolor","url":"show-color.js"},
|
{"name":"scolor.img","url":"show-color-icon.js","evaluate":true}
|
||||||
{"name":"*scolor","url":"show-color-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "miclock",
|
{ "id": "miclock",
|
||||||
|
|
@ -629,9 +592,8 @@
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+miclock","url":"clock-mixed.json"},
|
{"name":"miclock.app.js","url":"clock-mixed.js"},
|
||||||
{"name":"-miclock","url":"clock-mixed.js"},
|
{"name":"miclock.img","url":"clock-mixed-icon.js","evaluate":true}
|
||||||
{"name":"*miclock","url":"clock-mixed-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "bclock",
|
{ "id": "bclock",
|
||||||
|
|
@ -643,9 +605,8 @@
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+bclock","url":"clock-binary.json"},
|
{"name":"bclock.app.js","url":"clock-binary.js"},
|
||||||
{"name":"-bclock","url":"clock-binary.js"},
|
{"name":"bclock.img","url":"clock-binary-icon.js","evaluate":true}
|
||||||
{"name":"*bclock","url":"clock-binary-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "clotris",
|
{ "id": "clotris",
|
||||||
|
|
@ -656,9 +617,8 @@
|
||||||
"tags": "game",
|
"tags": "game",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+clotris","url":"clock-tris.json"},
|
{"name":"clotris.app.js","url":"clock-tris.js"},
|
||||||
{"name":"-clotris","url":"clock-tris.js"},
|
{"name":"clotris.img","url":"clock-tris-icon.js","evaluate":true},
|
||||||
{"name":"*clotris","url":"clock-tris-icon.js","evaluate":true},
|
|
||||||
{"name":".trishig","url":"clock-tris-high"}
|
{"name":".trishig","url":"clock-tris-high"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -670,9 +630,8 @@
|
||||||
"tags": "game",
|
"tags": "game",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+flappy","url":"app.json"},
|
{"name":"flappy.app.js","url":"app.js"},
|
||||||
{"name":"-flappy","url":"app.js"},
|
{"name":"flappy.img","url":"app-icon.js","evaluate":true}
|
||||||
{"name":"*flappy","url":"app-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -684,9 +643,8 @@
|
||||||
"tags": "gps",
|
"tags": "gps",
|
||||||
"type": "app",
|
"type": "app",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name": "+gpsinfo","url": "gps-info.json"},
|
{"name":"gpsinfo.app.js","url": "gps-info.js"},
|
||||||
{"name": "-gpsinfo","url": "gps-info.js"},
|
{"name":"gpsinfo.img","url": "gps-info-icon.js","evaluate": true}
|
||||||
{"name": "*gpsinfo","url": "gps-info-icon.js","evaluate": true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -699,13 +657,13 @@
|
||||||
"type": "app",
|
"type": "app",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name": "+pomodo","url": "pomodoro.json"},
|
{"name":"pomodo.app.js","url": "pomodoro.js"},
|
||||||
{"name": "-pomodo","url": "pomodoro.js"},
|
{"name":"pomodo.img","url": "pomodoro-icon.js","evaluate": true}
|
||||||
{"name": "*pomodo","url": "pomodoro-icon.js","evaluate": true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "blobclk",
|
{ "id": "blobclk",
|
||||||
"name": "Large Digit Blob Clock",
|
"name": "Large Digit Blob Clock",
|
||||||
|
"shortName" : "Blob Clock",
|
||||||
"icon": "clock-blob.png",
|
"icon": "clock-blob.png",
|
||||||
"version":"0.03",
|
"version":"0.03",
|
||||||
"description": "A clock with big digits",
|
"description": "A clock with big digits",
|
||||||
|
|
@ -713,9 +671,8 @@
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+blobclk","url":"clock-blob.json"},
|
{"name":"blobclk.app.js","url":"clock-blob.js"},
|
||||||
{"name":"-blobclk","url":"clock-blob.js"},
|
{"name":"blobclk.img","url":"clock-blob-icon.js","evaluate":true}
|
||||||
{"name":"*blobclk","url":"clock-blob-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "boldclk",
|
{ "id": "boldclk",
|
||||||
|
|
@ -727,33 +684,30 @@
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+boldclk","url":"bold_clock.json"},
|
{"name":"boldclk.app.js","url":"bold_clock.js"},
|
||||||
{"name":"-boldclk","url":"bold_clock.js"},
|
{"name":"boldclk.img","url":"bold_clock-icon.js","evaluate":true}
|
||||||
{"name":"*boldclk","url":"bold_clock-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "wdclk",
|
{ "id": "widclk",
|
||||||
"name": "Digital clock widget",
|
"name": "Digital clock widget",
|
||||||
"icon": "digital_clock_widget.png",
|
"icon": "widget.png",
|
||||||
"version":"0.01",
|
"version":"0.01",
|
||||||
"description": "A simple digital clock widget",
|
"description": "A simple digital clock widget",
|
||||||
"tags": "widget,clock",
|
"tags": "widget,clock",
|
||||||
"type":"widget",
|
"type":"widget",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+wdclk","url":"digital_clock_widget.json"},
|
{"name":"widclk.wid.js","url":"widget.js"}
|
||||||
{"name":"=wdclk","url":"digital_clock_widget.js"}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "wpedom",
|
{ "id": "widpedom",
|
||||||
"name": "Pedometer widget",
|
"name": "Pedometer widget",
|
||||||
"icon": "pedometer_widget.png",
|
"icon": "widget.png",
|
||||||
"version":"0.06",
|
"version":"0.06",
|
||||||
"description": "Daily pedometer widget",
|
"description": "Daily pedometer widget",
|
||||||
"tags": "widget",
|
"tags": "widget",
|
||||||
"type":"widget",
|
"type":"widget",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+wpedom","url":"pedometer_widget.json"},
|
{"name":"widpedom.wid.js","url":"widget.js"}
|
||||||
{"name":"=wpedom","url":"pedometer_widget.js"}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "berlinc",
|
{ "id": "berlinc",
|
||||||
|
|
@ -765,9 +719,8 @@
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+berlinc","url":"berlin-clock.json"},
|
{"name":"berlinc.app.js","url":"berlin-clock.js"},
|
||||||
{"name":"-berlinc","url":"berlin-clock.js"},
|
{"name":"berlinc.img","url":"berlin-clock-icon.js","evaluate":true}
|
||||||
{"name":"*berlinc","url":"berlin-clock-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "ctrclk",
|
{ "id": "ctrclk",
|
||||||
|
|
@ -779,9 +732,8 @@
|
||||||
"type":"clock",
|
"type":"clock",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+ctrclk","url":"app.json"},
|
{"name":"ctrclk.app.js","url":"app.js"},
|
||||||
{"name":"-ctrclk","url":"app.js"},
|
{"name":"ctrclk.img","url":"app-icon.js","evaluate":true}
|
||||||
{"name":"*ctrclk","url":"app-icon.js","evaluate":true}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "demoapp",
|
{ "id": "demoapp",
|
||||||
|
|
@ -793,9 +745,8 @@
|
||||||
"type":"app",
|
"type":"app",
|
||||||
"allow_emulator":true,
|
"allow_emulator":true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+demoapp","url":"app.json"},
|
{"name":"demoapp.app.js","url":"app.js"},
|
||||||
{"name":"-demoapp","url":"app.js"},
|
{"name":"demoapp.img","url":"app-icon.js","evaluate":true}
|
||||||
{"name":"*demoapp","url":"app-icon.js","evaluate":true}
|
|
||||||
],
|
],
|
||||||
"sortorder" : -9
|
"sortorder" : -9
|
||||||
},
|
},
|
||||||
|
|
@ -805,9 +756,22 @@
|
||||||
"description": "App to send a command to another Espruino to cause it to raise a flag",
|
"description": "App to send a command to another Espruino to cause it to raise a flag",
|
||||||
"tags": "",
|
"tags": "",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+flagrse","url":"app.json"},
|
{"name":"flagrse.app.js","url":"app.js"},
|
||||||
{"name":"-flagrse","url":"app.js"},
|
{"name":"flagrse.img","url":"app-icon.js","evaluate":true}
|
||||||
{"name":"*flagrse","url":"app-icon.js","evaluate":true}
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "pipboy",
|
||||||
|
"name": "Pipboy",
|
||||||
|
"icon": "app.png",
|
||||||
|
"version": "0.01",
|
||||||
|
"description": "Pipboy themed clock",
|
||||||
|
"tags": "clock",
|
||||||
|
"type":"clock",
|
||||||
|
"allow_emulator":true,
|
||||||
|
"storage": [
|
||||||
|
{"name":"pipboy.app.js","url":"app.js"},
|
||||||
|
{"name":"pipboy.img","url":"app-icon.js","evaluate":true}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{ "id": "wohrm",
|
{ "id": "wohrm",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
// Create an entry in apps.json as follows:
|
// Create an entry in apps.json as follows:
|
||||||
{ "id": "7chname",
|
{ "id": "7chname",
|
||||||
"name": "My app's human readable name",
|
"name": "My app's human readable name",
|
||||||
|
"shortName":"Short Name",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"version":"0.01",
|
"version":"0.01",
|
||||||
"description": "A detailed description of my great app",
|
"description": "A detailed description of my great app",
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Short Name",
|
|
||||||
"icon":"*7chname",
|
|
||||||
"src":"-7chname"
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
// Create an entry in apps.json as follows:
|
// Create an entry in apps.json as follows:
|
||||||
{ "id": "7chname",
|
{ "id": "7chname",
|
||||||
"name": "My widget's human readable name",
|
"name": "My widget's human readable name",
|
||||||
|
"shortName":"Short Name",
|
||||||
"icon": "widget.png",
|
"icon": "widget.png",
|
||||||
"version":"0.01",
|
"version":"0.01",
|
||||||
"description": "A detailed description of my great widget",
|
"description": "A detailed description of my great widget",
|
||||||
"tags": "widget",
|
"tags": "widget",
|
||||||
|
"type": "widget",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+7chname","url":"widget.json"},
|
{"name":"+7chname","url":"widget.json"},
|
||||||
{"name":"=7chname","url":"widget.js"}
|
{"name":"=7chname","url":"widget.js"}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"name":"widgetname", "type":"widget",
|
|
||||||
"src":"=7chname"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"About",
|
|
||||||
"icon":"*about",
|
|
||||||
"src":"-about"
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Analog Clock","type":"clock",
|
|
||||||
"icon":"*aclock",
|
|
||||||
"src":"-aclock",
|
|
||||||
"sortorder":-10
|
|
||||||
}
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
0.01: New App!
|
0.01: New App!
|
||||||
|
0.02: Fix issues with alarm scheduling
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
// Chances are boot0.js got run already and scheduled *another*
|
||||||
|
// 'load(alarm.js)' - so let's remove it first!
|
||||||
|
clearInterval();
|
||||||
|
|
||||||
|
function formatTime(t) {
|
||||||
|
var hrs = 0|t;
|
||||||
|
var mins = Math.round((t-hrs)*60);
|
||||||
|
return hrs+":"+("0"+mins).substr(-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentHr() {
|
||||||
|
var time = new Date();
|
||||||
|
return time.getHours()+(time.getMinutes()/60);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showAlarm(alarm) {
|
||||||
|
var msg = formatTime(alarm.hr);
|
||||||
|
var buzzCount = 10;
|
||||||
|
if (alarm.msg)
|
||||||
|
msg += "\n"+alarm.msg;
|
||||||
|
E.showPrompt(msg,{
|
||||||
|
title:"ALARM!",
|
||||||
|
buttons : {"Sleep":true,"Ok":false} // default is sleep so it'll come back in 10 mins
|
||||||
|
}).then(function(sleep) {
|
||||||
|
buzzCount = 0;
|
||||||
|
if (sleep) {
|
||||||
|
alarm.hr += 10/60; // 10 minutes
|
||||||
|
} else {
|
||||||
|
alarm.last = (new Date()).getDate();
|
||||||
|
if (!alarm.rp) alarm.on = false;
|
||||||
|
}
|
||||||
|
require("Storage").write("alarm.json",JSON.stringify(alarms));
|
||||||
|
load();
|
||||||
|
});
|
||||||
|
function buzz() {
|
||||||
|
Bangle.buzz(100).then(()=>{
|
||||||
|
setTimeout(()=>{
|
||||||
|
Bangle.buzz(100).then(function() {
|
||||||
|
if (buzzCount--)
|
||||||
|
setTimeout(buzz, 3000);
|
||||||
|
});
|
||||||
|
},100);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
buzz();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for alarms
|
||||||
|
var day = (new Date()).getDate();
|
||||||
|
var hr = getCurrentHr();
|
||||||
|
var alarms = require("Storage").readJSON("alarm.json")||[];
|
||||||
|
var active = alarms.filter(a=>a.on&&(a.hr<hr)&&(a.last!=day));
|
||||||
|
if (active.length) {
|
||||||
|
// if there's an alarm, show it
|
||||||
|
active = active.sort((a,b)=>a.hr-b.hr);
|
||||||
|
showAlarm(active[0]);
|
||||||
|
} else {
|
||||||
|
// otherwise just go back to default app
|
||||||
|
load();
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
|
|
||||||
var alarms = require("Storage").readJSON("@alarm")||[];
|
var alarms = require("Storage").readJSON("alarm.json")||[];
|
||||||
/*alarms = [
|
/*alarms = [
|
||||||
{ on : true,
|
{ on : true,
|
||||||
hr : 6.5, // hours + minutes/60
|
hr : 6.5, // hours + minutes/60
|
||||||
|
|
@ -13,7 +13,7 @@ var alarms = require("Storage").readJSON("@alarm")||[];
|
||||||
|
|
||||||
function formatTime(t) {
|
function formatTime(t) {
|
||||||
var hrs = 0|t;
|
var hrs = 0|t;
|
||||||
var mins = 0|((t-hrs)*60);
|
var mins = Math.round((t-hrs)*60);
|
||||||
return hrs+":"+("0"+mins).substr(-2);
|
return hrs+":"+("0"+mins).substr(-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,7 +47,7 @@ function editAlarm(alarmIndex) {
|
||||||
if (!newAlarm) {
|
if (!newAlarm) {
|
||||||
var a = alarms[alarmIndex];
|
var a = alarms[alarmIndex];
|
||||||
hrs = 0|a.hr;
|
hrs = 0|a.hr;
|
||||||
mins = 0|((a.hr-hrs)*60);
|
mins = Math.round((a.hr-hrs)*60);
|
||||||
en = a.on;
|
en = a.on;
|
||||||
repeat = a.rp;
|
repeat = a.rp;
|
||||||
}
|
}
|
||||||
|
|
@ -55,15 +55,11 @@ function editAlarm(alarmIndex) {
|
||||||
'': { 'title': 'Alarms' },
|
'': { 'title': 'Alarms' },
|
||||||
'Hours': {
|
'Hours': {
|
||||||
value: hrs,
|
value: hrs,
|
||||||
min: 0,
|
onchange: function(v){if (v<0)v=23;if (v>23)v=0;hrs=v;this.value=v;} // no arrow fn -> preserve 'this'
|
||||||
max: 23,
|
|
||||||
onchange: v=>hrs=v
|
|
||||||
},
|
},
|
||||||
'Minutes': {
|
'Minutes': {
|
||||||
value: mins,
|
value: mins,
|
||||||
min: 0,
|
onchange: function(v){if (v<0)v=59;if (v>59)v=0;mins=v;this.value=v;} // no arrow fn -> preserve 'this'
|
||||||
max: 60,
|
|
||||||
onchange: v=>mins=v
|
|
||||||
},
|
},
|
||||||
'Enabled': {
|
'Enabled': {
|
||||||
value: en,
|
value: en,
|
||||||
|
|
@ -79,8 +75,8 @@ function editAlarm(alarmIndex) {
|
||||||
function getAlarm() {
|
function getAlarm() {
|
||||||
var hr = hrs+(mins/60);
|
var hr = hrs+(mins/60);
|
||||||
var day = 0;
|
var day = 0;
|
||||||
// If alarm is for tomorrow not today, set day
|
// If alarm is for tomorrow not today (eg, in the past), set day
|
||||||
if (hr > getCurrentHr())
|
if (hr < getCurrentHr())
|
||||||
day = (new Date()).getDate();
|
day = (new Date()).getDate();
|
||||||
// Save alarm
|
// Save alarm
|
||||||
return {
|
return {
|
||||||
|
|
@ -91,13 +87,13 @@ function editAlarm(alarmIndex) {
|
||||||
if (newAlarm) {
|
if (newAlarm) {
|
||||||
menu["> New Alarm"] = function() {
|
menu["> New Alarm"] = function() {
|
||||||
alarms.push(getAlarm());
|
alarms.push(getAlarm());
|
||||||
require("Storage").write("@alarm",JSON.stringify(alarms));
|
require("Storage").write("alarm.json",JSON.stringify(alarms));
|
||||||
showMainMenu();
|
showMainMenu();
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
menu["> Save"] = function() {
|
menu["> Save"] = function() {
|
||||||
alarms[alarmIndex] = getAlarm();
|
alarms[alarmIndex] = getAlarm();
|
||||||
require("Storage").write("@alarm",JSON.stringify(alarms));
|
require("Storage").write("alarm.json",JSON.stringify(alarms));
|
||||||
showMainMenu();
|
showMainMenu();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -105,47 +101,4 @@ function editAlarm(alarmIndex) {
|
||||||
return E.showMenu(menu);
|
return E.showMenu(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showAlarm(alarm) {
|
showMainMenu();
|
||||||
var msg = formatTime(alarm.hr);
|
|
||||||
var buzzCount = 10;
|
|
||||||
if (alarm.msg)
|
|
||||||
msg += "\n"+alarm.msg;
|
|
||||||
E.showPrompt(msg,{
|
|
||||||
title:"ALARM!",
|
|
||||||
buttons : {"Sleep":true,"Ok":false} // default is sleep so it'll come back in 10 mins
|
|
||||||
}).then(function(sleep) {
|
|
||||||
buzzCount = 0;
|
|
||||||
if (sleep) {
|
|
||||||
alarm.hr += 10/60; // 10 minutes
|
|
||||||
} else {
|
|
||||||
alarm.last = (new Date()).getDate();
|
|
||||||
if (!alarm.rp) alarm.on = false;
|
|
||||||
}
|
|
||||||
require("Storage").write("@alarm",JSON.stringify(alarms));
|
|
||||||
load();
|
|
||||||
});
|
|
||||||
function buzz() {
|
|
||||||
Bangle.buzz(100).then(()=>{
|
|
||||||
setTimeout(()=>{
|
|
||||||
Bangle.buzz(100).then(function() {
|
|
||||||
if (buzzCount--)
|
|
||||||
setTimeout(buzz, 3000);
|
|
||||||
});
|
|
||||||
},100);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
buzz();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for alarms
|
|
||||||
var day = (new Date()).getDate();
|
|
||||||
var hr = getCurrentHr();
|
|
||||||
var active = alarms.filter(a=>a.on&&(a.hr<hr)&&(a.last!=day));
|
|
||||||
if (active.length) {
|
|
||||||
// if there's an alarm, show it
|
|
||||||
active = active.sort((a,b)=>a.hr-b.hr);
|
|
||||||
showAlarm(active[0]);
|
|
||||||
} else {
|
|
||||||
// otherwise show the main menu
|
|
||||||
showMainMenu();
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Alarms",
|
|
||||||
"icon":"*alarm",
|
|
||||||
"src":"-alarm"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
(() => {
|
(() => {
|
||||||
var alarms = require('Storage').readJSON('@alarm')||[];
|
var alarms = require('Storage').readJSON('alarm.json')||[];
|
||||||
alarms = alarms.filter(alarm=>alarm.on);
|
alarms = alarms.filter(alarm=>alarm.on);
|
||||||
if (!alarms.length) return;
|
if (!alarms.length) return;
|
||||||
delete alarms;
|
delete alarms;
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AH4Az4/HDDAACCywaSCpgeLBQOjzowRIxZPMBIWj0YvjNRKQSCpIWBEBq/VF6hrKdpwuKABYvXFywlDXjw5aF1gvKF0gv5F0ovvFxQxkF9ztLF8ItJF5XGAAIrfeJYtB4D7TFyQlEFwg8INgZtFF6wuCF4wAFBoPAF7ouNF8AfCF56ZFFyofEF9YgCF5z6GF9y+TC4SAFF9ZgNBgovZMAeczgRJBYovXMAtPAAIQIBYouXDAWjEYUrGBMrBYgvY/15vNVCtAADqoACCs4A/AH4A/AH4A/ABY")
|
require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AH4Az4/HDDAACCywaSCpgeLBQOjzowRIxZPMBIWj0YvjNRKQSCpIWBEBq/VF6hrKdpwuKABYvXFywlDXjw5aF1gvKF0gv5F0ovvFxQxkF9ztLF8ItJF5XGAAIrfeJYtB4D7TFyQlEFwg8INgZtFF6wuCF4wAFBoPAF7ouNF8AfCF56ZFFyofEF9YgCF5z6GF9y+TC4SAFF9ZgNBgovZMAeczgRJBYovXMAtPAAIQIBYouXDAWjEYUrGBMrBYgvY/15vNVCtAADqoACCs4A/AH4A/AH4A/ABY"))
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AH4A/ACXJ5PKAQfKAAPJB4nDAAIsaEwQAJ5IrCAAYbFGyBWBFyooCGxQABPAyDEABYuHGxInFAAQGGLyoIGLxQvCFyAvJBIzjKdB6OLagYwDc5K/DFyIVBAAprHF5IsTHaAuKRoSOSABwvMXyZhPF5iNfF9nJp9PGB4vh5PD3u8X86PCFwO8AAS/mGQe9zAACF/CPdF4aPD3rwmGAu9FxRghegQuKL8IvBFxYwhFx6QdFpxedXIIuQLpHJ4YdCBoQDDFQosRLxAaB4YAEIRIQDFyQvEFhYwGCQgvX/wcOCYYuWDYSmCF6CfEF6mlz96vX+z+evVPCZwABCJYAJvVVAAVPAAYTNCJoAJFwYvPCY5gUAH4A/AH4A/AH4A2")
|
require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AH4A/ACXJ5PKAQfKAAPJB4nDAAIsaEwQAJ5IrCAAYbFGyBWBFyooCGxQABPAyDEABYuHGxInFAAQGGLyoIGLxQvCFyAvJBIzjKdB6OLagYwDc5K/DFyIVBAAprHF5IsTHaAuKRoSOSABwvMXyZhPF5iNfF9nJp9PGB4vh5PD3u8X86PCFwO8AAS/mGQe9zAACF/CPdF4aPD3rwmGAu9FxRghegQuKL8IvBFxYwhFx6QdFpxedXIIuQLpHJ4YdCBoQDDFQosRLxAaB4YAEIRIQDFyQvEFhYwGCQgvX/wcOCYYuWDYSmCF6CfEF6mlz96vX+z+evVPCZwABCJYAJvVVAAVPAAYTNCJoAJFwYvPCY5gUAH4A/AH4A/AH4A2"))
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AGesAAQuuGAQ1jFQoAKF1wwdFyQycF6wwVFi4wWEiOBq1WqoABvQHBvWALsl6p4ADF4IIBGwSNjMAJdCAAVVGwQwPXjWBFoMrF4IwOFzVWp94lV4vIwNFzS8CvGi0YFCGBSNadohdCF9gAGdsgvuGJTvkGAgABFxv+wAwcAAQsLAAVPF9lPAAOIF1tWF7qMOp4DBxAABXtIADGAWB0oupGAeAvQABwJmGAwmlwQuZAAQuCF4SYDAgRtBBoeswKsDF7gsEF4+BqovfAANWF5VWFwIvZGAf+EAYuDBooOEF8ANJF/4vREIQv7BxIvZEIwvvBwQveEIIEDF9QA/AH4A/AH4ASA=")
|
require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AGesAAQuuGAQ1jFQoAKF1wwdFyQycF6wwVFi4wWEiOBq1WqoABvQHBvWALsl6p4ADF4IIBGwSNjMAJdCAAVVGwQwPXjWBFoMrF4IwOFzVWp94lV4vIwNFzS8CvGi0YFCGBSNadohdCF9gAGdsgvuGJTvkGAgABFxv+wAwcAAQsLAAVPF9lPAAOIF1tWF7qMOp4DBxAABXtIADGAWB0oupGAeAvQABwJmGAwmlwQuZAAQuCF4SYDAgRtBBoeswKsDF7gsEF4+BqovfAANWF5VWFwIvZGAf+EAYuDBooOEF8ANJF/4vREIQv7BxIvZEIwvvBwQveEIIEDF9QA/AH4A/AH4ASA="))
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ function next(e) {
|
||||||
} while (current && current==last);
|
} while (current && current==last);
|
||||||
g.clear();
|
g.clear();
|
||||||
var n = 1 + (0|(Math.random()*3.9));
|
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)
|
if (n==1)
|
||||||
g.drawImage(img,120,120,{scale:4,rotate:Math.random()-0.5});
|
g.drawImage(img,120,120,{scale:4,rotate:Math.random()-0.5});
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Animals Game", "type":"app",
|
|
||||||
"icon":"*animals",
|
|
||||||
"src":"-animals"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Asteroids!","type":"app",
|
|
||||||
"icon":"*astroid",
|
|
||||||
"src":"-astroid"
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Binary Clock",
|
|
||||||
"type":"clock",
|
|
||||||
"icon":"*bclock",
|
|
||||||
"src":"-bclock"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -196,20 +196,12 @@ Bangle.on('mag', function(m) {
|
||||||
Bangle.setCompassPower(1);
|
Bangle.setCompassPower(1);
|
||||||
Bangle.setGPSPower(1);
|
Bangle.setGPSPower(1);
|
||||||
g.clear();`;
|
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"))`;
|
var icon = `require("heatshrink").decompress(atob("mEwghC/AB0O/4AG8AXNgYXHmAXl94XH+AXNn4XH/wXW+YX/C6oWHAAIXN7sz9vdAAoXN9sznvuAAXf/vuC53jC4Xd7wXQ93jn3u9vv9vt7wXT/4tBAgIXQ7wvCC4PgC5sO6czIQJfBC6PumaPDC6wwCC50NYAJcBVgIDBCxrAFbgYXP7yoDF6TADL4YXPVAIXCRyAXC7wXW9zwBC6cNC9zABC4gWQC653CR4fQC6x3TF6gXXI4M9d6wAEC9EN73dAAZfQgczAAkwC/4XXAH4"))`;
|
||||||
|
|
||||||
sendCustomizedApp({
|
sendCustomizedApp({
|
||||||
id : "beer",
|
|
||||||
|
|
||||||
storage:[
|
storage:[
|
||||||
{name:"-beer", content:app},
|
{name:"beer.app.js", content:app},
|
||||||
{name:"+beer", content:json},
|
{name:"beer.img", content:icon, evaluate:true},
|
||||||
{name:"*beer", content:icon, evaluate:true},
|
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Berlin Clock",
|
|
||||||
"type":"clock",
|
|
||||||
"icon":"*berlinc",
|
|
||||||
"src":"-berlinc"
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
{
|
|
||||||
"name": "BLE Scanner",
|
|
||||||
"type":"app",
|
|
||||||
"icon": "*blescan",
|
|
||||||
"src": "-blescan"
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Large Clock",
|
|
||||||
"type":"clock",
|
|
||||||
"icon":"*blobclk",
|
|
||||||
"src":"-blobclk",
|
|
||||||
"sortorder":-10
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Bold Clock",
|
|
||||||
"type":"clock",
|
|
||||||
"icon":"*boldclk",
|
|
||||||
"src":"-boldclk",
|
|
||||||
"sortorder":-10
|
|
||||||
}
|
|
||||||
|
|
@ -2,3 +2,5 @@
|
||||||
0.03: Fix issue switching clockfaces via menu
|
0.03: Fix issue switching clockfaces via menu
|
||||||
0.04: Add alarm functionality
|
0.04: Add alarm functionality
|
||||||
0.05: Add Welcome screen on boot
|
0.05: Add Welcome screen on boot
|
||||||
|
0.06: Disable GPS time log messages, add (default=1) setting to hide log messages
|
||||||
|
0.07: Fix issues with alarm scheduling
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,20 @@
|
||||||
// This ALWAYS runs at boot
|
// This ALWAYS runs at boot
|
||||||
E.setFlags({pretokenise:1});
|
E.setFlags({pretokenise:1});
|
||||||
// Load settings...
|
// Load settings...
|
||||||
var s = require('Storage').readJSON('@setting')||{};
|
var s = require('Storage').readJSON('setting.json')||{};
|
||||||
if (s.ble!==false) {
|
if (s.ble!==false) {
|
||||||
if (s.HID) { // Humen interface device
|
if (s.HID) { // Human interface device
|
||||||
Bangle.HID = E.toUint8Array(atob("BQEJBqEBhQIFBxngKecVACUBdQGVCIEClQF1CIEBlQV1AQUIGQEpBZEClQF1A5EBlQZ1CBUAJXMFBxkAKXOBAAkFFQAm/wB1CJUCsQLABQwJAaEBhQEVACUBdQGVAQm1gQIJtoECCbeBAgm4gQIJzYECCeKBAgnpgQIJ6oECwA=="));
|
Bangle.HID = E.toUint8Array(atob("BQEJBqEBhQIFBxngKecVACUBdQGVCIEClQF1CIEBlQV1AQUIGQEpBZEClQF1A5EBlQZ1CBUAJXMFBxkAKXOBAAkFFQAm/wB1CJUCsQLABQwJAaEBhQEVACUBdQGVAQm1gQIJtoECCbeBAgm4gQIJzYECCeKBAgnpgQIJ6oECwA=="));
|
||||||
NRF.setServices({}, {uart:true, hid:Bangle.HID});
|
NRF.setServices({}, {uart:true, hid:Bangle.HID});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If not programmable, force terminal onto screen
|
if (s.blerepl===false) { // If not programmable, force terminal off Bluetooth
|
||||||
if (s.dev===false) Terminal.setConsole(true);
|
if (s.log) Terminal.setConsole(true); // if showing debug, force REPL onto terminal
|
||||||
|
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
|
||||||
|
}
|
||||||
// we just reset, so BLE should be on
|
// we just reset, so BLE should be on
|
||||||
if (s.ble===false) NRF.sleep();
|
if (s.ble===false) NRF.sleep();
|
||||||
// Set time, vibrate, beep, etc
|
// Set time, vibrate, beep, etc
|
||||||
|
|
@ -21,82 +26,43 @@ E.setTimeZone(s.timezone);
|
||||||
delete s;
|
delete s;
|
||||||
// check for alarms
|
// check for alarms
|
||||||
function checkAlarm() {
|
function checkAlarm() {
|
||||||
var alarms = require('Storage').readJSON('@alarm')||[];
|
var alarms = require('Storage').readJSON('alarm.json')||[];
|
||||||
var time = new Date();
|
var time = new Date();
|
||||||
var active = alarms.filter(a=>a.on&&(a.last!=time.getDate()));
|
var active = alarms.filter(a=>a.on&&(a.last!=time.getDate()));
|
||||||
if (active.length) {
|
if (active.length) {
|
||||||
active = active.sort((a,b)=>a.hr-b.hr);
|
active = active.sort((a,b)=>a.hr-b.hr);
|
||||||
var hr = time.getHours()+(time.getMinutes()/60);
|
var hr = time.getHours()+(time.getMinutes()/60)+(time.getSeconds()/3600);
|
||||||
if (!require('Storage').read("-alarm")) {
|
if (!require('Storage').read("alarm.js")) {
|
||||||
console.log("No alarm app!");
|
console.log("No alarm app!");
|
||||||
require('Storage').write('@alarm',"[]")
|
require('Storage').write('alarm.json',"[]")
|
||||||
} else {
|
} else {
|
||||||
if (active[0].hr < hr) {
|
var t = 3600000*(active[0].hr-hr);
|
||||||
// fire alarm now
|
if (t<1000) t=1000;
|
||||||
load("-alarm");
|
/* execute alarm at the correct time. We avoid execing immediately
|
||||||
} else {
|
since this code will get called AGAIN when alarm.js is loaded. alarm.js
|
||||||
// execute alarm at the correct time
|
will then clearInterval() to get rid of this call so it can proceed
|
||||||
setTimeout(function() {
|
normally. */
|
||||||
load("-alarm");
|
setTimeout(function() {
|
||||||
},3600000*(active[0].hr-hr));
|
load("alarm.js");
|
||||||
}
|
},t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// check to see if our clock is wrong - if it is use GPS time
|
// check to see if our clock is wrong - if it is use GPS time
|
||||||
if ((new Date()).getFullYear()==1970) {
|
if ((new Date()).getFullYear()==1970) {
|
||||||
console.log("Searching for GPS time");
|
//console.log("Searching for GPS time");
|
||||||
Bangle.on('GPS',function cb(g) {
|
Bangle.on('GPS',function cb(g) {
|
||||||
Bangle.setGPSPower(0);
|
Bangle.setGPSPower(0);
|
||||||
Bangle.removeListener("GPS",cb);
|
Bangle.removeListener("GPS",cb);
|
||||||
if (!g.time || (g.time.getFullYear()<2000) ||
|
if (!g.time || (g.time.getFullYear()<2000) ||
|
||||||
(g.time.getFullYear()==2250)) {
|
(g.time.getFullYear()==2250)) {
|
||||||
console.log("GPS receiver's time not set");
|
//console.log("GPS receiver's time not set");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setTime(g.time.getTime()/1000);
|
setTime(g.time.getTime()/1000);
|
||||||
console.log("GPS time",g.time.toString());
|
//console.log("GPS time",g.time.toString());
|
||||||
checkAlarm();
|
checkAlarm();
|
||||||
});
|
});
|
||||||
Bangle.setGPSPower(1);
|
Bangle.setGPSPower(1);
|
||||||
} else checkAlarm();
|
} else checkAlarm();
|
||||||
delete 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
// This runs after a 'fresh' boot
|
// This runs after a 'fresh' boot
|
||||||
var settings={};
|
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) {
|
if (!settings.welcomed && require("Storage").read("welcome.js")!==undefined) {
|
||||||
setTimeout(()=>load("-welcome"));
|
setTimeout(()=>load("welcome.js"));
|
||||||
} else {
|
} else {
|
||||||
// load clock if specified
|
// load clock if specified
|
||||||
var clockApp = settings.clock;
|
var clockApp = settings.clock;
|
||||||
if (clockApp) clockApp = require("Storage").read(clockApp)
|
if (clockApp) clockApp = require("Storage").read(clockApp)
|
||||||
if (!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); }
|
try { return require("Storage").readJSON(app); }
|
||||||
catch (e) {}
|
catch (e) {}
|
||||||
}).filter(app=>app.type=="clock").sort((a, b) => a.sortorder - b.sortorder);
|
}).filter(app=>app.type=="clock").sort((a, b) => a.sortorder - b.sortorder);
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Bootloader","type":"boot"
|
|
||||||
}
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
require("heatshrink").decompress(atob("mEwgRC/AH4A/gED/k/5/wh/wgAFCBcg7NgAVBh/zDoYLkHaAFqAH4A/AH4AW"));
|
require("heatshrink").decompress(atob("mEwgRC/AH4A/gED/k/5/wh/wgAFCBcg7NgAVBh/zDoYLkHaAFqAH4A/AH4AW"))
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Clock 3x2 Pix",
|
|
||||||
"type":"clock",
|
|
||||||
"icon":"*clck3x2",
|
|
||||||
"src":"-clck3x2"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Click Master",
|
|
||||||
"icon": "*clickms",
|
|
||||||
"src":"-clickms"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Clock-Tris",
|
|
||||||
"icon":"*clotris",
|
|
||||||
"src":"-clotris"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Compass","type":"app",
|
|
||||||
"icon":"*compass",
|
|
||||||
"src":"-compass"
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"name": "Centerclock",
|
|
||||||
"type": "clock",
|
|
||||||
"icon": "*ctrclk",
|
|
||||||
"src": "-ctrclk"
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Cube",
|
|
||||||
"type":"app",
|
|
||||||
"icon":"*cube",
|
|
||||||
"src":"-cube"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Demo Loop",
|
|
||||||
"icon":"*demoapp",
|
|
||||||
"src":"-demoapp"
|
|
||||||
}
|
|
||||||
|
|
@ -66,8 +66,8 @@ function showApps() {
|
||||||
'< Back': () => m = showMainMenu(),
|
'< Back': () => m = showMainMenu(),
|
||||||
};
|
};
|
||||||
|
|
||||||
var list = storage.list().filter((a)=> {
|
var list = storage.list(/\.info$/).filter((a)=> {
|
||||||
return a[0]=='+' && a !== '+setting';
|
return a !== 'setting.info';
|
||||||
}).sort().map((app) => {
|
}).sort().map((app) => {
|
||||||
var ret = storage.readJSON(app);
|
var ret = storage.readJSON(app);
|
||||||
ret[''] = app;
|
ret[''] = app;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"App Manager","type":"app",
|
|
||||||
"icon":"*files",
|
|
||||||
"src":"-files"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Flag Raiser",
|
|
||||||
"icon":"*flagrse",
|
|
||||||
"src":"-flagrse"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Flappy Bird",
|
|
||||||
"icon":"*flappy",
|
|
||||||
"src":"-flappy"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Gadgetbridge",
|
|
||||||
"icon":"*gbridge",
|
|
||||||
"src":"-gbridge"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Gesture Test", "type":"app",
|
|
||||||
"icon":"*gesture",
|
|
||||||
"src":"-gesture"
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"name": "GPS Info",
|
|
||||||
"type": "app",
|
|
||||||
"icon": "*gpsinfo",
|
|
||||||
"src": "-gpsinfo"
|
|
||||||
}
|
|
||||||
|
|
@ -1,2 +1,4 @@
|
||||||
0.01: New App!
|
0.01: New App!
|
||||||
0.02: Fix GPS time logging
|
0.02: Fix GPS time logging
|
||||||
|
0.03: Fix GPS time display in gpsrec app
|
||||||
|
0.04: Properly Fix GPS time display in gpsrec app
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
Bangle.drawWidgets();
|
Bangle.drawWidgets();
|
||||||
|
|
||||||
var settings = require("Storage").readJSON("@gpsrec")||{};
|
var settings = require("Storage").readJSON("gpsrec.json")||{};
|
||||||
|
|
||||||
function getFN(n) {
|
function getFN(n) {
|
||||||
return ".gpsrc"+n.toString(36);
|
return ".gpsrc"+n.toString(36);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSettings() {
|
function updateSettings() {
|
||||||
require("Storage").write("@gpsrec", settings);
|
require("Storage").write("gpsrec.json", settings);
|
||||||
if (WIDGETS["gpsrec"])
|
if (WIDGETS["gpsrec"])
|
||||||
WIDGETS["gpsrec"].reload();
|
WIDGETS["gpsrec"].reload();
|
||||||
}
|
}
|
||||||
|
|
@ -80,7 +80,7 @@ function viewTrack(n) {
|
||||||
var l = f.readLine();
|
var l = f.readLine();
|
||||||
if (l!==undefined) {
|
if (l!==undefined) {
|
||||||
var c = l.split(",");
|
var c = l.split(",");
|
||||||
trackTime = new Date(0|c[0]);
|
trackTime = new Date(parseInt(c[0]));
|
||||||
}
|
}
|
||||||
while (l!==undefined) {
|
while (l!==undefined) {
|
||||||
trackCount++;
|
trackCount++;
|
||||||
|
|
@ -104,7 +104,6 @@ function viewTrack(n) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
menu['< Back'] = viewTracks;
|
menu['< Back'] = viewTracks;
|
||||||
print(menu);
|
|
||||||
return E.showMenu(menu);
|
return E.showMenu(menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"GPS Recorder",
|
|
||||||
"icon":"*gpsrec",
|
|
||||||
"src":"-gpsrec"
|
|
||||||
}
|
|
||||||
|
|
@ -55,7 +55,7 @@
|
||||||
|
|
||||||
// Called by the GPS app to reload settings and decide what's
|
// Called by the GPS app to reload settings and decide what's
|
||||||
function reload() {
|
function reload() {
|
||||||
settings = require("Storage").readJSON("@gpsrec")||{};
|
settings = require("Storage").readJSON("gpsrec.json")||{};
|
||||||
settings.period = settings.period||1;
|
settings.period = settings.period||1;
|
||||||
settings.file |= 0;
|
settings.file |= 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
0.03: Fix time output on new firmwares when no GPS time set (fix #104)
|
||||||
|
|
@ -5,11 +5,11 @@ Bangle.setLCDTimeout(0);
|
||||||
|
|
||||||
g.clear();
|
g.clear();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var fix;
|
var fix;
|
||||||
|
Bangle.setGPSPower(1);
|
||||||
Bangle.on('GPS',function(f) {
|
Bangle.on('GPS',function(f) {
|
||||||
fix = f;
|
fix = f;
|
||||||
|
g.reset(1);
|
||||||
g.setFont("6x8",2);
|
g.setFont("6x8",2);
|
||||||
g.setFontAlign(0,0);
|
g.setFontAlign(0,0);
|
||||||
g.clearRect(90,30,239,90);
|
g.clearRect(90,30,239,90);
|
||||||
|
|
@ -24,7 +24,10 @@ Bangle.on('GPS',function(f) {
|
||||||
g.drawString(fix.satellites+" satellites",170,80);
|
g.drawString(fix.satellites+" satellites",170,80);
|
||||||
|
|
||||||
g.clearRect(0,100,239,239);
|
g.clearRect(0,100,239,239);
|
||||||
var t = fix.time.toString().split(" ");/*
|
var t = ["","","","---",""];
|
||||||
|
if (fix.time!==undefined)
|
||||||
|
t = fix.time.toString().split(" ");
|
||||||
|
/*
|
||||||
[
|
[
|
||||||
"Sun",
|
"Sun",
|
||||||
"Nov",
|
"Nov",
|
||||||
|
|
@ -42,23 +45,24 @@ Bangle.on('GPS',function(f) {
|
||||||
g.drawString(t[3],120,160); // year
|
g.drawString(t[3],120,160); // year
|
||||||
g.setFont("6x8",3);
|
g.setFont("6x8",3);
|
||||||
g.drawString(t[4],120,185); // time
|
g.drawString(t[4],120,185); // time
|
||||||
// timezone
|
if (fix.time) {
|
||||||
var tz = (new Date()).getTimezoneOffset()/60;
|
// timezone
|
||||||
if (tz==0) tz="UTC";
|
var tz = (new Date()).getTimezoneOffset()/60;
|
||||||
else if (tz>0) tz="UTC+"+tz;
|
if (tz==0) tz="UTC";
|
||||||
else tz="UTC"+tz;
|
else if (tz>0) tz="UTC+"+tz;
|
||||||
g.setFont("6x8",2);
|
else tz="UTC"+tz;
|
||||||
g.drawString(tz,120,210); // gmt
|
g.setFont("6x8",2);
|
||||||
g.setFontAlign(0,0,3);
|
g.drawString(tz,120,210); // gmt
|
||||||
g.drawString("Set",230,120);
|
g.setFontAlign(0,0,3);
|
||||||
g.setFontAlign(0,0);
|
g.drawString("Set",230,120);
|
||||||
|
g.setFontAlign(0,0);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
setInterval(function() {
|
setInterval(function() {
|
||||||
g.drawImage(img,48,48,{scale:1.5,rotate:Math.sin(getTime()*2)/2});
|
g.drawImage(img,48,48,{scale:1.5,rotate:Math.sin(getTime()*2)/2});
|
||||||
},100);
|
},100);
|
||||||
setWatch(function() {
|
setWatch(function() {
|
||||||
setTime(fix.time.getTime()/1000);
|
if (fix.time!==undefined)
|
||||||
|
setTime(fix.time.getTime()/1000);
|
||||||
}, BTN2, {repeat:true});
|
}, BTN2, {repeat:true});
|
||||||
|
|
||||||
Bangle.setGPSPower(1)
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"GPS Time","type":"app",
|
|
||||||
"icon":"*gpstime",
|
|
||||||
"src":"-gpstime"
|
|
||||||
}
|
|
||||||
|
|
@ -5,7 +5,7 @@ the touchscreen
|
||||||
|
|
||||||
var storage = require('Storage');
|
var storage = require('Storage');
|
||||||
|
|
||||||
const settings = storage.readJSON('@setting') || { HID: false };
|
const settings = storage.readJSON('setting.json') || { HID: false };
|
||||||
const KEY = {
|
const KEY = {
|
||||||
A : 4 ,
|
A : 4 ,
|
||||||
B : 5 ,
|
B : 5 ,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name": "Binary Keyboard","type":"app",
|
|
||||||
"icon": "*hidbkbd",
|
|
||||||
"src": "-hidbkbd"
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
var storage = require('Storage');
|
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;
|
var sendHid, next, prev, toggle, up, down, profile;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name": "Keyboard Control","type":"app",
|
|
||||||
"icon": "*hidkbd",
|
|
||||||
"src": "-hidkbd"
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
var storage = require('Storage');
|
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;
|
var sendHid, next, prev, toggle, up, down, profile;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name": "Music Control","type":"app",
|
|
||||||
"icon": "*hidmsic",
|
|
||||||
"src": "-hidmsic"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Horse Race",
|
|
||||||
"icon": "*horsey",
|
|
||||||
"src":"-horsey"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Hypno Rings","type":"app",
|
|
||||||
"icon":"*hrings",
|
|
||||||
"src":"-hrings"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Heart Rate","type":"app",
|
|
||||||
"icon":"*hrm",
|
|
||||||
"src":"-hrm"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Jingle Bells","type":"app",
|
|
||||||
"icon":"*jbells",
|
|
||||||
"src":"-jbells"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
var s = require("Storage");
|
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); }
|
try { return s.readJSON(app); }
|
||||||
catch (e) { return {name:"DEAD: "+app.substr(1)} }
|
catch (e) { return {name:"DEAD: "+app.substr(1)} }
|
||||||
}).filter(app=>app.type=="app" || app.type=="clock" || !app.type);
|
}).filter(app=>app.type=="app" || app.type=="clock" || !app.type);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Launcher","type":"launch",
|
|
||||||
"src":"-launch"
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Morphing Clock","type":"clock",
|
|
||||||
"icon":"*mclock",
|
|
||||||
"src":"-mclock",
|
|
||||||
"sortorder":-10
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Mixed Clock","type":"clock",
|
|
||||||
"icon":"*miclock",
|
|
||||||
"src":"-miclock",
|
|
||||||
"sortorder":-10
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Manic Monday tone",
|
|
||||||
"icon": "*mmonday",
|
|
||||||
"src":"-mmonday"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Morse Code","type":"app",
|
|
||||||
"icon":"*morse",
|
|
||||||
"src":"-morse"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"nceuwid",
|
|
||||||
"type":"widget",
|
|
||||||
"src":"=nceuwid"
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"name":"5K Fun Run","type":"app",
|
|
||||||
"icon":"*ncfrun",
|
|
||||||
"src":"-ncfrun",
|
|
||||||
"sortorder":-1
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
NRF.sleep();
|
|
||||||
var g = Graphics.getInstance();
|
|
||||||
g.setFontAlign(1, 1, 0);
|
g.setFontAlign(1, 1, 0);
|
||||||
const d = g.getWidth() - 18;
|
const d = g.getWidth() - 18;
|
||||||
function c(a) {
|
function c(a) {
|
||||||
|
|
@ -53,7 +51,7 @@ function logos() {
|
||||||
];
|
];
|
||||||
function next() {
|
function next() {
|
||||||
var n = logos.shift();
|
var n = logos.shift();
|
||||||
var img = require("Storage").read("*"+n[0]);
|
var img = require("Storage").read("nc-"+n[0]+".img");
|
||||||
g.clear();
|
g.clear();
|
||||||
g.drawImage(img, n[1], n[2]);
|
g.drawImage(img, n[1], n[2]);
|
||||||
n[3]();
|
n[3]();
|
||||||
|
|
@ -117,16 +115,11 @@ function info() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function cleanup() {
|
function cleanup() {
|
||||||
E.showMessage('Loading...');
|
try {
|
||||||
var s = require('Storage');
|
var settings = require("Storage").readJSON('setting.json');
|
||||||
s.erase('*nfr');
|
settings.welcomed = true;
|
||||||
s.erase('*nceu');
|
require("Storage").write('setting.json',settings);
|
||||||
s.erase('*bangle');
|
} catch (e) {}
|
||||||
s.erase('*nodew');
|
|
||||||
s.erase('*tf');
|
|
||||||
s.erase('+ncstart');
|
|
||||||
s.erase('.boot3');
|
|
||||||
s.erase('*ncstart');
|
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"name": "NCEU Start",
|
|
||||||
"type": "app",
|
|
||||||
"icon": "*ncstart",
|
|
||||||
"src": ".boot3"
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
eval(require("Storage").read("ncstart.app.js"))
|
||||||
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Open Location","type":"app",
|
|
||||||
"icon":"*openloc",
|
|
||||||
"src":"-openloc"
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEwxH+AC4fDDjAuSgwACGFIuBhgACGAJjmLoQvDGAJkhbAguGGYwxbRAoAMGDZZMGBAvSbIpdSGCxYCW5jpDHhKSRDYQgGAwY8ETZYvPDZBXEAAwUFNAowOF44bFNJI2ENISRQdIqzLYhAxDAoRgScZgwFdow1DF54tQdpRMDF5jjHLiDxWF44wJBZIJFF5qPGF5blDLxIvPeAjsOF7RgCc6QvId6AvUd5QACF5pyEKAwlGF5qORcIwoFBgIwHFwwvTU4gvILxYuOXwouKA5AwGFxzuIDYYvkDQ6GIABKqEL6ryGF8QbHF6QXFX6wvuYIQvnFJgMBAAQva/wgMBQT4CF5QPCeB65CABgwCHxYuOF6L5JHYYuPSAyDFBRS6TMA4AME4RdHFyhgCLRLoJLzBgDExa7JFywwVFzQwTFwIADGDC5NRohDBSTQdCGCARCGDRNCGRQuFSobAYGAYxIFwoTDGKpMGWggADA4Q1FYipNGGA7NHYawVBD44qDGIbEHIwwlEA="))
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
const bigFont = 4;
|
||||||
|
const smallFont = 2;
|
||||||
|
const tinyFont = 1;
|
||||||
|
const green = 0x0661;
|
||||||
|
const darkGreen = 0x0461;
|
||||||
|
const darkerGreen = 0x0261;
|
||||||
|
const pip = require("heatshrink").decompress(atob("klQyAlihNhgNhNP5FC0MjokboUJ8JC64ABBgNAjdDifiikhjfjjekjcDgOhImMKoUbscTsUbwUT4QBC8UMkMMgUT8MLwcBS8/hiNiIo2DhkBgkhhfhHoMT0MT0RLBjYJCCIMTocBUoIAiiIvBgcKsMSG4KLChY1CjckgUhgOAhJDBocL4RTBAYMT0ZJliS9BwUDQIchgWAhXCgVAgUghWhiXihWBgUAhdjhYTBkEB8ELkUTgcA8BHfgNAZ4MT8UTwcCJIOjikjihVB8QDBAIcToUSRYNDkdjjWDgOhjdjhVBI8EAgVBiXhQ4MTkcb4ZPCTILLBAYPBjZDBAIUL8QBBd4KRBWIMboZHfiPCOIMKsK5BR4XChkBAIUChkiheibYMT0RPBBoJZBgWgiRfD0RHfhMhhPhjcjhcBiQrBwSHBRocLRINCgUAhWBR4SZBsatCI4IRBsRHfAAMKkJBBhYBCgfBgZDBAYQFC0Q3BicCgehgbRBscKoMCkBlBjXiI8IxBifDgVAidDhfiIoMLkMUgUb4USQ4MiAoLlDiejgVhI4L3BjUjIr8BIILPBwUBwEa8YzBhQ/BoTLBjejgOgiTVEhkChdhiXCI4MB4MA8BHgsAxBjkDP4MjskTgZ3BTIMMkMb8cKLINCS4KPEcIMChWiK4LVhgJ5EAIJJBOoKTBbIQLB4I9BA4QJDCoOigZLBocJ8JHiwELGoPAgfghdCBIJ7BH4mhAYXAAYMDAIQNE0UKwJHioETwZ/C8cT0cS4UDgCBC4UTHIKjCiaNChfiB4SVDoUA4BJhicjhVgjeEjfDifiikCiZPBwUS4MB4ES0Ub4UUgMMgJDBAYJTBiXjIsIABiPiaIK5BgWggXhhXhgQJB4Mi8kakRJBHoJHDLIViiWCWYJHjhNBhWCHoMK0MbgkbkkTgYHBKYMTgUC4DVCcYUbscB8BDjAArFBOoKLCoECgADBaoMToUTsMLwML0MLBIUJ4JFpAAK3BidDhfiQIXCQIIBBRIcEgJFC0UKoJFrbYnBjeDibHBAIUMgIFC8QBC4UKsEA8EZ4cRJd0BwDPC8Y/BI4IBBR4IHBheijXkgOBjcCjcDVoJHriUiiWigVhiY3BS4PBI4JLCwcKkUK0UMgULwSrBiPBRtEhidDQII3BgMgPoMKgRRBhVhgPAiWBieCiehhQBBoKpBJYJFjiPihPhhdChfBieiGIMKwEKkI5BJIMTsUL4UL4afBgUgidjBIMbscJsBFfhOhjdDicigUAhWBYYMT8MT4QBHcIMCwIVBU4TnCMIMbgarBaLkgIoML8UT8Q1BiViYYI/DikCAoRXCgOAiWCCoIbBAIRHBEIPjBoJHbiR7D8UMgQ9BIoMKbIIJCAIMLkMSoSjCIYUMgIBECYIFCKYL/BIq8KgMTwRtBXIcL0UKsELRIIJBBYUCwEK4UL4UD4MDCoPgCIITEEIYJBgUBsLTUsMTka1DAIS3B0UCoETQYIvCT4MKoLXBH4QXCAYIBDEInhSIIZCsTTUsQZBNIXigkBGIVjgUhZIQ7DTIIPBoSHESoRDFAIYlBT4MToUBkCNQsETsRFBgaFBAoPhEIUiR4WiB4QxBwK+BhYTCZojPDAIYJCgfgAoRjBkKNQ0UTZoLVBgMKOYPihiLBoYhBToQJBXocALYbTEEIJHFE4IJCUYQFBkUA8CNMPoOCGIIBCoLPC4aPCsTNCBoIvD4MCkC/BHYrZEAoKTGdIQDB0UJ4KNMsR9CDYeCgR9BwZ9CsQHBGYhHB4RHGJIT1CNoTdGMIQnC0MSwSNKgEbobBBYYQXCgQrBkYpCJ4T9BI4sKkELoQzEMoKtB0BhBQYKnCT4Z5EjdCHoIAHTYIbBZYIBBDIWihWBhWhhYBBI4UDsJPCDIOhI4TjBD4PBAIJ9C8SdCkQdBBYIbCEoITDwUJ0JHHhTLBe4xPBhUigVBA4TNBoIhBA4KjC8RZBhcCDoKvDC4cTgUCkMbwgPDXoIfDikCiWBIw3ggOAidjI4ZFBiXCBoWgS4JHEoRZDBYMK4MKB4Q1BI4YDC4USsUKAoOjF4TrCAIcbkSNGoQZCeoODFYMboZRBB4LvBicjjeDCoMLoSBER4PhhWCV4StDJ4UbscSkQhBiXjjZJCLIsTsUBsBHDGoWChVhgUBhVBiPiLAnAhPgB4MJNoLJCQoJHBichTYWjAIJXBKIMCsMKkLHBjWDhOhOYJHFLocB8A0BhNhLYMLwJTBjUjiPChNBIwYFBjXjiXhiVha4RLB4ADBDYMCkEB4ABCLoQZBCoL9BjcjfoILBDIMD8AhCAISBBGoMR0USDIIbCEoMS0ZlBI4cBIINjhkCNIXiOIZzCZoODc4IBBSYQJBCYUT4cTgcA0DLBieCBYTXCAoMSwZHCwSJBV4JJBN4MST4Mga4ngY4MLoMbGYJrDW4QtC4RLBAIRDBE4INB0UKOYNggEhgFgiWiCYQPB8BPBhUCYoTRBokCwEbskJ4KzBhUia4j/B4cCsC3CgKlBAIXCKIQvCIIIvBjcidoJvCkMa8UBgMAdYPBjahCjbPB8MKGYQ3BjUDgPhjcEhUhiWhV4MJwTXCsDDCBYMCiVjhUBTIL7BKIIBBgVAhQ3B4BDCOoPjDoa5CB4MAhWCGYI3BEoMjkkSoQ3CoMSkZJBgPgNYITBhIPDoELwUDV4PBidjidDiXihXChWBF4IxCSYMCidihehhfAgfADIL7Ba4JBCwMCDYInBoTZCoDJDiNikXkiQpBoUZ8YNDM4MLsUD8EEgAvBGYI3CHIgNBAIYVBC4cL4T3BEYKZBjdjNYIBBCYYjBWII5DAAMJ0MawbjDAAnAjcje4MLSIPiGIJrBegMTOIPhB4IFEAIITBBYUCgMSAIKDBgKLC0ULsJFBWoMJ4I7GABgXBFYMMgIBBJILNBXYMT0JDBHoTpCLYQDD4USW4gnCI4NhhSzBkMSwcBR4wANhViI4aRDV4MKKYRDBBogBEJ4RdCf4sTgUTIYJpBoMRwRFTcocTsR7E0UCkELgQHCAJo5CI4lgI4MCoMasZPBADHgbIIxEwUCgELkQHC0BDHgYDB0IBBgPhNosa4cBkEA4BGZbIUiieiYYWjgPgTIwBKieCRIIjDZoMR4ZDbWYmAidCI41jA4RJBAI6nBBoNiV4I/fABMSwUb4RHDjejikCAJphBI9cBoETGINigUAhbfBapkL4UK4UJ4MKDAIAohOgjXjgUgheBhfAgY9B0IBBAoIHCAIOihVCiXCiXDI9JJCwMCgKPCI4YBIieCgPhicjjWEI9YABhUhY4I9C8JDEAoIBCdYJHCLwJGtI4NCikDikCAIsMAIUT8RDBCYMbwapBR+iRFRoeihVhhWhdYMS0RHtgUhgY1B0EDAIPAAoQDB4MToUCgELgMDA4MiR+sDR4Q9BBIUhgPgieCgYDBoRHwaYoBD8DPDa4IJBhkAiXjI91BifihkCifhAoMUgUMgMb4cKgMSsQNBhkhJ4JHugKNCIoIBCA4cbocBsEJ4MT0RVBgUBI9sJHoOhaIQDB4EDBIUSsITDjWjkcjgMgI9sB4BHEAIPgSoVihOhLYkBiNCItpHC0CLDAYMDI4OijXjHt5HKwET4cL8UTAIPjiciTYMI8BH4gES4ULkcS8USkUJ8AJBiTPwAA8KsUKsMCoECsMK0MTgUTsZH1hPhhdChaNB4MT0RBC4cKTINCgMgImGghPihdigfBgeggfAhehhXBgHAZ+qLCwULAYPCiaNBoTbBgNAIuoABiOiiQBB0LJBhUhgKLBAEgA=="));
|
||||||
|
|
||||||
|
function topLine() {
|
||||||
|
|
||||||
|
g.setColor(green);
|
||||||
|
g.setFontAlign(0, -1, 0);
|
||||||
|
|
||||||
|
g.moveTo(0, 50).lineTo(30, 50);
|
||||||
|
g.lineTo(30, 40);
|
||||||
|
g.lineTo(35, 40).moveTo(90, 40).lineTo(95, 40);
|
||||||
|
g.lineTo(95, 50);
|
||||||
|
g.lineTo(239, 50);
|
||||||
|
|
||||||
|
g.setFont("6x8", smallFont);
|
||||||
|
g.drawString("STAT", 65, 34);
|
||||||
|
g.drawString("INV", 130, 34);
|
||||||
|
g.drawString("DATA", 190, 34);
|
||||||
|
g.setColor(darkGreen);
|
||||||
|
g.drawString("STATUS", 45, 55);
|
||||||
|
g.drawString("SPEC", 122, 55);
|
||||||
|
g.drawString("PERKS", 195, 55);
|
||||||
|
}
|
||||||
|
|
||||||
|
function bottomLine() {
|
||||||
|
|
||||||
|
g.setColor(darkGreen);
|
||||||
|
g.fillRect(5, 175, 60, 185);
|
||||||
|
g.fillRect(67, 175, 140, 185);
|
||||||
|
|
||||||
|
g.setColor(darkerGreen);
|
||||||
|
g.fillRect(5, 190, 70, 200);
|
||||||
|
g.fillRect(75, 190, 239, 200);
|
||||||
|
|
||||||
|
g.setFont("6x8", tinyFont);
|
||||||
|
g.drawString("STIM (0)", 32, 177);
|
||||||
|
g.drawString("RADAWAY (0)", 105, 177);
|
||||||
|
g.setColor(green);
|
||||||
|
g.drawString("HP 115/115", 38, 192);
|
||||||
|
g.drawString("LEVEL 6", 100, 192);
|
||||||
|
g.drawRect(127, 192, 235, 198);
|
||||||
|
}
|
||||||
|
|
||||||
|
function boy() {
|
||||||
|
g.drawImage(pip, 165, 85);
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawClock() {
|
||||||
|
|
||||||
|
var t = new Date();
|
||||||
|
var h = t.getHours();
|
||||||
|
var m = t.getMinutes();
|
||||||
|
var time = ("0" + h).substr(-2) + ":" + ("0" + m).substr(-2);
|
||||||
|
|
||||||
|
g.setFont("6x8",bigFont);
|
||||||
|
g.setColor(green);
|
||||||
|
g.setFontAlign(0, -1, 0);
|
||||||
|
|
||||||
|
g.clearRect(0, 110, 150, 140);
|
||||||
|
g.drawString(time, 70, 110);
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawAll() {
|
||||||
|
topLine();
|
||||||
|
boy();
|
||||||
|
bottomLine();
|
||||||
|
drawClock();
|
||||||
|
}
|
||||||
|
|
||||||
|
Bangle.on('lcdPower', function(on) {
|
||||||
|
if (on) drawAll();
|
||||||
|
});
|
||||||
|
|
||||||
|
g.clear();
|
||||||
|
Bangle.loadWidgets();
|
||||||
|
Bangle.drawWidgets();
|
||||||
|
setInterval(drawClock, 1E4);
|
||||||
|
drawAll();
|
||||||
|
|
||||||
|
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||||
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Pomodoro","type":"app",
|
|
||||||
"icon":"*pomodo",
|
|
||||||
"src":"-pomodo"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Party Parrot","type":"app",
|
|
||||||
"icon":"*pparrot",
|
|
||||||
"src":"-pparrot"
|
|
||||||
}
|
|
||||||
|
|
@ -41,19 +41,11 @@ g.setColor(0,0,0);
|
||||||
g.drawString(url,120,230);
|
g.drawString(url,120,230);
|
||||||
g.setColor(1,1,1);
|
g.setColor(1,1,1);
|
||||||
`;
|
`;
|
||||||
var json = JSON.stringify({
|
|
||||||
name:"QR Code",
|
|
||||||
icon:"*qrcode",
|
|
||||||
src:"-qrcode"
|
|
||||||
});
|
|
||||||
var icon = `require("heatshrink").decompress(atob("mEwgP/AEX8gE8nkAn4FSngCWF6xfYDgIABHAQFPDQXD4YgDApxNDMooFOAQIdDAqIvWfcYA="))`;
|
var icon = `require("heatshrink").decompress(atob("mEwgP/AEX8gE8nkAn4FSngCWF6xfYDgIABHAQFPDQXD4YgDApxNDMooFOAQIdDAqIvWfcYA="))`;
|
||||||
sendCustomizedApp({
|
sendCustomizedApp({
|
||||||
id : "qrcode",
|
|
||||||
|
|
||||||
storage:[
|
storage:[
|
||||||
{name:"-qrcode", content:app},
|
{name:"qrcode.app.js", content:app},
|
||||||
{name:"+qrcode", content:json},
|
{name:"qrcode.img", content:icon, evaluate:true},
|
||||||
{name:"*qrcode", content:icon, evaluate:true},
|
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -240,20 +240,12 @@ Bangle.setGPSPower(1);
|
||||||
Bangle.setCompassPower(1);
|
Bangle.setCompassPower(1);
|
||||||
g.clear();
|
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=="))`;
|
var icon = `require("heatshrink").decompress(atob("mEwgIkhvgFE/wEDgOHAocDgYFEgOAAp4XEEYsB4w1E5hBKnByFKw8/AQNAAQP/4EAAIMB4HggBABHoNwCwUGE4kOgEYBAMAhk+hgIBAoM/hkEAoMIv8MC4QFChARCAoIMCDoQXChkcjA1EAoJBBg5dCJoJHDKYWAsCGD4AJBAAXBDYIlCsYFBGwUzPok+AokcsOOmIUCAogAWA=="))`;
|
||||||
|
|
||||||
sendCustomizedApp({
|
sendCustomizedApp({
|
||||||
id : "route",
|
|
||||||
|
|
||||||
storage:[
|
storage:[
|
||||||
{name:"-route", content:app},
|
{name:"route.app.js", content:app},
|
||||||
{name:"+route", content:json},
|
{name:"route.img", content:icon, evaluate:true},
|
||||||
{name:"*route", content:icon, evaluate:true},
|
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Battery Level","type":"widget",
|
|
||||||
"src":"=sbat"
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"name":"bluetooth","type":"widget",
|
|
||||||
"src":"=sbt"
|
|
||||||
}
|
|
||||||
|
|
@ -11,7 +11,7 @@ const yposYear = 175;
|
||||||
const yposGMT = 220;
|
const yposGMT = 220;
|
||||||
|
|
||||||
// Check settings for what type our clock should be
|
// 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() {
|
function drawSimpleClock() {
|
||||||
// get date
|
// get date
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Simple Clock",
|
|
||||||
"type":"clock",
|
|
||||||
"icon":"*sclock",
|
|
||||||
"src":"-sclock",
|
|
||||||
"sortorder":-10
|
|
||||||
}
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
require("heatshrink").decompress(atob("mEwxH+64A/AH4A/AH4AllYADqAADugAD4QAD5wADxgADnwADF/4v/F/4vMFQg0EFScyAAYv/F/4v/F5l0AAYqEGggqOlgADF/4v/F/4vMFQnOAAYqEGggqJmgADF/4v/F/4vMFRM+AAYqEGggqEnYADF/4v/F/4vMFR0sAAYqEGglrAAYv/F/4v/F5gqTnYADFQg0EF/4v/F/4vMAH4A/AH4A/AH4AIA"));
|
require("heatshrink").decompress(atob("mEwxH+64A/AH4A/AH4AllYADqAADugAD4QAD5wADxgADnwADF/4v/F/4vMFQg0EFScyAAYv/F/4v/F5l0AAYqEGggqOlgADF/4v/F/4vMFQnOAAYqEGggqJmgADF/4v/F/4vMFRM+AAYqEGggqEnYADF/4v/F/4vMFR0sAAYqEGglrAAYv/F/4v/F5gqTnYADFQg0EF/4v/F/4vMAH4A/AH4A/AH4AIA"))
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Show Color","type":"app",
|
|
||||||
"icon":"*scolor",
|
|
||||||
"src":"-scolor"
|
|
||||||
}
|
|
||||||
|
|
@ -1,2 +1,4 @@
|
||||||
0.02: Add support for 30-minute timezones.
|
0.02: Add support for 30-minute timezones.
|
||||||
0.03: Add support for Welcome app
|
0.03: Add support for Welcome app
|
||||||
|
0.04: Add setting to disable log messages
|
||||||
|
0.05: Fix Settings json
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
ble: true, // Bluetooth enabled by default
|
ble: true, // Bluetooth enabled by default
|
||||||
dev: true, // Is REPL on Bluetooth - can Espruino IDE be used?
|
blerepl: true, // Is REPL on Bluetooth - can Espruino IDE be used?
|
||||||
|
log: false, // Do log messages appear on screen?
|
||||||
timeout: 10, // Default LCD timeout in seconds
|
timeout: 10, // Default LCD timeout in seconds
|
||||||
vibrate: true, // Vibration enabled by default. App must support
|
vibrate: true, // Vibration enabled by default. App must support
|
||||||
beep: true, // Beep enabled by default. App must support
|
beep: true, // Beep enabled by default. App must support
|
||||||
|
|
@ -9,4 +10,5 @@
|
||||||
clock: null, // a string for the default clock's name
|
clock: null, // a string for the default clock's name
|
||||||
"12hour" : false, // 12 or 24 hour clock?
|
"12hour" : false, // 12 or 24 hour clock?
|
||||||
distance : "kilometer" // or "mile"
|
distance : "kilometer" // or "mile"
|
||||||
|
// welcomed : undefined/true (whether welcome app should show)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,34 +5,34 @@ const storage = require('Storage');
|
||||||
let settings;
|
let settings;
|
||||||
|
|
||||||
function updateSettings() {
|
function updateSettings() {
|
||||||
//storage.erase('@setting'); // - not needed, just causes extra writes if settings were the same
|
//storage.erase('setting.json'); // - not needed, just causes extra writes if settings were the same
|
||||||
storage.write('@setting', settings);
|
storage.write('setting.json', settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetSettings() {
|
function resetSettings() {
|
||||||
settings = {
|
settings = {
|
||||||
ble: true,
|
ble: true, // Bluetooth enabled by default
|
||||||
dev: true,
|
blerepl: true, // Is REPL on Bluetooth - can Espruino IDE be used?
|
||||||
timeout: 10,
|
log: false, // Do log messages appear on screen?
|
||||||
vibrate: true,
|
timeout: 10, // Default LCD timeout in seconds
|
||||||
beep: true,
|
vibrate: true, // Vibration enabled by default. App must support
|
||||||
timezone: 0,
|
beep: true, // Beep enabled by default. App must support
|
||||||
HID : false,
|
timezone: 0, // Set the timezone for the device
|
||||||
clock: null,
|
HID : false, // BLE HID mode, off by default
|
||||||
"12hour" : false,
|
clock: null, // a string for the default clock's name
|
||||||
|
"12hour" : false, // 12 or 24 hour clock?
|
||||||
distance : "kilometer" // or "mile"
|
distance : "kilometer" // or "mile"
|
||||||
// welcomed : undefined/true (whether welcome app should show)
|
// welcomed : undefined/true (whether welcome app should show)
|
||||||
};
|
};
|
||||||
Bangle.setLCDTimeout(settings.timeout);
|
|
||||||
updateSettings();
|
updateSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
settings = storage.readJSON('@setting');
|
settings = storage.readJSON('setting.json');
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
if (!settings) resetSettings();
|
if (!settings) resetSettings();
|
||||||
|
|
||||||
const boolFormat = (v) => v ? "On" : "Off";
|
const boolFormat = v => v ? "On" : "Off";
|
||||||
|
|
||||||
function showMainMenu() {
|
function showMainMenu() {
|
||||||
const mainmenu = {
|
const mainmenu = {
|
||||||
|
|
@ -47,10 +47,18 @@ function showMainMenu() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'Programmable': {
|
'Programmable': {
|
||||||
value: settings.dev,
|
value: settings.blerepl,
|
||||||
format: boolFormat,
|
format: boolFormat,
|
||||||
onchange: () => {
|
onchange: () => {
|
||||||
settings.dev = !settings.dev;
|
settings.blerepl = !settings.blerepl;
|
||||||
|
updateSettings();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'Debug info': {
|
||||||
|
value: settings.log,
|
||||||
|
format: v => v ? "Show" : "Hide",
|
||||||
|
onchange: () => {
|
||||||
|
settings.log = !settings.log;
|
||||||
updateSettings();
|
updateSettings();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -179,7 +187,7 @@ function makeConnectable() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function showClockMenu() {
|
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); }
|
try { return require("Storage").readJSON(app); }
|
||||||
catch (e) {}
|
catch (e) {}
|
||||||
}).filter(app=>app.type=="clock").sort((a, b) => a.sortorder - b.sortorder);
|
}).filter(app=>app.type=="clock").sort((a, b) => a.sortorder - b.sortorder);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"name": "Settings","type":"app",
|
|
||||||
"icon": "*settings",
|
|
||||||
"src": "-settings",
|
|
||||||
"sortorder": -15
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Spirit Level","type":"app",
|
|
||||||
"icon":"*slevel",
|
|
||||||
"src":"-slevel"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Speedo","type":"app",
|
|
||||||
"icon":"*speedo",
|
|
||||||
"src":"-speedo"
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
{
|
|
||||||
"name":"Stethoscope","type":"app",
|
|
||||||
"icon":"*stetho",
|
|
||||||
"src":"-stetho"
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue