mirror of
https://github.com/pebble-dev/clay.git
synced 2026-08-28 04:46:57 -04:00
Merge pull request #50 from pebble/#20/allow-user-data
#20/allow user data
This commit is contained in:
@@ -609,16 +609,27 @@ Pebble.addEventListener('webviewclosed', function(e) {
|
|||||||
|
|
||||||
### `Clay([Array] config, [function] customFn, [object] options)`
|
### `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
|
#### Properties
|
||||||
|
|
||||||
| Property | Type | Description |
|
| Property | Type | Description |
|
||||||
|----------|------|-------------|
|
|----------|------|-------------|
|
||||||
| `.config` | Array | Reference to the config passed to the constructor and used for generating the page. **WARNING** this is a direct reference, not a copy of the config so any modification you make to it, will be reflected on the original as well |
|
| `.config` | Array | Copy of the config passed to the constructor and used for generating the page. |
|
||||||
| `.customFn` | Function | Reference to the custom function passed to the constructor. **WARNING** this is a direct reference, not a copy of the custom function so any modification you make to it, will be reflected on the original as well |
|
| `.customFn` | Function | Reference to the custom function passed to the constructor. **WARNING** this is a direct reference, not a copy of the custom function so any modification you make to it, will be reflected on the original as well |
|
||||||
| `.meta` | Object | Contains information about the current user and watch. **WARNING** This will only be populated in the `showConfiguration` event handler. (See example above) |
|
| `.meta` | Object | Contains information about the current user and watch. **WARNING** This will only be populated in the `showConfiguration` event handler. (See example above) |
|
||||||
| `.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.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.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.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
|
#### 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 Clay = require('./clay');
|
||||||
var clayConfig = require('./config');
|
var clayConfig = require('./config');
|
||||||
var customClay = require('./custom-clay');
|
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
|
##### custom-clay.js
|
||||||
@@ -679,6 +691,15 @@ module.exports = function(minified) {
|
|||||||
if (!clayConfig.meta.activeWatchInfo || clayConfig.meta.activeWatchInfo.platform === 'aplite') {
|
if (!clayConfig.meta.activeWatchInfo || clayConfig.meta.activeWatchInfo.platform === 'aplite') {
|
||||||
clayConfig.getItemByAppKey('background').hide();
|
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.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.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.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
|
#### Methods
|
||||||
|
|||||||
@@ -21,4 +21,6 @@ module.exports = function() {
|
|||||||
toggleBackground.call(coolStuffToggle);
|
toggleBackground.call(coolStuffToggle);
|
||||||
coolStuffToggle.on('change', toggleBackground);
|
coolStuffToggle.on('change', toggleBackground);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log('userData: ', Clay.meta.userData);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ window.clayConfig = require('./config.js');
|
|||||||
window.claySettings = {};
|
window.claySettings = {};
|
||||||
window.customFn = require('./custom-fn.js');
|
window.customFn = require('./custom-fn.js');
|
||||||
window.clayComponents = require('../src/scripts/components');
|
window.clayComponents = require('../src/scripts/components');
|
||||||
|
window.clayMeta = require('../test/fixture').meta({
|
||||||
|
userData: {foo: 'bar'}
|
||||||
|
});
|
||||||
|
|
||||||
var platform = window.navigator.userAgent.match(/Android/) ? 'android' : 'ios';
|
var platform = window.navigator.userAgent.match(/Android/) ? 'android' : 'ios';
|
||||||
document.documentElement.classList.add('platform-' + platform);
|
document.documentElement.classList.add('platform-' + platform);
|
||||||
|
|||||||
+3
-1
@@ -94,7 +94,9 @@ gulp.task('clay', ['inlineHtml'], function() {
|
|||||||
.bundle()
|
.bundle()
|
||||||
.pipe(source('clay.js'))
|
.pipe(source('clay.js'))
|
||||||
.pipe(buffer())
|
.pipe(buffer())
|
||||||
.pipe(uglify())
|
.pipe(uglify({
|
||||||
|
preserveComments: 'license'
|
||||||
|
}))
|
||||||
.pipe(insert.prepend(versionMessage))
|
.pipe(insert.prepend(versionMessage))
|
||||||
.pipe(gulp.dest('./dist/'));
|
.pipe(gulp.dest('./dist/'));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,14 +4,17 @@ var configPageHtml = require('./tmp/config-page.html');
|
|||||||
var toSource = require('tosource');
|
var toSource = require('tosource');
|
||||||
var standardComponents = require('./src/scripts/components');
|
var standardComponents = require('./src/scripts/components');
|
||||||
var utils = require('./src/scripts/lib/utils');
|
var utils = require('./src/scripts/lib/utils');
|
||||||
|
var deepcopy = require('deepcopy/build/deepcopy.min');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Array} config - the Clay config
|
* @param {Array} config - the Clay config
|
||||||
* @param {function} [customFn] - Custom code to run from the config page. Will run
|
* @param {function} [customFn] - Custom code to run from the config page. Will run
|
||||||
* with the ClayConfig instance as context
|
* with the ClayConfig instance as context
|
||||||
* @param {Object} [options] - Additional options to pass to Clay
|
* @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
|
* automatically handle the 'showConfiguration' and 'webviewclosed' events
|
||||||
|
* @param {*} [options.userData={}] - Arbitrary data to pass to the config page. Will
|
||||||
|
* be available as `clayConfig.meta.userData`
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function Clay(config, customFn, options) {
|
function Clay(config, customFn, options) {
|
||||||
@@ -27,15 +30,30 @@ function Clay(config, customFn, options) {
|
|||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
self.config = config;
|
self.config = deepcopy(config);
|
||||||
self.customFn = customFn || function() {};
|
self.customFn = customFn || function() {};
|
||||||
self.components = {};
|
self.components = {};
|
||||||
self.meta = {
|
self.meta = {
|
||||||
activeWatchInfo: null,
|
activeWatchInfo: null,
|
||||||
accountToken: '',
|
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
|
// Let Clay handle all the magic
|
||||||
if (options.autoHandleEvents !== false && typeof Pebble !== 'undefined') {
|
if (options.autoHandleEvents !== false && typeof Pebble !== 'undefined') {
|
||||||
|
|
||||||
@@ -62,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
|
* @private
|
||||||
* @param {Clay~ConfigItem|Array} item
|
* @param {Clay~ConfigItem|Array} item
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
"browserify-istanbul": "^0.2.1",
|
"browserify-istanbul": "^0.2.1",
|
||||||
"chai": "^3.4.1",
|
"chai": "^3.4.1",
|
||||||
"deamdify": "^0.2.0",
|
"deamdify": "^0.2.0",
|
||||||
|
"deepcopy": "^0.6.1",
|
||||||
"del": "^2.0.2",
|
"del": "^2.0.2",
|
||||||
"eslint": "^1.5.1",
|
"eslint": "^1.5.1",
|
||||||
"eslint-config-pebble": "^1.2.0",
|
"eslint-config-pebble": "^1.2.0",
|
||||||
|
|||||||
+14
-4
@@ -11,12 +11,13 @@ var componentRegistry = require('../src/scripts/lib/component-registry');
|
|||||||
var idCounter = 0;
|
var idCounter = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param {Object} [extra] - add/replace keys in the meta
|
||||||
* @returns {{accountToken: string, watchToken: string, activeWatchInfo: {platform:
|
* @returns {{accountToken: string, watchToken: string, activeWatchInfo: {platform:
|
||||||
* string, model: string, language: string, firmware: {major: number, minor:
|
* string, model: string, language: string, firmware: {major: number, minor:
|
||||||
* number, patch: number, suffix: string}}}}
|
* number, patch: number, suffix: string}}, userData: {}}}
|
||||||
*/
|
*/
|
||||||
module.exports.meta = function() {
|
module.exports.meta = function(extra) {
|
||||||
return {
|
var result = {
|
||||||
accountToken: '0123456789abcdef0123456789abcdef',
|
accountToken: '0123456789abcdef0123456789abcdef',
|
||||||
watchToken: '0123456789abcdef0123456789abcdef',
|
watchToken: '0123456789abcdef0123456789abcdef',
|
||||||
activeWatchInfo: {
|
activeWatchInfo: {
|
||||||
@@ -29,8 +30,15 @@ module.exports.meta = function() {
|
|||||||
patch: 2,
|
patch: 2,
|
||||||
suffix: ''
|
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 {Object} [options] - Additional options to pass to Clay
|
||||||
* @param {boolean} [options.autoHandleEvents] - If false, Clay will not
|
* @param {boolean} [options.autoHandleEvents] - If false, Clay will not
|
||||||
* automatically handle the 'showConfiguration' and 'webviewclosed' events
|
* automatically handle the 'showConfiguration' and 'webviewclosed' events
|
||||||
|
* @param {*} [options.userData={}] - Arbitrary data to pass to the config page. Will
|
||||||
|
* be available as `clayConfig.meta.userData`
|
||||||
* @param {boolean} [destroyLocalStorage=true]
|
* @param {boolean} [destroyLocalStorage=true]
|
||||||
* @return {Clay}
|
* @return {Clay}
|
||||||
*/
|
*/
|
||||||
|
|||||||
+25
-31
@@ -7,31 +7,19 @@ var standardComponents = require('../../src/scripts/components');
|
|||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var toSource = require('tosource');
|
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}
|
* @return {void}
|
||||||
*/
|
*/
|
||||||
function stubPebble() {
|
function stubPebble() {
|
||||||
|
var meta = fixture.meta();
|
||||||
|
|
||||||
global.Pebble = {
|
global.Pebble = {
|
||||||
addEventListener: sinon.stub(),
|
addEventListener: sinon.stub(),
|
||||||
openURL: sinon.stub(),
|
openURL: sinon.stub(),
|
||||||
sendAppMessage: sinon.stub(),
|
sendAppMessage: sinon.stub(),
|
||||||
getActiveWatchInfo: sinon.stub().returns(activeWatchInfo),
|
getActiveWatchInfo: sinon.stub().returns(meta.activeWatchInfo),
|
||||||
getAccountToken: sinon.stub().returns(accountToken),
|
getAccountToken: sinon.stub().returns(meta.accountToken),
|
||||||
getWatchToken: sinon.stub().returns(watchToken)
|
getWatchToken: sinon.stub().returns(meta.watchToken)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,6 +123,15 @@ describe('Clay', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('.config', function() {
|
||||||
|
it('is a copy not a reference', function() {
|
||||||
|
var config = fixture.config(['input', 'text', 'color']);
|
||||||
|
var clay = fixture.clay(config);
|
||||||
|
assert.notStrictEqual(clay.config, config);
|
||||||
|
assert.deepEqual(clay.config, config);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('.registerComponent()', function() {
|
describe('.registerComponent()', function() {
|
||||||
it('adds the component to the this.components', function() {
|
it('adds the component to the this.components', function() {
|
||||||
var clay = fixture.clay([]);
|
var clay = fixture.clay([]);
|
||||||
@@ -301,37 +298,34 @@ describe('Clay', function() {
|
|||||||
var emptyMeta = {
|
var emptyMeta = {
|
||||||
activeWatchInfo: null,
|
activeWatchInfo: null,
|
||||||
accountToken: '',
|
accountToken: '',
|
||||||
watchToken: ''
|
watchToken: '',
|
||||||
|
userData: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
it('populates the meta in the showConfiguration handler', function() {
|
it('populates the meta in the showConfiguration handler', function() {
|
||||||
stubPebble();
|
stubPebble();
|
||||||
var clay = fixture.clay([]);
|
var userData = {foo: 'bar'};
|
||||||
|
var clay = fixture.clay([], null, {userData: userData});
|
||||||
|
|
||||||
// meta only gets populated after showConfiguration happens
|
// meta only gets populated after showConfiguration happens
|
||||||
assert.deepEqual(clay.meta, emptyMeta);
|
assert.deepEqual(clay.meta, emptyMeta);
|
||||||
Pebble.addEventListener.withArgs('showConfiguration').callArg(1);
|
Pebble.addEventListener.withArgs('showConfiguration').callArg(1);
|
||||||
|
assert.deepEqual(clay.meta, fixture.meta({userData: userData}));
|
||||||
assert.deepEqual(clay.meta, {
|
|
||||||
activeWatchInfo: activeWatchInfo,
|
|
||||||
accountToken: accountToken,
|
|
||||||
watchToken: watchToken
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('populates the meta in the ready handler', function() {
|
it('populates the meta in the ready handler', function() {
|
||||||
stubPebble();
|
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
|
// meta only gets populated after ready happens
|
||||||
assert.deepEqual(clay.meta, emptyMeta);
|
assert.deepEqual(clay.meta, emptyMeta);
|
||||||
Pebble.addEventListener.withArgs('ready').callArg(1);
|
Pebble.addEventListener.withArgs('ready').callArg(1);
|
||||||
|
|
||||||
assert.deepEqual(clay.meta, {
|
assert.deepEqual(clay.meta, fixture.meta({userData: userData}));
|
||||||
activeWatchInfo: activeWatchInfo,
|
|
||||||
accountToken: accountToken,
|
|
||||||
watchToken: watchToken
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('populates the meta with with empty values when there is no Pebble global',
|
it('populates the meta with with empty values when there is no Pebble global',
|
||||||
|
|||||||
Reference in New Issue
Block a user