mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-31 03:10:07 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			250 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
| /**********************************************************************
 | |
| * 
 | |
| * Features:
 | |
| *	- config
 | |
| *		general config API
 | |
| *	- localstorage-config
 | |
| *		maintain configuration state in localStorage
 | |
| *	- fs-config
 | |
| *		maintain configuration state in file system
 | |
| *
 | |
| * XXX this module need refactoring...
 | |
| *
 | |
| *
 | |
| **********************************************************************/
 | |
| ((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
 | |
| (function(require){ var module={} // make module AMD/node compatible...
 | |
| /*********************************************************************/
 | |
| 
 | |
| var toggler = require('lib/toggler')
 | |
| var actions = require('lib/actions')
 | |
| var features = require('lib/features')
 | |
| 
 | |
| var core = require('features/core')
 | |
| 
 | |
| 
 | |
| 
 | |
| /*********************************************************************/
 | |
| 
 | |
| // XXX might be a good idea to add "sandbox" mode -- i.e. all settings 
 | |
| // 		are saved to sessionStorage and a re-open will load the old settings...
 | |
| // XXX might be a good idea to add a .configLoaded(..) and .configChanged(..) 
 | |
| // 		events thought it's not clear how are we going to track changes...
 | |
| var ConfigStoreActions = actions.Actions({
 | |
| 	config: {
 | |
| 		// XXX should this include path???
 | |
| 		// 		...there should be modes:
 | |
| 		// 			- 'read-only'	-- don't save...
 | |
| 		// 			- 'portable'	-- use APP dir
 | |
| 		// 			- 'normal'		-- use $HOME
 | |
| 		'config-fs-filename': '.ImageGrid.json',
 | |
| 
 | |
| 		'config-auto-save-interval': 1000*5,
 | |
| 
 | |
| 		'config-load-sequence': [
 | |
| 			// localStorage...
 | |
| 			'storage:${INSTANCE}/config',
 | |
| 
 | |
| 			// FS...
 | |
| 			// XXX should we load both or just one???
 | |
| 			'fileSync:${APP}/.ImageGrid.json',
 | |
| 			'fileSync:${HOME}/.ImageGrid.json',
 | |
| 
 | |
| 			// temporary config...
 | |
| 			// NOTE: this is active until we re-open the app...
 | |
| 			'session:${INSTANCE}/config',
 | |
| 		],
 | |
| 	},
 | |
| 
 | |
| 	__config_base: null,
 | |
| 	__config_loaded_from: null,
 | |
| 
 | |
| 	// XXX handle save order -- need to save to one location only...
 | |
| 	// 		...use: .__config_loaded_from in reverse order (stop on session:..)
 | |
| 	// XXX keep record of what we loaded...
 | |
| 	// XXX should we only support sync stores??? (current state)
 | |
| 	loadConfig: ['File/Load configuration',
 | |
| 		core.doc`
 | |
| 
 | |
| 		NOTE: might need to reload after this.
 | |
| 		`,
 | |
| 		function(query){
 | |
| 			// store loaded...
 | |
| 			var loaded = this.__config_loaded_from = []
 | |
| 
 | |
| 			this.resetConfig()
 | |
| 
 | |
| 			// do the load...
 | |
| 			;(query ? 
 | |
| 					(query instanceof Array ? query : [query])
 | |
| 					: (this.config['config-load-sequence'] || ['storage:config']))
 | |
| 				.forEach(function(query){
 | |
| 					query = this.parseStoreQuery(query)
 | |
| 					var cfg = this.loadStore(query)
 | |
| 
 | |
| 					// select store...
 | |
| 					cfg = query.store
 | |
| 						.map(function(store){ return cfg[store] })
 | |
| 						.filter(function(cfg){ return Object.keys(cfg).length > 0 })
 | |
| 						.shift() || {}
 | |
| 					// select key...
 | |
| 					cfg = query.key
 | |
| 						.map(function(key){ return cfg[key] })
 | |
| 						.filter(function(cfg){ return !!cfg })
 | |
| 						.shift()
 | |
| 
 | |
| 					// merge the config...
 | |
| 					cfg 
 | |
| 						&& Object.assign(this.config, cfg)
 | |
| 						&& loaded.push(query.query)
 | |
| 				}.bind(this))
 | |
| 		}],
 | |
| 	storeConfig: ['File/Save configuration',
 | |
| 		function(query){
 | |
| 			// XXX
 | |
| 			this.saveStore(query || 'storage:${INSTANCE}/config') 
 | |
| 		}],
 | |
| 	// XXX this needs to be confirmed...
 | |
| 	resetConfig: ['File/Reset configuration',
 | |
| 		core.doc`
 | |
| 
 | |
| 		NOTE: might need to reload after this.
 | |
| 		`,
 | |
| 		function(){
 | |
| 			var base = this.__config_base = this.__config_base || this.config
 | |
| 			this.config = Object.create(base)
 | |
| 		}],
 | |
| 
 | |
| 	// XXX use timer events... (???)
 | |
| 	toggleConfigAutoStore: ['File/Auto-save configuration',
 | |
| 		toggler.Toggler(null, 
 | |
| 			function(_, state){ 
 | |
| 				var timer = 'config-auto-save-timer'
 | |
| 
 | |
| 				if(state == null){
 | |
| 					return this.isPersistentInterval(timer) || 'none'
 | |
| 
 | |
| 				} else {
 | |
| 					var that = this
 | |
| 					var interval = this.config['config-auto-save-interval']
 | |
| 
 | |
| 					// no timer interval set...
 | |
| 					if(!interval){
 | |
| 						return false
 | |
| 					}
 | |
| 
 | |
| 					// start/restart...
 | |
| 					if(state == 'running' && interval){
 | |
| 						this.setPersistentInterval(timer, 'storeConfig', interval*1000)
 | |
| 
 | |
| 					// stop...
 | |
| 					} else {
 | |
| 						this.clearPersistentInterval(timer)
 | |
| 					}
 | |
| 				}
 | |
| 			},
 | |
| 			'running')],
 | |
| 	
 | |
| 
 | |
| 	// XXX does not work yet... 
 | |
| 	toggleConfigSandbox: ['- File/',
 | |
| 		toggler.Toggler(null, 
 | |
| 			function(_, state){ 
 | |
| 
 | |
| 				if(state == null){
 | |
| 					return Object.keys(this.store('session:${INSTANCE}/config').session).length > 0 || 'none'
 | |
| 
 | |
| 				} else if(state == 'sandboxed'){
 | |
| 					this.store('session:${INSTANCE}/config', undefined)
 | |
| 
 | |
| 				} else {
 | |
| 					this.storeConfig('session:${INSTANCE}/config')
 | |
| 				}
 | |
| 			},
 | |
| 			'sandboxed')],
 | |
| })
 | |
| 
 | |
| var ConfigStore = 
 | |
| module.ConfigStore = core.ImageGridFeatures.Feature({
 | |
| 	title: '',
 | |
| 	doc: '',
 | |
| 
 | |
| 	tag: 'store-config',
 | |
| 	priority: 80,
 | |
| 	depends: [
 | |
| 		'timers',
 | |
| 		'store-localstorage',
 | |
| 	],
 | |
| 	suggested: [
 | |
| 		'store-fs-json-sync',
 | |
| 	],
 | |
| 
 | |
| 	actions: ConfigStoreActions,
 | |
| 
 | |
| 	handlers: [
 | |
| 		// XXX need to update rather than rewrite things...
 | |
| 		['prepareStoreToSave', 
 | |
| 			function(res, query, data){
 | |
| 				var ls_path = '${INSTANCE}/config'
 | |
| 				//var ls_path = 'config'
 | |
| 				query = this.parseStoreQuery(query)
 | |
| 				
 | |
| 				// config not requested...
 | |
| 				if(query.key != '*' 
 | |
| 						&& query.key.indexOf('config')
 | |
| 						&& query.key.indexOf(ls_path)){
 | |
| 					return
 | |
| 				}
 | |
| 
 | |
| 				// localStorage...
 | |
| 				// NOTE: we do not need to clone anything here as this 
 | |
| 				// 		will be done by the localStorage handler...
 | |
| 				if(query.store.indexOf('storage') >= 0){
 | |
| 					//res.data.storage[ls_path] = this.config
 | |
| 					res.data.storage[ls_path] = data || this.config
 | |
| 				}
 | |
| 
 | |
| 				if(query.store.indexOf('fileSync') >= 0){
 | |
| 					// XXX should this include path???
 | |
| 					//res.data.fileSync[this.config['config-fs-filename'] || '.ImageGrid.json'] = this.config
 | |
| 					res.data.fileSync[this.config['config-fs-filename'] || '.ImageGrid.json'] = data || this.config
 | |
| 				}
 | |
| 			}],
 | |
| 		//['prepareIndexForLoad',
 | |
| 		//	function(){
 | |
| 		//	}],
 | |
| 		// NOTE: this is sync for sync stores...
 | |
| 		['storeDataLoaded',
 | |
| 			function(_, store, data){
 | |
| 				var base = this.__config_base = this.__config_base || this.config
 | |
| 				var ls_path = '${INSTANCE}/config'
 | |
| 
 | |
| 				// XXX sort out load priority/logic...
 | |
| 				// 		- one or the other or both?
 | |
| 				// 		- what order?
 | |
| 
 | |
| 				if((data.storage || {})[ls_path]){
 | |
| 					var config = data.storage[ls_path] || {}
 | |
| 					config.__proto__ = base
 | |
| 					this.config = config
 | |
| 				}
 | |
| 
 | |
| 				if((data.fsJSONSync || {}).config){
 | |
| 					var config = data.fsJSONSync.config || {}
 | |
| 					config.__proto__ = base
 | |
| 					this.config = config
 | |
| 				}
 | |
| 
 | |
| 				// auto-start auto-save...
 | |
| 				this.config['config-auto-save-interval'] > 0 
 | |
| 					&& this.toggleConfigAutoStore('?') == 'off'
 | |
| 					&& this.toggleConfigAutoStore()
 | |
| 			}],
 | |
| 	],
 | |
| })
 | |
| 
 | |
| 
 | |
| 
 | |
| /**********************************************************************
 | |
| * vim:set ts=4 sw=4 :                               */ return module })
 |