Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ Standard text input field.
| attributes | object | An object containing HTML attributes to set on the input field. Set `type` to values such as "email", "time", "date" etc to adjust the behavior of the component. |
| capabilities | array | Array of features that the connected watch must have for this item to be present |
| group | string | Set this to allow this item, along with other items sharing the same group to be looked up using `Clay.getItemsByGroup()` in your [custom function](#custom-function) |
| persistPerWatch | boolean | Optional. If set to `true`, the selected value will be stored separately for each watch model. Defaults to `false`. | |


##### Example
Expand Down Expand Up @@ -211,6 +212,7 @@ Switch for a single item.
| description | string | Optional sub-text to include below the component |
| capabilities | array | Array of features that the connected watch must have for this item to be present |
| group | string | Set this to allow this item, along with other items sharing the same group to be looked up using `Clay.getItemsByGroup()` in your [custom function](#custom-function) |
| persistPerWatch | boolean | Optional. If set to `true`, the selected value will be stored separately for each watch model. Defaults to `false`. | |


##### Example
Expand Down Expand Up @@ -245,6 +247,7 @@ A dropdown menu containing multiple options.
| options | array of objects | The options you want to appear in the dropdown menu. Each option is an object with a `label` and `value` property. |
| capabilities | array | Array of features that the connected watch must have for this item to be present |
| group | string | Set this to allow this item, along with other items sharing the same group to be looked up using `Clay.getItemsByGroup()` in your [custom function](#custom-function) |
| persistPerWatch | boolean | Optional. If set to `true`, the selected value will be stored separately for each watch model. Defaults to `false`. | |

##### Example

Expand Down Expand Up @@ -354,6 +357,7 @@ The color picker will automatically show a different layout depending on the wat
| allowGray | boolean | Optional. Set this to `true` to include gray (`#AAAAAA`) in the color picker for aplite running on firmware 3 and above. This is optional because only a subset of the drawing operations support gray on aplite. Defaults to `false` |
| capabilities | array | Array of features that the connected watch must have for this item to be present |
| group | string | Set this to allow this item, along with other items sharing the same group to be looked up using `Clay.getItemsByGroup()` in your [custom function](#custom-function) |
| persistPerWatch | boolean | Optional. If set to `true`, the selected value will be stored separately for each watch model. Defaults to `false`. | |

##### Example

Expand Down Expand Up @@ -419,6 +423,7 @@ A list of options allowing the user can only choose one option to submit.
| options | array of objects | The options you want to appear in the radio group. Each option is an object with a `label` and `value` property. |
| capabilities | array | Array of features that the connected watch must have for this item to be present |
| group | string | Set this to allow this item, along with other items sharing the same group to be looked up using `Clay.getItemsByGroup()` in your [custom function](#custom-function) |
| persistPerWatch | boolean | Optional. If set to `true`, the selected value will be stored separately for each watch model. Defaults to `false`. | |

##### Example

Expand Down Expand Up @@ -465,6 +470,7 @@ A list of options where a user may choose more than one option to submit.
| options | array of strings | The labels for each checkbox you want to appear in the checkbox group. |
| capabilities | array | Array of features that the connected watch must have for this item to be present |
| group | string | Set this to allow this item, along with other items sharing the same group to be looked up using `Clay.getItemsByGroup()` in your [custom function](#custom-function) |
| persistPerWatch | boolean | Optional. If set to `true`, the selected value will be stored separately for each watch model. Defaults to `false`. | |

##### Example

Expand Down Expand Up @@ -497,6 +503,7 @@ In the above example, Sushi and Burgers will be selected by default.
| description | string | Optional sub-text to include below the component |
| capabilities | array | Array of features that the connected watch must have for this item to be present |
| group | string | Set this to allow this item, along with other items sharing the same group to be looked up using `Clay.getItemsByGroup()` in your [custom function](#custom-function) |
| persistPerWatch | boolean | Optional. If set to `true`, the selected value will be stored separately for each watch model. Defaults to `false`. | |

##### Example

Expand Down Expand Up @@ -536,6 +543,7 @@ you must just remember to divide the received value on the watch accordingly.
| description | string | Optional sub-text to include below the component |
| capabilities | array | Array of features that the connected watch must have for this item to be present |
| group | string | Set this to allow this item, along with other items sharing the same group to be looked up using `Clay.getItemsByGroup()` in your [custom function](#custom-function) |
| persistPerWatch | boolean | Optional. If set to `true`, the selected value will be stored separately for each watch model. Defaults to `false`. | |

##### Example

Expand Down
68 changes: 51 additions & 17 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ function Clay(config, customFn, options) {
userData: {}
};
self.version = version;
self.watchSpecificKeys = [];

/**
* Populate the meta with data from the Pebble object. Make sure to run this inside
Expand Down Expand Up @@ -120,7 +121,14 @@ function Clay(config, customFn, options) {
self.registerComponent(standardComponents[item.type]);
});

// validate config against teh use of appKeys
// extract watch specific keys
_scanConfig(self.config, function(item) {
return item.persistPerWatch === true;
}, function(item) {
self.watchSpecificKeys.push(item.messageKey);
});

// validate config against the use of appKeys
_scanConfig(self.config, function(item) {
return item.appKey;
}, function() {
Expand All @@ -129,6 +137,44 @@ function Clay(config, customFn, options) {
});
}

Clay.prototype._getStoredSettings = function() {
var self = this;
var globalSettings = {};
var watchSpecificSettings = {};
var watchStorageKey = 'clay-watch-' + (self.meta.watchToken || 'fallback');

try {
globalSettings = JSON.parse(localStorage.getItem('clay-settings')) || {};
watchSpecificSettings = JSON.parse(localStorage.getItem(watchStorageKey)) || {};
} catch (e) {
console.error(e.toString());
}

return Object.assign({}, globalSettings, watchSpecificSettings);
};

Clay.prototype._setStoredSettings = function(settings) {
var self = this;
var globalSettings = {};
var watchSpecificSettings = {};
var watchStorageKey = 'clay-watch-' + (self.meta.watchToken || 'fallback');

if (self.watchSpecificKeys.length) {
Object.keys(settings).forEach(function(key) {
if (self.watchSpecificKeys.includes(key)) {
watchSpecificSettings[key] = settings[key];
} else {
globalSettings[key] = settings[key];
}
});
} else {
globalSettings = settings;
}

localStorage.setItem(watchStorageKey, JSON.stringify(watchSpecificSettings));
localStorage.setItem('clay-settings', JSON.stringify(globalSettings));
};

/**
* Register a component to Clay.
* @param {Object} component - the clay component to register
Expand All @@ -150,16 +196,10 @@ Clay.prototype.registerComponent = function(component) {
* @return {string}
*/
Clay.prototype.generateUrl = function() {
var settings = {};
var settings = this._getStoredSettings();
var emulator = !Pebble || Pebble.platform === 'pypkjs';
var returnTo = emulator ? '$$$RETURN_TO$$$' : 'pebblejs://close#';

try {
settings = JSON.parse(localStorage.getItem('clay-settings')) || {};
} catch (e) {
console.error(e.toString());
}

var compiledHtml = configPageHtml
.replace('$$RETURN_TO$$', returnTo)
.replace('$$CUSTOM_FN$$', toSource(this.customFn))
Expand Down Expand Up @@ -208,7 +248,7 @@ Clay.prototype.getSettings = function(response, convert) {
}
});

localStorage.setItem('clay-settings', JSON.stringify(settingsStorage));
this._setStoredSettings(settingsStorage);

return convert === false ? settings : Clay.prepareSettingsForAppMessage(settings);
};
Expand All @@ -226,13 +266,7 @@ Clay.prototype.getSettings = function(response, convert) {
* @return {undefined}
*/
Clay.prototype.setSettings = function(key, value) {
var settingsStorage = {};

try {
settingsStorage = JSON.parse(localStorage.getItem('clay-settings')) || {};
} catch (e) {
console.error(e.toString());
}
var settingsStorage = this._getStoredSettings();

if (typeof key === 'object') {
var settings = key;
Expand All @@ -243,7 +277,7 @@ Clay.prototype.setSettings = function(key, value) {
settingsStorage[key] = value;
}

localStorage.setItem('clay-settings', JSON.stringify(settingsStorage));
this._setStoredSettings(settingsStorage);
};

/**
Expand Down
31 changes: 31 additions & 0 deletions test/spec/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,8 @@ describe('Clay', function() {
it('it writes to localStorage when passing a key and a value',
function() {
var clay = fixture.clay([]);
clay.meta.watchToken = '0123456789abcdef0123456789abcdef';

var expected = {
key1: 'value1',
key2: 'value2%7Dbreaks'
Expand All @@ -419,8 +421,37 @@ describe('Clay', function() {
assert.equal(localStorage.getItem('clay-settings'),
JSON.stringify(expected)
);

assert.equal(
localStorage.getItem('clay-watch-0123456789abcdef0123456789abcdef'),
JSON.stringify({}));
});

it('it writes watch specific keys to a separate localStorage item as well',
function() {

var clay = fixture.clay([{messageKey: 'key1', persistPerWatch: true}]);
clay.meta.watchToken = '0123456789abcdef0123456789abcdef';

var expectedGlobalSettings = {
key2: 'value2%7Dbreaks'
};

var expectedWatchSettings = {
key1: 'value1'
};

clay.setSettings('key1', 'value1');
clay.setSettings('key2', 'value2%7Dbreaks');
assert.equal(localStorage.getItem('clay-settings'),
JSON.stringify(expectedGlobalSettings)
);

assert.equal(
localStorage.getItem('clay-watch-0123456789abcdef0123456789abcdef'),
JSON.stringify(expectedWatchSettings));
});

it('doesn\'t throw and logs an error if settings in localStorage are broken',
function() {
var clay = fixture.clay([]);
Expand Down