🏴☠️ A dead simple module to assist managing and persisting user settings within Fitbit watch faces, applications, and companion.
fitbit-settings
is designed to be a plug-and-play approach to help manage essential aspects of the user's settings within your watch faces and applications.
It includes the the following goodies:
- Persisting and retrieving of stored settings (device storage)
- Migration of stored settings upon changes to default settings
- Best-effort bi-directional syncing between companion and device for offline changes, device driven changes, and
settingsStorage
changes - Automatically cast strings to associated types (i.e: "true" -> true)
- Event handlers for companion changes
- Chain-able methods for state management
This is intended to be be simple, light, and flat by nature. Thus, it doesn't handle nested settings, so be warned, matey.
Note: This module is designed to only works for Fitbit OS (JerryScript) and still in alpha for some potential bugs.
$ npm install --save fitbit-settings
On initializing
- The device will update it's state by retrieve any pre-existing settings stored on the device and migrate any new setting properties found in the default settings.
On listening
- The device will sync the companion with it's current settings
- The companion will parse the differences and notify the device of the changes that may have occurred when disconnected
- The device will update the properties with the missing changes and save them to the device
- The device will listen for changes done within the settings app or
settingsStorage
and automatically update the settings stored in the device - If the
syncWithCompanion
option is set, the device will persist any changes through the.update()
method to the companion, the companion will then update thesettingsStorage
It's recommended to keep things as flat as possible, and prefix properties if need be (i.e color_background
, display_battery
). This will keep the settings lean and prevent unexpected overrides of settings upon reboots and migrations.
import FsSettings from 'fitbit-settings/app';
const defaultSettings = {
color_background: '#000',
color_label: '#fff',
hide_battery: false,
tap_disable: true,
color_hour: '#000cec9',
color_minute: '#fff',
color_battery: '#fff'
});
const appSettings = new FsSettings(defaultSettings);
// Update settings (color_battery, color_hour)
// Persist to Device Disk
appSettings
.update('color_battery', 'red')
.update('color_hour', 'yellow')
.save();
// Reset to default settings
// Persist to disk
appSettings.reset().save();
// Set style based on settings
document.getElementById('battery').style.fill = appSettings.getProp('color_battery');
Make sure to utilize the same defaults across a common export to act as a source of truth.
Common Files: `/common/default-settings.js
export const defaultSettings = {
color_background: '#000',
color_label: '#fff',
hide_battery: false,
tap_disable: true,
color_hour: '#000cec9',
color_minute: '#fff',
color_battery: '#fff'
});
Initialize with default settings within a singleton to use across different files and activate the listen
method.
App File: /app/settings.js
import FsSettings from 'fitbit-settings/app';
import defaultSettings from './common/defaultSettings';
const appSettings = new FsSettings(defaultSettings, {
// set to true if you want to allow your watch face UI to make changes to the settings
syncWithCompanion: true,
callListenersOnInit: true
};
// Register event handlers that will get called every time this changes from the companion as well as called upon when the watchface initially loads
appSettings.onPropChange('color_background',
(event) => setBackgroundColor(event.data.value));
appSettings.onPropChange('color_hour', event => setHourColor(event.data.value));
// Update and sync changes with companion if connection exists
appSettings.listen();
// Update the settings based on events in the UI,
// but also update the companion settings
if (userClickedElement) {
appSettings.update('tap_disable', false);
}
Companion File
import defaultSettings from './common/defaultSettings';
const companionSettings = new FsSettings(defaultSettings);
companionSettings.listen();
Type: class
Usage: new FsSettings(defaultSettings, options)
Type: object
Default settings for the application / watch face
Type: object
Type: string
Override the default file path ('settings.cbor').
Type: boolean
Allow updates to notify the companion / setting storage. This is typically for when you may allow the user to update the settings within the watch face.
Type: boolean
Upon calling listen()
, fitbit-settings will also call all .onPropChange
listeners with its current values. This is useful for watchfaces with listeners that need to be called on initialization.
Returns: instance
Activate listeners to watch for changes in the companion, this requires the settings to also be listening in the companion side.
Returns: instance
Register callbacks for companion changes that occur when listening. Limited to 1 callback per a propName.
Returns: Value of prop stored in memory state
Type: string
Prop of setting to retrieve IE: 'color_battery'
Returns: instance
Updates the current setting state within the app. If no prop currently exists, this will create a new one. In addition, syncWithCompanion will notify the companion of this update.
Type: string
Type: any
Returns class instance
Persist existing setting state to watch disk.
Returns class instance
Reset internal setting state back to default settings
Type: class
Usage: new FsSettings(defaultSettings)
Activate listeners to watch for notifications from the device and notify the device for property changes in the settings storage / settings app.
All files are written within the src
directory and compiled to to ES5 to support the Fitbit JavaScript runtime. Once the files are built, these are outputted to the project's root directory. In order to build these files, run npm run build
.
Prior to publishing or submitting a pull request, it's best to include some test/spec files. The test suite uses Jest, and can the suite can be executed with npm run test
.
If you need any help, feel free to submit an issue.
fitbit-settings
is currently being used in these production watch faces and applications:
If you are using,
fitbit-settings
, feel free to add your studio by submitting a GitHub issue
MIT © Brandon Him