Add developers to send arbitrary data to the config page

This commit is contained in:
Keegan
2016-03-11 03:36:00 +11:00
parent b1a6f184ba
commit e5496c62d6
6 changed files with 77 additions and 51 deletions
+23 -1
View File
@@ -609,6 +609,16 @@ Pebble.addEventListener('webviewclosed', function(e) {
### `Clay([Array] config, [function] customFn, [object] options)`
#### Constructor Parameters
| Parameter | Type | Description |
|----------|-------|-------------|
| `config` | Array | The config that will be used to generate the configuration page |
| `customFn` | Function\|null | (Optional) The [custom function](#custom-function) to be injected into the generated configuration page. |
| `options` | Object | (Optional) See below for properties |
| `options.autoHandleEvents` | Boolean | (Optional) Defaults to `true`. If set to `false`, Clay will not [auto handle the `showConfiguration` and `webviewclosed` events](#handling-the-showconfiguration-and-webviewclosed-events-manually) |
| `options.userData` | Any | (Optional) Any arbitrary data you want to pass to your config page. It will be available in your custom function as `this.meta.userData` |
#### Properties
| Property | Type | Description |
@@ -619,6 +629,7 @@ Pebble.addEventListener('webviewclosed', function(e) {
| `.meta.activeWatchInfo` | watchinfo\|null | An object containing information on the currently connected Pebble smartwatch or null if unavailable. Read more [here](https://developer.pebble.com/docs/js/Pebble/#getActiveWatchInfo). |
| `.meta.accountToken` | String | A unique account token that is associated with the Pebble account of the current user. Read more [here](https://developer.pebble.com/docs/js/Pebble/#getAccountToken). |
| `.meta.watchToken` | String | A unique token that can be used to identify a Pebble device. Read more [here](https://developer.pebble.com/docs/js/Pebble/#getWatchToken). |
| `.meta.userData` | Any | A deep copy of the arbitrary data provided in the `options.userData`. Defaults to an empty object |
#### Methods
@@ -650,7 +661,8 @@ Make sure to always wait for the config page to be built before manipulating ite
var Clay = require('./clay');
var clayConfig = require('./config');
var customClay = require('./custom-clay');
var clay = new Clay(clayConfig, customClay);
var userData = {token: 'abc123'}
var clay = new Clay(clayConfig, customClay, {userData: userData});
```
##### custom-clay.js
@@ -679,6 +691,15 @@ module.exports = function(minified) {
if (!clayConfig.meta.activeWatchInfo || clayConfig.meta.activeWatchInfo.platform === 'aplite') {
clayConfig.getItemByAppKey('background').hide();
}
// Set the value of an item based on the userData
$.request('get', 'https://some.cool/api', {token: clayConfig.meta.userData.token})
.then(function(result) {
// Do something interesting with the data from the server
})
.error(function(status, statusText, responseText) {
// Handle the error
});
});
};
@@ -701,6 +722,7 @@ This is the main way of talking to your generated config page. An instance of th
| `.meta.activeWatchInfo` | watchinfo\|null | An object containing information on the currently connected Pebble smartwatch or null if unavailable. Read more [here](https://developer.pebble.com/docs/js/Pebble/#getActiveWatchInfo). |
| `.meta.accountToken` | String | A unique account token that is associated with the Pebble account of the current user. Read more [here](https://developer.pebble.com/docs/js/Pebble/#getAccountToken). |
| `.meta.watchToken` | String | A unique token that can be used to identify a Pebble device. Read more [here](https://developer.pebble.com/docs/js/Pebble/#getWatchToken). |
| `.meta.userData` | Any | The data passed in the `options.userData` of the [Clay constructor.](#clayarray-config-function-customfn-object-options) |
#### Methods
+2
View File
@@ -21,4 +21,6 @@ module.exports = function() {
toggleBackground.call(coolStuffToggle);
coolStuffToggle.on('change', toggleBackground);
});
console.log('userData: ', Clay.meta.userData);
};
+3
View File
@@ -5,6 +5,9 @@ window.clayConfig = require('./config.js');
window.claySettings = {};
window.customFn = require('./custom-fn.js');
window.clayComponents = require('../src/scripts/components');
window.clayMeta = require('../test/fixture').meta({
userData: {foo: 'bar'}
});
var platform = window.navigator.userAgent.match(/Android/) ? 'android' : 'ios';
document.documentElement.classList.add('platform-' + platform);
+19 -15
View File
@@ -11,8 +11,10 @@ var deepcopy = require('deepcopy/build/deepcopy.min');
* @param {function} [customFn] - Custom code to run from the config page. Will run
* with the ClayConfig instance as context
* @param {Object} [options] - Additional options to pass to Clay
* @param {boolean} [options.autoHandleEvents] - If false, Clay will not
* @param {boolean} [options.autoHandleEvents=true] - If false, Clay will not
* automatically handle the 'showConfiguration' and 'webviewclosed' events
* @param {*} [options.userData={}] - Arbitrary data to pass to the config page. Will
* be available os `clayConfig.meta.userData`
* @constructor
*/
function Clay(config, customFn, options) {
@@ -34,9 +36,24 @@ function Clay(config, customFn, options) {
self.meta = {
activeWatchInfo: null,
accountToken: '',
watchToken: ''
watchToken: '',
userData: {}
};
/**
* Populate the meta with data from the Pebble object. Make sure to run this inside
* either the "showConfiguration" or "ready" event handler
* @return {void}
*/
function _populateMeta() {
self.meta = {
activeWatchInfo: Pebble.getActiveWatchInfo && Pebble.getActiveWatchInfo(),
accountToken: Pebble.getAccountToken(),
watchToken: Pebble.getWatchToken(),
userData: deepcopy(options.userData || {})
};
}
// Let Clay handle all the magic
if (options.autoHandleEvents !== false && typeof Pebble !== 'undefined') {
@@ -63,19 +80,6 @@ function Clay(config, customFn, options) {
});
}
/**
* Populate the meta with data from the Pebble object. Make sure to run this inside
* either the "showConfiguration" or "ready" event handler
* @return {void}
*/
function _populateMeta() {
self.meta = {
activeWatchInfo: Pebble.getActiveWatchInfo && Pebble.getActiveWatchInfo(),
accountToken: Pebble.getAccountToken(),
watchToken: Pebble.getWatchToken()
};
}
/**
* @private
* @param {Clay~ConfigItem|Array} item
+14 -4
View File
@@ -11,12 +11,13 @@ var componentRegistry = require('../src/scripts/lib/component-registry');
var idCounter = 0;
/**
* @param {Object} [extra] - add/replace keys in the meta
* @returns {{accountToken: string, watchToken: string, activeWatchInfo: {platform:
* string, model: string, language: string, firmware: {major: number, minor:
* number, patch: number, suffix: string}}}}
* number, patch: number, suffix: string}}, userData: {}}}
*/
module.exports.meta = function() {
return {
module.exports.meta = function(extra) {
var result = {
accountToken: '0123456789abcdef0123456789abcdef',
watchToken: '0123456789abcdef0123456789abcdef',
activeWatchInfo: {
@@ -29,8 +30,15 @@ module.exports.meta = function() {
patch: 2,
suffix: ''
}
}
},
userData: {}
};
_.eachObj(extra || {}, function(key, val) {
result[key] = val;
});
return result;
};
/**
@@ -106,6 +114,8 @@ module.exports.clayConfig = function(types, build, autoRegister, settings) {
* @param {Object} [options] - Additional options to pass to Clay
* @param {boolean} [options.autoHandleEvents] - If false, Clay will not
* automatically handle the 'showConfiguration' and 'webviewclosed' events
* @param {*} [options.userData={}] - Arbitrary data to pass to the config page. Will
* be available os `clayConfig.meta.userData`
* @param {boolean} [destroyLocalStorage=true]
* @return {Clay}
*/
+16 -31
View File
@@ -7,31 +7,19 @@ var standardComponents = require('../../src/scripts/components');
var sinon = require('sinon');
var toSource = require('tosource');
var accountToken = '0123456789abcdef0123456789abcdef';
var watchToken = '0123456789abcdef0123456789abcdef';
var activeWatchInfo = {
platform: 'chalk',
model: 'qemu_platform_chalk',
language: 'en_US',
firmware: {
major: 3,
minor: 3,
patch: 2,
suffix: ''
}
};
/**
* @return {void}
*/
function stubPebble() {
var meta = fixture.meta();
global.Pebble = {
addEventListener: sinon.stub(),
openURL: sinon.stub(),
sendAppMessage: sinon.stub(),
getActiveWatchInfo: sinon.stub().returns(activeWatchInfo),
getAccountToken: sinon.stub().returns(accountToken),
getWatchToken: sinon.stub().returns(watchToken)
getActiveWatchInfo: sinon.stub().returns(meta.activeWatchInfo),
getAccountToken: sinon.stub().returns(meta.accountToken),
getWatchToken: sinon.stub().returns(meta.watchToken)
};
}
@@ -310,37 +298,34 @@ describe('Clay', function() {
var emptyMeta = {
activeWatchInfo: null,
accountToken: '',
watchToken: ''
watchToken: '',
userData: {}
};
it('populates the meta in the showConfiguration handler', function() {
stubPebble();
var clay = fixture.clay([]);
var userData = {foo: 'bar'};
var clay = fixture.clay([], null, {userData: userData});
// meta only gets populated after showConfiguration happens
assert.deepEqual(clay.meta, emptyMeta);
Pebble.addEventListener.withArgs('showConfiguration').callArg(1);
assert.deepEqual(clay.meta, {
activeWatchInfo: activeWatchInfo,
accountToken: accountToken,
watchToken: watchToken
});
assert.deepEqual(clay.meta, fixture.meta({userData: userData}));
});
it('populates the meta in the ready handler', function() {
stubPebble();
var clay = fixture.clay([], null, {autoHandleEvents: false});
var userData = {foo: 'bar'};
var clay = fixture.clay([], null, {
autoHandleEvents: false,
userData: userData
});
// meta only gets populated after ready happens
assert.deepEqual(clay.meta, emptyMeta);
Pebble.addEventListener.withArgs('ready').callArg(1);
assert.deepEqual(clay.meta, {
activeWatchInfo: activeWatchInfo,
accountToken: accountToken,
watchToken: watchToken
});
assert.deepEqual(clay.meta, fixture.meta({userData: userData}));
});
it('populates the meta with with empty values when there is no Pebble global',