If you've made an app, often you may want to provide some options to allow
it to be customised. While you can use E.showMenu
to add an options screen
inside your app, Bangle.js provides a way to add extra menus to the
global Settings
application.
First, check out the tutorial on adding an app to the Bangle.js App Loader
as it'll help you to understand about metadata.json
.
First off, you need to store your settings in a file. Apps in Bangle.js generally
use either "myapp.json"
or "myapp.settings.json"
as the filename, where myapp
is your app's ID. We're using "myapp.json"
here (which what we would suggest).
In the app itself, you can read settings using code like this:
var settings = Object.assign({
// default values
something: 123,
anotherthing: 456,
}, require('Storage').readJSON("myapp.json", true) || {});
If you don't set defaults, your code needs to be able to handle missing items:
// read settings file, or if it doesn't exist use {}
var settings = require('Storage').readJSON("myapp.json", true) || {};
// Use the setting, or a default value if undefined
var value = settings.something!==undefined ? settings.something : 123;
// Or a cleaner version when you know a value of '0' isn't valid:
var value = settings.something || 123;
It's important to think about both memory usage and speed:
var settings = require('Storage').readJSON("myapp.json", true) || {};
var value = settings.something || 123;
delete settings; // remove unneeded settings from memory
Note: You should never depend upon a settings file being present, or even having some field, so defaults are a good idea. Someone may have deleted it or upgraded from an older version of your app.
When you're loading settings inside your app, you can manually write:
require('Storage').writeJSON("myapp.json", {
something : 123
});
To set up some settings. You can enter this at the console and then reload your app to check then take effect.
It's also important to check your app works with no settings file
using require('Storage').erase("myapp.json")
. It's very easy to create
an app that works for you, submit it to the app store and find nobody
else can use it because they don't have a settings file.
Now, develop your setting page. In the Web IDE, upload to RAM and start with the following:
(function(back) {
var FILE = "myapp.json";
// Load settings
var settings = Object.assign({
something: 123,
}, require('Storage').readJSON(FILE, true) || {});
function writeSettings() {
require('Storage').writeJSON(FILE, settings);
}
// Show the menu
E.showMenu({
"" : { "title" : "App Name" },
"< Back" : () => back(),
'On or off?': {
value: !!settings.onoroff, // !! converts undefined to false
onchange: v => {
settings.onoroff = v;
writeSettings();
}
// format: ... may be specified as a function which converts the value to a string
// if the value is a boolean, showMenu() will convert this automatically, which
// keeps settings menus consistent
},
'How Many?': {
value: 0|settings.howmany, // 0| converts undefined to 0
min: 0, max: 10,
onchange: v => {
settings.howmany = v;
writeSettings();
}
},
});
})(load)
It's pretty easy to add different options - check out the E.showMenu
docs for more ideas.
This is great for testing, however to create a settings app, you must remove the
(load)
from the end of the code, so it should look like this:
(function(back) {
var FILE = "myapp.json";
// Load settings
var settings = Object.assign({
something: 123,
}, require('Storage').readJSON(FILE, true) || {});
function writeSettings() {
require('Storage').writeJSON(FILE, settings);
}
// Show the menu
E.showMenu({
"" : { "title" : "App Name" },
"< Back" : () => back(),
'On or off?': {
value: !!settings.onoroff, // !! converts undefined to false
onchange: v => {
settings.onoroff = v;
writeSettings();
}
},
'How Many?': {
value: 0|settings.howmany, // 0| converts undefined to 0
min: 0, max: 10,
onchange: v => {
settings.howmany = v;
writeSettings();
}
},
});
})
Save the file to myapp.settings.js
on the Bangle's
storage. If the app JSON is set up, you should now be able to access the
settings by going to Settings
-> App/Widget Settings
and your App's Name.
settings.js
in your app's
folder in the App Loader.myapp.settings.js
and myapp.json
to metadata.json
Assuming this is your app, add the lines marked:
{
"id": "myapp",
"name": "My App",
"version": "0.01",
"description": "...",
"icon": "app.png",
"tags": "...",
"supports": ["BANGLEJS","BANGLEJS2"],
"storage": [
{"name":"myapp.app.js","url":"app.js"},
{"name":"myapp.settings.js","url":"settings.js"}, // < ------- HERE
{"name":"myapp.img","url":"app-icon.js","evaluate":true},
],
"data": [{"name":"myapp.json"}] // < ------- HERE
}
And you're finished!
Sometimes you may want settings for a Widget, and that widget may be running in the background while the settings page is active. In that case we'd suggest:
reload
to your Widget that reloads the settings and redrawsif (WIDGETS["myapp"]) WIDGETS["myapp"].reload()
at the
end of your writeSettings
function.Sometimes you may want to enter the settings menu direct from your app. If you do, you can use this code:
eval(require("Storage").read("myapp.settings.js"))(()=>load());
You should replace the call to load()
with a function that displays the
main menu of your app, or going < Back
from settings will go back
to the clock.
This page is auto-generated from GitHub. If you see any mistakes or have suggestions, please let us know.