Last active
August 29, 2015 14:17
-
-
Save lahmatiy/e499e76be22140648cb9 to your computer and use it in GitHub Desktop.
Example of persistent user preferences using basis.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Enum class is proposed future citizen of basis.js | |
// | |
var Value = require('basis.data').Value; | |
var Enum = Value.subclass({ | |
className: 'Enum', | |
init: function(){ | |
var values = basis.array.from(this.values); | |
/** @cut */if (this.proxy) | |
/** @cut */ basis.dev.warn('Setting `proxy` for Enum instances is prohibited'); | |
this.proxy = function(value){ | |
if (values.indexOf(value) != -1) | |
return value; | |
/** @cut */basis.dev.warn('Trying to set wrong value for Enum instance.' + | |
/** @cut */ '\nVariants: ', values, | |
/** @cut */ '\nIgnored value: ', value); | |
return this.value; | |
}; | |
if (values.indexOf(this.value) == -1) | |
this.value = values[0]; | |
Value.prototype.init.call(this); | |
}, | |
toggle: function(){ | |
var idx = (this.values.indexOf(this.value) + 1) % this.values.length; | |
this.set(this.values[idx]); | |
} | |
}); | |
module.exports = Enum; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Example of persistent user preferencies. | |
// Probably common class based on this solution will be added to basis.js. | |
var SETTINGS = 'user-preferences'; | |
var Value = require('basis.data').Value; | |
var ObjectSet = require('basis.data.value').ObjectSet; | |
var Enum = require('./enum.js'); | |
var initValues = {}; | |
var storage = (function(){ | |
var testKey = '__localStorageTest' + Math.random(); | |
var localStorage = global.localStorage; | |
var supported = false; | |
// test localStorage as it can produce exceptions in some cases | |
try { | |
localStorage.setItem(testKey, testKey); | |
supported = localStorage.getItem(testKey) === testKey; | |
localStorage.removeItem(testKey); | |
} catch (e) { | |
// if exception don't use localStorage | |
} | |
return supported ? localStorage : {}; | |
})(); | |
// try fetch settings from storage | |
try { | |
initValues = basis.json.parse(storage[SETTINGS]); | |
} catch (e) {} | |
// preference map and default values | |
var preferences = { | |
sidebarSize: ['normal', 'short'], | |
viewMode: ['list', 'table'], | |
lastLogin: '' | |
}; | |
// convert to Value instances | |
for (var name in preferences) | |
preferences[name] = Array.isArray(preferences[name]) | |
? new Enum({ | |
value: initValues[name], | |
values: preferences[name] | |
}) | |
: new Value({ | |
value: name in initValues ? initValues[name] : preferences[name] | |
}); | |
// sync with local storage | |
var changesWatcher = new ObjectSet({ | |
objects: basis.object.values(preferences), | |
calculateValue: function(){ | |
return JSON.stringify(basis.object.keys(preferences).sort().reduce(function(res, name){ | |
res[name] = preferences[name].value; | |
return res; | |
}, {})); | |
}, | |
handler: { | |
change: function(){ | |
storage[SETTINGS] = this.value; | |
} | |
} | |
}); | |
// make copy of preferences object, to avoid overrides | |
module.exports = basis.object.slice(preferences); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Value = require('basis.data').Value; | |
var Node = require('basis.ui').Node; | |
var preferences = require('./preferences.js'); | |
console.log(preferences.sidebarSize); | |
// > Enum { .. } | |
// if no value in localStorage than default value used | |
// for enums it's a first item | |
console.log(preferences.sidebarSize.value); | |
// > "normal" | |
preferences.sidebarSize.set('xxx'); | |
// > Trying to set wrong value for Enum instance. | |
// Variants: ["normal", "short"] | |
// Ignored value: xxx | |
preferences.sidebarSize.set('short'); | |
console.log(preferences.sidebarSize.value); | |
// > "short" | |
// if setting is enum, we could switch value by toggle method | |
preferences.sidebarSize.toggle(); | |
console.log(preferences.sidebarSize.value); | |
// > "normal" | |
var view = new Node({ | |
binding: { | |
size: preferences.sidebarSize, | |
// of cause it's anti-pattern and sizes should live in template/css land | |
// but it shows how value could be transformed | |
width: preferences.sidebarSize.as(function(value){ | |
return value == 'normal' ? 300 : 50; | |
}) | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment