mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-31 19:30:07 +00:00 
			
		
		
		
	moved to new store for config...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									1949aa884f
								
							
						
					
					
						commit
						35a7a16539
					
				| @ -11,6 +11,7 @@ | |||||||
| var core = require('features/core') | var core = require('features/core') | ||||||
| 
 | 
 | ||||||
| require('features/base') | require('features/base') | ||||||
|  | require('features/store') | ||||||
| require('features/collections') | require('features/collections') | ||||||
| require('features/sort') | require('features/sort') | ||||||
| require('features/tags') | require('features/tags') | ||||||
|  | |||||||
| @ -24,274 +24,6 @@ var core = require('features/core') | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /*********************************************************************/ |  | ||||||
| // XXX move store to a separate module...
 |  | ||||||
| 
 |  | ||||||
| // XXX should we unify this with the save/load API
 |  | ||||||
| var StoreActions = actions.Actions({ |  | ||||||
| 	config: { |  | ||||||
| 		// Storage mode...
 |  | ||||||
| 		//
 |  | ||||||
| 		// This can be:
 |  | ||||||
| 		// 	'read-only'
 |  | ||||||
| 		// 	'read-write'
 |  | ||||||
| 		// 	null			- ignore store
 |  | ||||||
| 		//
 |  | ||||||
| 		// NOTE: this only affects start/stop/timer event handling, manual
 |  | ||||||
| 		// 		call to .loadData(..) / .saveData(..) are not affected...
 |  | ||||||
| 		'store-mode': 'read-write', |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 	// Store handler dict...
 |  | ||||||
| 	//
 |  | ||||||
| 	// Format:
 |  | ||||||
| 	// 	{
 |  | ||||||
| 	// 		<store-tag>: <handler-action>,
 |  | ||||||
| 	// 		...
 |  | ||||||
| 	// 	}
 |  | ||||||
| 	//
 |  | ||||||
| 	// XXX this is almost the same as .collection_handlers...
 |  | ||||||
| 	get store_handlers(){ |  | ||||||
| 		return this.cache('store_handlers', function(d){ |  | ||||||
| 			var res = {} |  | ||||||
| 
 |  | ||||||
| 			this.actions.forEach(function(action){  |  | ||||||
| 				var store = this.getActionAttr(action, 'handle_data_store') |  | ||||||
| 				res[store] |  | ||||||
| 					&& console.warn('Multiple handlers for store:', store) |  | ||||||
| 				if(store){ |  | ||||||
| 					res[store] = action |  | ||||||
| 				} |  | ||||||
| 			}.bind(this)) |  | ||||||
| 
 |  | ||||||
| 			return res |  | ||||||
| 		}) }, |  | ||||||
| 
 |  | ||||||
| 	// events...
 |  | ||||||
| 	storeDataLoaded: ['- Store/', |  | ||||||
| 		core.doc`Store data loaded event...
 |  | ||||||
| 
 |  | ||||||
| 		This is tirggered as soon per store as soon as data is loaded,  |  | ||||||
| 		this is sync for sync stores. |  | ||||||
| 
 |  | ||||||
| 		NOTE: only one store data set is included per call.`,
 |  | ||||||
| 		core.Event(function(data){ |  | ||||||
| 			// Store data loaded event...
 |  | ||||||
| 			//
 |  | ||||||
| 			// Not intended for direct use, use .declareReady() to initiate.
 |  | ||||||
| 			return data |  | ||||||
| 		})], |  | ||||||
| 
 |  | ||||||
| 	// base API...
 |  | ||||||
| 	prepareStoreToSave: ['- Store/', |  | ||||||
| 		core.doc` |  | ||||||
| 
 |  | ||||||
| 		Modes: |  | ||||||
| 			'fast'		- fast timer |  | ||||||
| 			'full'		- full store |  | ||||||
| 
 |  | ||||||
| 		Format: |  | ||||||
| 			{ |  | ||||||
| 				// metadata...
 |  | ||||||
| 				mode: <mode>, |  | ||||||
| 				data: <timestamp>, |  | ||||||
| 
 |  | ||||||
| 				// the actual data...
 |  | ||||||
| 				store: { |  | ||||||
| 					<store-type>: { |  | ||||||
| 						<data-key>: <data>, |  | ||||||
| 						... |  | ||||||
| 					}, |  | ||||||
| 					... |  | ||||||
| 				}, |  | ||||||
| 			} |  | ||||||
| 		`,
 |  | ||||||
| 		function(mode, date){  |  | ||||||
| 			var store = {} |  | ||||||
| 			// populate the store...
 |  | ||||||
| 			Object.keys(this.store_handlers) |  | ||||||
| 				.forEach(function(key){ store[key] = {} }) |  | ||||||
| 			return { |  | ||||||
| 				mode: mode || 'full', |  | ||||||
| 				date: date || Date.timeStamp(), |  | ||||||
| 
 |  | ||||||
| 				store: store, |  | ||||||
| 			}  |  | ||||||
| 		}], |  | ||||||
| 	prepareStoreToLoad: ['- Store/', |  | ||||||
| 		core.doc` |  | ||||||
| 		 |  | ||||||
| 		NOTE: this can be called multiple times, once per each store. |  | ||||||
| 		NOTE: only one store data set is included per call.`,
 |  | ||||||
| 		function(data){ return data || {} }], |  | ||||||
| 	// XXX async???
 |  | ||||||
| 	// XXX we need to be able to save/load specific part of the data...
 |  | ||||||
| 	// 		...i.e. query by store and/or key...
 |  | ||||||
| 	saveData: ['- Store/', |  | ||||||
| 		function(mode, date){ |  | ||||||
| 			var handlers = this.store_handlers |  | ||||||
| 			var data = this.prepareStoreToSave(mode, date) |  | ||||||
| 			 |  | ||||||
| 			Object.keys(data.store).forEach(function(store){ |  | ||||||
| 				var handler = handlers[store] |  | ||||||
| 				handler  |  | ||||||
| 					&& this[handler].call(this, data.store[store]) |  | ||||||
| 			}.bind(this)) |  | ||||||
| 		}], |  | ||||||
| 	loadData: ['- Store/', |  | ||||||
| 		function(){ |  | ||||||
| 			var handlers = this.store_handlers |  | ||||||
| 			var data = {} |  | ||||||
| 			return Promise |  | ||||||
| 				.all(Object.keys(handlers) |  | ||||||
| 					.map(function(s){ |  | ||||||
| 						var res = this[handlers[s]]() |  | ||||||
| 						return res instanceof Promise ? |  | ||||||
| 							// async store...
 |  | ||||||
| 							res.then(function(d){ d  |  | ||||||
| 								&& (data[s] = d) |  | ||||||
| 								&& this.storeDataLoaded( |  | ||||||
| 									this.prepareStoreToLoad({[s]: d})) }.bind(this)) |  | ||||||
| 							// sync store...
 |  | ||||||
| 							: (res  |  | ||||||
| 								&& (data[s] = res) |  | ||||||
| 								&& this.storeDataLoaded( |  | ||||||
| 									this.prepareStoreToLoad({[s]: res}))) |  | ||||||
| 					}.bind(this)))  |  | ||||||
| 				.then(function(){ return data })}], |  | ||||||
| 	// XXX do we need to do a partial clear???
 |  | ||||||
| 	clearData: ['- Store/', |  | ||||||
| 		function(target){ |  | ||||||
| 			var handlers = this.store_handlers |  | ||||||
| 
 |  | ||||||
| 			Object.keys(handlers).forEach(function(store){ |  | ||||||
| 				var handler = handlers[store] |  | ||||||
| 				handler |  | ||||||
| 					&& this[handler].call(this, null) |  | ||||||
| 			}.bind(this)) |  | ||||||
| 		}], |  | ||||||
| }) |  | ||||||
| 
 |  | ||||||
| var Store =  |  | ||||||
| module.Store = core.ImageGridFeatures.Feature({ |  | ||||||
| 	title: '', |  | ||||||
| 	doc: '', |  | ||||||
| 
 |  | ||||||
| 	tag: 'store', |  | ||||||
| 	depends: [ |  | ||||||
| 		'cache', |  | ||||||
| 	], |  | ||||||
| 	suggested: [ |  | ||||||
| 		'store-localstorage', |  | ||||||
| 	], |  | ||||||
| 	isApplicable: function(){ return typeof(localStorage) != 'undefined' }, |  | ||||||
| 
 |  | ||||||
| 	actions: StoreActions, |  | ||||||
| 
 |  | ||||||
| 	handlers: [ |  | ||||||
| 		['start.pre',  |  | ||||||
| 			function(){  |  | ||||||
| 				if(this.config['store-mode'] != null){ |  | ||||||
| 					this.requestReadyAnnounce() |  | ||||||
| 					this |  | ||||||
| 						.loadData()  |  | ||||||
| 						.then(function(){ |  | ||||||
| 							this.declareReady() }.bind(this))  |  | ||||||
| 				} }], |  | ||||||
| 		['stop',  |  | ||||||
| 			function(){  |  | ||||||
| 				this.config['store-mode'] == 'read-write' && this.saveData() }], |  | ||||||
| 		// XXX timer???
 |  | ||||||
| 		// XXX
 |  | ||||||
| 	], |  | ||||||
| }) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //---------------------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| // XXX we should have a separate store config with settings of how to 
 |  | ||||||
| // 		load the store... (???)
 |  | ||||||
| var StoreLocalStorageActions = actions.Actions({ |  | ||||||
| 	config: { |  | ||||||
| 		// XXX
 |  | ||||||
| 		'store-root-key': 'test-store-root-key', |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| 	// XXX get root key from config...
 |  | ||||||
| 	// 		...this would require us to store the store config separately...
 |  | ||||||
| 	localStorageDataHandler: ['- Store/', |  | ||||||
| 		{handle_data_store: 'localStorage',}, |  | ||||||
| 		function(data){ |  | ||||||
| 			// XXX get this from config...
 |  | ||||||
| 			var root = this.config['store-root-key']  |  | ||||||
| 
 |  | ||||||
| 			// clear...
 |  | ||||||
| 			if(data === null){ |  | ||||||
| 				delete localStorage[root] |  | ||||||
| 
 |  | ||||||
| 			// set...
 |  | ||||||
| 			} else if(data){ |  | ||||||
| 				localStorage[root] = JSON.stringify(data) |  | ||||||
| 
 |  | ||||||
| 			// get...
 |  | ||||||
| 			} else { |  | ||||||
| 				var d = localStorage[root] |  | ||||||
| 				return d != undefined ? JSON.parse(d) : {} |  | ||||||
| 			} |  | ||||||
| 		}], |  | ||||||
| 	sessionStorageDataHandler: ['- Store/', |  | ||||||
| 		{handle_data_store: 'sessionStorage',}, |  | ||||||
| 		function(data){ |  | ||||||
| 			// XXX get this from config...
 |  | ||||||
| 			var root = this.config['store-root-key']  |  | ||||||
| 
 |  | ||||||
| 			// clear...
 |  | ||||||
| 			if(data === null){ |  | ||||||
| 				delete sessionStorage[root] |  | ||||||
| 
 |  | ||||||
| 			// set...
 |  | ||||||
| 			} else if(data){ |  | ||||||
| 				sessionStorage[root] = JSON.stringify(data) |  | ||||||
| 
 |  | ||||||
| 			// get...
 |  | ||||||
| 			} else { |  | ||||||
| 				var d = localStorage[root] |  | ||||||
| 				return d != undefined ? JSON.parse(d) : {} |  | ||||||
| 			} |  | ||||||
| 		}], |  | ||||||
| }) |  | ||||||
| 
 |  | ||||||
| var StoreLocalStorage =  |  | ||||||
| module.StoreLocalStorage = core.ImageGridFeatures.Feature({ |  | ||||||
| 	title: '', |  | ||||||
| 	doc: '', |  | ||||||
| 
 |  | ||||||
| 	tag: 'store-localstorage', |  | ||||||
| 	depends: [ |  | ||||||
| 		'store', |  | ||||||
| 	], |  | ||||||
| 	isApplicable: function(){  |  | ||||||
| 		return typeof(localStorage) != 'undefined'  |  | ||||||
| 			&& typeof(sessionStorage) != 'undefined' }, |  | ||||||
| 
 |  | ||||||
| 	actions: StoreLocalStorageActions, |  | ||||||
| }) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //---------------------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| // XXX StoreFSJSONSync
 |  | ||||||
| // 		Lookup order:
 |  | ||||||
| // 			- app dir
 |  | ||||||
| // 			- $HOME
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //---------------------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| // XXX StoreFSJSON
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /*********************************************************************/ | /*********************************************************************/ | ||||||
| 
 | 
 | ||||||
| // XXX might be a good idea to add a .configLoaded(..) and .configChanged(..) 
 | // XXX might be a good idea to add a .configLoaded(..) and .configChanged(..) 
 | ||||||
| @ -305,16 +37,18 @@ var ConfigStoreActions = actions.Actions({ | |||||||
| 		// 			- 'normal'		-- use $HOME
 | 		// 			- 'normal'		-- use $HOME
 | ||||||
| 		'config-fs-filename': '.ImageGrid.json', | 		'config-fs-filename': '.ImageGrid.json', | ||||||
| 
 | 
 | ||||||
| 		'config-auto-save-interval': null, | 		'config-auto-save-interval': 1000*5, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	__base_config: null, | 	__base_config: null, | ||||||
| 
 | 
 | ||||||
| 	/* XXX | 	 | ||||||
|  | 	// XXX
 | ||||||
| 	storeConfig: ['File/Store configuration', | 	storeConfig: ['File/Store configuration', | ||||||
| 		function(key){ | 		function(key){ | ||||||
| 			// XXX
 | 			// XXX
 | ||||||
| 		}], | 		}], | ||||||
|  | 	// XXX
 | ||||||
| 	loadConfig: ['File/Load stored configuration', | 	loadConfig: ['File/Load stored configuration', | ||||||
| 		function(key){ | 		function(key){ | ||||||
| 			// XXX
 | 			// XXX
 | ||||||
| @ -325,8 +59,9 @@ var ConfigStoreActions = actions.Actions({ | |||||||
| 			var base = this.__base_config = this.__base_config || this.config | 			var base = this.__base_config = this.__base_config || this.config | ||||||
| 			this.config = Object.create(base) | 			this.config = Object.create(base) | ||||||
| 		}], | 		}], | ||||||
| 	//*/
 | 
 | ||||||
| 	/* XXX use timer events... | 	// XXX use timer events... (???)
 | ||||||
|  | 	// XXX this needs a working .storeConfig(..)
 | ||||||
| 	toggleAutoStoreConfig: ['File/Store configuration', | 	toggleAutoStoreConfig: ['File/Store configuration', | ||||||
| 		toggler.Toggler(null,  | 		toggler.Toggler(null,  | ||||||
| 			function(_, state){  | 			function(_, state){  | ||||||
| @ -355,7 +90,6 @@ var ConfigStoreActions = actions.Actions({ | |||||||
| 				} | 				} | ||||||
| 			}, | 			}, | ||||||
| 			'running')], | 			'running')], | ||||||
| 	//*/
 |  | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| var ConfigStore =  | var ConfigStore =  | ||||||
| @ -398,10 +132,7 @@ module.ConfigStore = core.ImageGridFeatures.Feature({ | |||||||
| 					var base = this.__base_config = this.__base_config || this.config | 					var base = this.__base_config = this.__base_config || this.config | ||||||
| 					var config = store.localStorage.config || {} | 					var config = store.localStorage.config || {} | ||||||
| 					config.__proto__ = base | 					config.__proto__ = base | ||||||
| 					// XXX set the config...
 | 					this.config = config | ||||||
| 					// 		...disabled for now to avoid conflicts with 
 |  | ||||||
| 					// 		legacy until we are ready to make the move...
 |  | ||||||
| 					//this.config = config
 |  | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				// XXX sync fs store...
 | 				// XXX sync fs store...
 | ||||||
| @ -410,6 +141,11 @@ module.ConfigStore = core.ImageGridFeatures.Feature({ | |||||||
| 				if((store.fsJSONSync || {}).config){ | 				if((store.fsJSONSync || {}).config){ | ||||||
| 					// XXX
 | 					// XXX
 | ||||||
| 				} | 				} | ||||||
|  | 
 | ||||||
|  | 				// auto-start auto-save...
 | ||||||
|  | 				this.config['config-auto-save-interval'] > 0  | ||||||
|  | 					&& this.toggleAutoStoreConfig('?') == 'off' | ||||||
|  | 					&& this.toggleAutoStoreConfig() | ||||||
| 			}], | 			}], | ||||||
| 	], | 	], | ||||||
| }) | }) | ||||||
| @ -417,6 +153,8 @@ module.ConfigStore = core.ImageGridFeatures.Feature({ | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /*********************************************************************/ | /*********************************************************************/ | ||||||
|  | /*/ XXX LEGACY... | ||||||
|  | //
 | ||||||
| // XXX might be a good idea to add an external payload mechanism for 
 | // XXX might be a good idea to add an external payload mechanism for 
 | ||||||
| // 		other data to be saved to avoid re-implementing the same logic
 | // 		other data to be saved to avoid re-implementing the same logic
 | ||||||
| // 		...like is done in features/history.js
 | // 		...like is done in features/history.js
 | ||||||
| @ -512,7 +250,6 @@ var ConfigActions = actions.Actions({ | |||||||
| 			'running')], | 			'running')], | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| var Config =  | var Config =  | ||||||
| module.Config = core.ImageGridFeatures.Feature({ | module.Config = core.ImageGridFeatures.Feature({ | ||||||
| 	title: '', | 	title: '', | ||||||
| @ -616,7 +353,6 @@ var ConfigLocalStorageActions = actions.Actions({ | |||||||
| 		}], | 		}], | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| var ConfigLocalStorage =  | var ConfigLocalStorage =  | ||||||
| module.ConfigLocalStorage = core.ImageGridFeatures.Feature({ | module.ConfigLocalStorage = core.ImageGridFeatures.Feature({ | ||||||
| 	title: '', | 	title: '', | ||||||
| @ -636,52 +372,7 @@ module.ConfigLocalStorage = core.ImageGridFeatures.Feature({ | |||||||
| 
 | 
 | ||||||
| 	actions: ConfigLocalStorageActions, | 	actions: ConfigLocalStorageActions, | ||||||
| }) | }) | ||||||
| 
 | //*/
 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //---------------------------------------------------------------------
 |  | ||||||
| // XXX store config locations:
 |  | ||||||
| // 		- app
 |  | ||||||
| // 		- home
 |  | ||||||
| // XXX config override location/filename to support portable apps...
 |  | ||||||
| // XXX comment support in json (preferably both reading and writing...)
 |  | ||||||
| 
 |  | ||||||
| var ConfigFSActions = actions.Actions({ |  | ||||||
| 	config: { |  | ||||||
| 	}, |  | ||||||
| 
 |  | ||||||
| }) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| var ConfigFS =  |  | ||||||
| module.ConfigFS = core.ImageGridFeatures.Feature({ |  | ||||||
| 	title: '', |  | ||||||
| 	doc: '', |  | ||||||
| 
 |  | ||||||
| 	tag: 'fs-config', |  | ||||||
| 	depends: [ |  | ||||||
| 		'localstorage-config', |  | ||||||
| 		'fs', |  | ||||||
| 	], |  | ||||||
| 
 |  | ||||||
| 	actions: ConfigFSActions, |  | ||||||
| 
 |  | ||||||
| 	handlers: [ |  | ||||||
| 		// NOTE: considering that allot depends on this it must be 
 |  | ||||||
| 		// 		first to run...
 |  | ||||||
| 		['loadConfig', |  | ||||||
| 			function(){  |  | ||||||
| 			}], |  | ||||||
| 		['storeConfig', |  | ||||||
| 			function(){  |  | ||||||
| 			}], |  | ||||||
| 	], |  | ||||||
| }) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| //---------------------------------------------------------------------
 |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /********************************************************************** | /********************************************************************** | ||||||
|  | |||||||
| @ -891,7 +891,7 @@ var TimersActions = actions.Actions({ | |||||||
| 				ms: ms, | 				ms: ms, | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			timeouts[id] = setInterval( | 			intervals[id] = setInterval( | ||||||
| 				function(){ this.call(action) }.bind(this),  | 				function(){ this.call(action) }.bind(this),  | ||||||
| 				ms || 0) | 				ms || 0) | ||||||
| 		}], | 		}], | ||||||
|  | |||||||
| @ -137,8 +137,8 @@ core.ImageGridFeatures.Feature('imagegrid-testing', [ | |||||||
| 
 | 
 | ||||||
| 	// XXX testing...
 | 	// XXX testing...
 | ||||||
| 	'store-config', | 	'store-config', | ||||||
|  | 	//'config',
 | ||||||
| 
 | 
 | ||||||
| 	'config', |  | ||||||
| 	'ui-url-hash', | 	'ui-url-hash', | ||||||
| 
 | 
 | ||||||
| 	'fail-safe-devtools', | 	'fail-safe-devtools', | ||||||
|  | |||||||
							
								
								
									
										285
									
								
								ui (gen4)/features/store.js
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										285
									
								
								ui (gen4)/features/store.js
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,285 @@ | |||||||
|  | /********************************************************************** | ||||||
|  | *  | ||||||
|  | * | ||||||
|  | * | ||||||
|  | **********************************************************************/ | ||||||
|  | ((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define) | ||||||
|  | (function(require){ var module={} // make module AMD/node compatible...
 | ||||||
|  | /*********************************************************************/ | ||||||
|  | 
 | ||||||
|  | var actions = require('lib/actions') | ||||||
|  | var features = require('lib/features') | ||||||
|  | 
 | ||||||
|  | var core = require('features/core') | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*********************************************************************/ | ||||||
|  | 
 | ||||||
|  | // XXX should we unify this with the save/load API
 | ||||||
|  | var StoreActions = actions.Actions({ | ||||||
|  | 	config: { | ||||||
|  | 		// Storage mode...
 | ||||||
|  | 		//
 | ||||||
|  | 		// This can be:
 | ||||||
|  | 		// 	'read-only'
 | ||||||
|  | 		// 	'read-write'
 | ||||||
|  | 		// 	null			- ignore store
 | ||||||
|  | 		//
 | ||||||
|  | 		// NOTE: this only affects start/stop/timer event handling, manual
 | ||||||
|  | 		// 		call to .loadData(..) / .saveData(..) are not affected...
 | ||||||
|  | 		'store-mode': 'read-write', | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 	// Store handler dict...
 | ||||||
|  | 	//
 | ||||||
|  | 	// Format:
 | ||||||
|  | 	// 	{
 | ||||||
|  | 	// 		<store-tag>: <handler-action>,
 | ||||||
|  | 	// 		...
 | ||||||
|  | 	// 	}
 | ||||||
|  | 	//
 | ||||||
|  | 	// XXX this is almost the same as .collection_handlers...
 | ||||||
|  | 	get store_handlers(){ | ||||||
|  | 		return this.cache('store_handlers', function(d){ | ||||||
|  | 			var res = {} | ||||||
|  | 
 | ||||||
|  | 			this.actions.forEach(function(action){  | ||||||
|  | 				var store = this.getActionAttr(action, 'handle_data_store') | ||||||
|  | 				res[store] | ||||||
|  | 					&& console.warn('Multiple handlers for store:', store) | ||||||
|  | 				if(store){ | ||||||
|  | 					res[store] = action | ||||||
|  | 				} | ||||||
|  | 			}.bind(this)) | ||||||
|  | 
 | ||||||
|  | 			return res | ||||||
|  | 		}) }, | ||||||
|  | 
 | ||||||
|  | 	// events...
 | ||||||
|  | 	storeDataLoaded: ['- Store/', | ||||||
|  | 		core.doc`Store data loaded event...
 | ||||||
|  | 
 | ||||||
|  | 		This is tirggered as soon per store as soon as data is loaded,  | ||||||
|  | 		this is sync for sync stores. | ||||||
|  | 
 | ||||||
|  | 		NOTE: only one store data set is included per call.`,
 | ||||||
|  | 		core.Event(function(data){ | ||||||
|  | 			// Store data loaded event...
 | ||||||
|  | 			//
 | ||||||
|  | 			// Not intended for direct use, use .declareReady() to initiate.
 | ||||||
|  | 			return data | ||||||
|  | 		})], | ||||||
|  | 
 | ||||||
|  | 	// base API...
 | ||||||
|  | 	prepareStoreToSave: ['- Store/', | ||||||
|  | 		core.doc` | ||||||
|  | 
 | ||||||
|  | 		Modes: | ||||||
|  | 			'fast'		- fast timer | ||||||
|  | 			'full'		- full store | ||||||
|  | 
 | ||||||
|  | 		Format: | ||||||
|  | 			{ | ||||||
|  | 				// metadata...
 | ||||||
|  | 				mode: <mode>, | ||||||
|  | 				data: <timestamp>, | ||||||
|  | 
 | ||||||
|  | 				// the actual data...
 | ||||||
|  | 				store: { | ||||||
|  | 					<store-type>: { | ||||||
|  | 						<data-key>: <data>, | ||||||
|  | 						... | ||||||
|  | 					}, | ||||||
|  | 					... | ||||||
|  | 				}, | ||||||
|  | 			} | ||||||
|  | 		`,
 | ||||||
|  | 		function(mode, date){  | ||||||
|  | 			var store = {} | ||||||
|  | 			// populate the store...
 | ||||||
|  | 			Object.keys(this.store_handlers) | ||||||
|  | 				.forEach(function(key){ store[key] = {} }) | ||||||
|  | 			return { | ||||||
|  | 				mode: mode || 'full', | ||||||
|  | 				date: date || Date.timeStamp(), | ||||||
|  | 
 | ||||||
|  | 				store: store, | ||||||
|  | 			}  | ||||||
|  | 		}], | ||||||
|  | 	prepareStoreToLoad: ['- Store/', | ||||||
|  | 		core.doc` | ||||||
|  | 		 | ||||||
|  | 		NOTE: this can be called multiple times, once per each store. | ||||||
|  | 		NOTE: only one store data set is included per call.`,
 | ||||||
|  | 		function(data){ return data || {} }], | ||||||
|  | 	// XXX async???
 | ||||||
|  | 	// XXX we need to be able to save/load specific part of the data...
 | ||||||
|  | 	// 		...i.e. query by store and/or key...
 | ||||||
|  | 	saveData: ['- Store/', | ||||||
|  | 		function(mode, date){ | ||||||
|  | 			var handlers = this.store_handlers | ||||||
|  | 			var data = this.prepareStoreToSave(mode, date) | ||||||
|  | 			 | ||||||
|  | 			Object.keys(data.store).forEach(function(store){ | ||||||
|  | 				var handler = handlers[store] | ||||||
|  | 				handler  | ||||||
|  | 					&& this[handler].call(this, data.store[store]) | ||||||
|  | 			}.bind(this)) | ||||||
|  | 		}], | ||||||
|  | 	loadData: ['- Store/', | ||||||
|  | 		function(){ | ||||||
|  | 			var handlers = this.store_handlers | ||||||
|  | 			var data = {} | ||||||
|  | 			return Promise | ||||||
|  | 				.all(Object.keys(handlers) | ||||||
|  | 					.map(function(s){ | ||||||
|  | 						var res = this[handlers[s]]() | ||||||
|  | 						return res instanceof Promise ? | ||||||
|  | 							// async store...
 | ||||||
|  | 							res.then(function(d){ d  | ||||||
|  | 								&& (data[s] = d) | ||||||
|  | 								&& this.storeDataLoaded( | ||||||
|  | 									this.prepareStoreToLoad({[s]: d})) }.bind(this)) | ||||||
|  | 							// sync store...
 | ||||||
|  | 							: (res  | ||||||
|  | 								&& (data[s] = res) | ||||||
|  | 								&& this.storeDataLoaded( | ||||||
|  | 									this.prepareStoreToLoad({[s]: res}))) | ||||||
|  | 					}.bind(this)))  | ||||||
|  | 				.then(function(){ return data })}], | ||||||
|  | 	// XXX do we need to do a partial clear???
 | ||||||
|  | 	clearData: ['- Store/', | ||||||
|  | 		function(target){ | ||||||
|  | 			var handlers = this.store_handlers | ||||||
|  | 
 | ||||||
|  | 			Object.keys(handlers).forEach(function(store){ | ||||||
|  | 				var handler = handlers[store] | ||||||
|  | 				handler | ||||||
|  | 					&& this[handler].call(this, null) | ||||||
|  | 			}.bind(this)) | ||||||
|  | 		}], | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | var Store =  | ||||||
|  | module.Store = core.ImageGridFeatures.Feature({ | ||||||
|  | 	title: '', | ||||||
|  | 	doc: '', | ||||||
|  | 
 | ||||||
|  | 	tag: 'store', | ||||||
|  | 	depends: [ | ||||||
|  | 		'cache', | ||||||
|  | 	], | ||||||
|  | 	suggested: [ | ||||||
|  | 		'store-localstorage', | ||||||
|  | 	], | ||||||
|  | 	isApplicable: function(){ return typeof(localStorage) != 'undefined' }, | ||||||
|  | 
 | ||||||
|  | 	actions: StoreActions, | ||||||
|  | 
 | ||||||
|  | 	handlers: [ | ||||||
|  | 		['start.pre',  | ||||||
|  | 			function(){  | ||||||
|  | 				if(this.config['store-mode'] != null){ | ||||||
|  | 					this.requestReadyAnnounce() | ||||||
|  | 					this | ||||||
|  | 						.loadData()  | ||||||
|  | 						.then(function(){ | ||||||
|  | 							this.declareReady() }.bind(this))  | ||||||
|  | 				} }], | ||||||
|  | 		['stop',  | ||||||
|  | 			function(){  | ||||||
|  | 				this.config['store-mode'] == 'read-write' && this.saveData() }], | ||||||
|  | 		// XXX timer???
 | ||||||
|  | 		// XXX
 | ||||||
|  | 	], | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------
 | ||||||
|  | 
 | ||||||
|  | // XXX we should have a separate store config with settings of how to 
 | ||||||
|  | // 		load the store... (???)
 | ||||||
|  | var StoreLocalStorageActions = actions.Actions({ | ||||||
|  | 	config: { | ||||||
|  | 		'store-root-key': 'ImageGrid.Viewer.main', | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 	// XXX get root key from config...
 | ||||||
|  | 	// 		...this would require us to store the store config separately...
 | ||||||
|  | 	localStorageDataHandler: ['- Store/', | ||||||
|  | 		{handle_data_store: 'localStorage',}, | ||||||
|  | 		function(data){ | ||||||
|  | 			// XXX get this from config...
 | ||||||
|  | 			var root = this.config['store-root-key']  | ||||||
|  | 
 | ||||||
|  | 			// clear...
 | ||||||
|  | 			if(data === null){ | ||||||
|  | 				delete localStorage[root] | ||||||
|  | 
 | ||||||
|  | 			// set...
 | ||||||
|  | 			} else if(data){ | ||||||
|  | 				localStorage[root] = JSON.stringify(data) | ||||||
|  | 
 | ||||||
|  | 			// get...
 | ||||||
|  | 			} else { | ||||||
|  | 				var d = localStorage[root] | ||||||
|  | 				return d != undefined ? JSON.parse(d) : {} | ||||||
|  | 			} | ||||||
|  | 		}], | ||||||
|  | 	sessionStorageDataHandler: ['- Store/', | ||||||
|  | 		{handle_data_store: 'sessionStorage',}, | ||||||
|  | 		function(data){ | ||||||
|  | 			// XXX get this from config...
 | ||||||
|  | 			var root = this.config['store-root-key']  | ||||||
|  | 
 | ||||||
|  | 			// clear...
 | ||||||
|  | 			if(data === null){ | ||||||
|  | 				delete sessionStorage[root] | ||||||
|  | 
 | ||||||
|  | 			// set...
 | ||||||
|  | 			} else if(data){ | ||||||
|  | 				sessionStorage[root] = JSON.stringify(data) | ||||||
|  | 
 | ||||||
|  | 			// get...
 | ||||||
|  | 			} else { | ||||||
|  | 				var d = localStorage[root] | ||||||
|  | 				return d != undefined ? JSON.parse(d) : {} | ||||||
|  | 			} | ||||||
|  | 		}], | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | var StoreLocalStorage =  | ||||||
|  | module.StoreLocalStorage = core.ImageGridFeatures.Feature({ | ||||||
|  | 	title: '', | ||||||
|  | 	doc: '', | ||||||
|  | 
 | ||||||
|  | 	tag: 'store-localstorage', | ||||||
|  | 	depends: [ | ||||||
|  | 		'store', | ||||||
|  | 	], | ||||||
|  | 	isApplicable: function(){  | ||||||
|  | 		return typeof(localStorage) != 'undefined'  | ||||||
|  | 			&& typeof(sessionStorage) != 'undefined' }, | ||||||
|  | 
 | ||||||
|  | 	actions: StoreLocalStorageActions, | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------
 | ||||||
|  | 
 | ||||||
|  | // XXX StoreFSJSONSync
 | ||||||
|  | // 		Lookup order:
 | ||||||
|  | // 			- app dir
 | ||||||
|  | // 			- $HOME
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //---------------------------------------------------------------------
 | ||||||
|  | 
 | ||||||
|  | // XXX StoreFSJSON
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /********************************************************************** | ||||||
|  | * vim:set ts=4 sw=4 :                               */ return module }) | ||||||
| @ -485,7 +485,7 @@ module.SingleImageViewLocalStorage = core.ImageGridFeatures.Feature({ | |||||||
| 	tag: 'ui-single-image-local-storage', | 	tag: 'ui-single-image-local-storage', | ||||||
| 	depends: [ | 	depends: [ | ||||||
| 		'ui-single-image', | 		'ui-single-image', | ||||||
| 		'localstorage-config', | 		//'localstorage-config',
 | ||||||
| 	], | 	], | ||||||
| 
 | 
 | ||||||
| 	handlers:[ | 	handlers:[ | ||||||
|  | |||||||
							
								
								
									
										6
									
								
								ui (gen4)/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										6
									
								
								ui (gen4)/package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -1068,9 +1068,9 @@ | |||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "ig-features": { |     "ig-features": { | ||||||
|       "version": "3.3.2", |       "version": "3.3.3", | ||||||
|       "resolved": "https://registry.npmjs.org/ig-features/-/ig-features-3.3.2.tgz", |       "resolved": "https://registry.npmjs.org/ig-features/-/ig-features-3.3.3.tgz", | ||||||
|       "integrity": "sha512-NSvuVkLUI47f1mpG03/fVqJaMYLDUFVcg2FNXUtqvDqQqKhlZuXJfxsGcoFQ1eIZ1pqYcYeYHmjNbgmK6rT5cA==", |       "integrity": "sha512-EiX+ghvyFkgK2g+gXfALDXCBTAb/S99M9se31jMxkud/z5aZQnvXIrBwhDktt4YXUmeZ4ENvuibJYIZrdcCcmA==", | ||||||
|       "requires": { |       "requires": { | ||||||
|         "ig-actions": "3.15.0", |         "ig-actions": "3.15.0", | ||||||
|         "ig-object": "1.0.2" |         "ig-object": "1.0.2" | ||||||
|  | |||||||
| @ -27,7 +27,7 @@ | |||||||
|     "glob": "^4.0.6", |     "glob": "^4.0.6", | ||||||
|     "guarantee-events": "^1.0.0", |     "guarantee-events": "^1.0.0", | ||||||
|     "ig-actions": "^3.15.0", |     "ig-actions": "^3.15.0", | ||||||
|     "ig-features": "^3.3.2", |     "ig-features": "^3.3.3", | ||||||
|     "ig-object": "^1.0.2", |     "ig-object": "^1.0.2", | ||||||
|     "moment": "^2.20.1", |     "moment": "^2.20.1", | ||||||
|     "openseadragon": "^2.3.1", |     "openseadragon": "^2.3.1", | ||||||
|  | |||||||
| @ -72,6 +72,7 @@ $(function(){ | |||||||
| 
 | 
 | ||||||
| 	} catch(err){ | 	} catch(err){ | ||||||
| 		console.error(err) | 		console.error(err) | ||||||
|  | 		//throw err
 | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user