diff --git a/README.md b/README.md index 1283f44..1659445 100755 --- a/README.md +++ b/README.md @@ -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 diff --git a/dev/custom-fn.js b/dev/custom-fn.js index 259bc60..fe004aa 100644 --- a/dev/custom-fn.js +++ b/dev/custom-fn.js @@ -21,4 +21,6 @@ module.exports = function() { toggleBackground.call(coolStuffToggle); coolStuffToggle.on('change', toggleBackground); }); + + console.log('userData: ', Clay.meta.userData); }; diff --git a/dev/dev.js b/dev/dev.js index bee8be2..72cccee 100644 --- a/dev/dev.js +++ b/dev/dev.js @@ -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); diff --git a/index.js b/index.js index e7402ff..ebb939b 100755 --- a/index.js +++ b/index.js @@ -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 diff --git a/test/fixture.js b/test/fixture.js index 9eac5d2..088a73c 100644 --- a/test/fixture.js +++ b/test/fixture.js @@ -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} */ diff --git a/test/spec/index.js b/test/spec/index.js index 7dcf8dd..60c6a76 100644 --- a/test/spec/index.js +++ b/test/spec/index.js @@ -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',