mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-31 03:10:07 +00:00 
			
		
		
		
	simplified the custom dialog constructing -- still not too happy with it + some preliminary work on exporting...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									de0136c614
								
							
						
					
					
						commit
						4063cc4898
					
				| @ -33,6 +33,15 @@ var browseWalk = require('lib/widget/browse-walk') | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | /*********************************************************************/ | ||||||
|  | 
 | ||||||
|  | if(typeof(process) != 'undefined'){ | ||||||
|  | 	var copy = file.denodeify(fse.copy) | ||||||
|  | 	var ensureDir = file.denodeify(fse.ensureDir) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /*********************************************************************/ | /*********************************************************************/ | ||||||
| // fs reader/loader...
 | // fs reader/loader...
 | ||||||
| 
 | 
 | ||||||
| @ -758,17 +767,21 @@ var FileSystemWriterActions = actions.Actions({ | |||||||
| 	exportView: ['File/Export current view', | 	exportView: ['File/Export current view', | ||||||
| 		function(){ | 		function(){ | ||||||
| 		}], | 		}], | ||||||
| 	// XXX not done yet...
 | 
 | ||||||
| 	// 		needs:
 | 	// Export current state as a full loadable index
 | ||||||
| 	// 			ensureDir(..)
 | 	//
 | ||||||
| 	// 			copy(..)
 |  | ||||||
| 	// 		...both denodeify(..)'ed
 |  | ||||||
| 	// XXX export current state as a full loadable index
 |  | ||||||
| 	// XXX might be interesting to unify this and .exportView(..)
 | 	// XXX might be interesting to unify this and .exportView(..)
 | ||||||
| 	// XXX should this return a promise??? ...a clean promise???
 | 	// XXX should this return a promise??? ...a clean promise???
 | ||||||
|  | 	// XXX add preview selection...
 | ||||||
|  | 	// XXX handle .image.path and other stack files...
 | ||||||
| 	// XXX local collections???
 | 	// XXX local collections???
 | ||||||
|  | 	// XXX add a ui...
 | ||||||
|  | 	// 		- select path
 | ||||||
|  | 	// 		- select preview size
 | ||||||
| 	exportCollection: ['File/Export as collection', | 	exportCollection: ['File/Export as collection', | ||||||
| 		function(path, logger){ | 		function(path, logger){ | ||||||
|  | 			logger = logger || this.logger | ||||||
|  | 
 | ||||||
| 			var json = this.json() | 			var json = this.json() | ||||||
| 
 | 
 | ||||||
| 			// get all loaded gids...
 | 			// get all loaded gids...
 | ||||||
| @ -785,6 +798,7 @@ var FileSystemWriterActions = actions.Actions({ | |||||||
| 				var img = json.images[gid] | 				var img = json.images[gid] | ||||||
| 				if(img){ | 				if(img){ | ||||||
| 					images[gid] = json.images[gid] | 					images[gid] = json.images[gid] | ||||||
|  | 
 | ||||||
| 					// remove un-needed previews...
 | 					// remove un-needed previews...
 | ||||||
| 					// XXX
 | 					// XXX
 | ||||||
| 				} | 				} | ||||||
| @ -794,26 +808,27 @@ var FileSystemWriterActions = actions.Actions({ | |||||||
| 			json.data.order = gids | 			json.data.order = gids | ||||||
| 			json.images = images | 			json.images = images | ||||||
| 			// XXX should we check if index dir is present in path???
 | 			// XXX should we check if index dir is present in path???
 | ||||||
| 			path = path +'/'+ this.config['index-dir'] | 			var index_path = path +'/'+ this.config['index-dir'] | ||||||
| 
 |  | ||||||
| 			// NOTE: if we are to use .saveIndex(..) here, do not forget
 |  | ||||||
| 			// 		to reset .changes
 |  | ||||||
| 			file.writeIndex( |  | ||||||
| 				this.prepareIndexForWrite(json).prepared,  |  | ||||||
| 				path,  |  | ||||||
| 				this.config['index-filename-template'],  |  | ||||||
| 				logger || this.logger) |  | ||||||
| 
 | 
 | ||||||
| 			// copy previews for the loaded images...
 | 			// copy previews for the loaded images...
 | ||||||
| 			// XXX should also optionally populate the base dir and nested favs...
 | 			// XXX should also optionally populate the base dir and nested favs...
 | ||||||
| 			var base_dir = this.base_dir | 			var base_dir = this.location.path | ||||||
|  | 
 | ||||||
| 			gids.forEach(function(gid){ | 			gids.forEach(function(gid){ | ||||||
| 				var img = json.images[gid] | 				var img = json.images[gid] | ||||||
| 				var img_base = img.base_path | 				var img_base = img.base_path | ||||||
| 				img.base_path = path |  | ||||||
| 				var previews = img.preview | 				var previews = img.preview | ||||||
| 
 | 
 | ||||||
| 				for(var res in previews){ | 				// NOTE: we are copying everything to one place so no 
 | ||||||
|  | 				// 		need for a base path...
 | ||||||
|  | 				delete img.base_path | ||||||
|  | 
 | ||||||
|  | 				// XXX copy img.path -- the main image, especially when no previews present....
 | ||||||
|  | 				// XXX
 | ||||||
|  | 
 | ||||||
|  | 				Object.keys(previews).forEach(function(res){ | ||||||
|  | 					var preview_path = decodeURI(previews[res])  | ||||||
|  | 
 | ||||||
| 					var from = (img_base || base_dir) +'/'+ preview_path | 					var from = (img_base || base_dir) +'/'+ preview_path | ||||||
| 					var to = path +'/'+ preview_path | 					var to = path +'/'+ preview_path | ||||||
| 
 | 
 | ||||||
| @ -823,7 +838,7 @@ var FileSystemWriterActions = actions.Actions({ | |||||||
| 					// XXX
 | 					// XXX
 | ||||||
| 					ensureDir(pathlib.dirname(to)) | 					ensureDir(pathlib.dirname(to)) | ||||||
| 						.catch(function(err){ | 						.catch(function(err){ | ||||||
| 							// XXX
 | 							logger && logger.emit('error', err) | ||||||
| 						}) | 						}) | ||||||
| 						.then(function(){ | 						.then(function(){ | ||||||
| 							return copy(from, to) | 							return copy(from, to) | ||||||
| @ -832,12 +847,99 @@ var FileSystemWriterActions = actions.Actions({ | |||||||
| 								// 		we just use the one above (after
 | 								// 		we just use the one above (after
 | ||||||
| 								// 		.then(..))
 | 								// 		.then(..))
 | ||||||
| 								.catch(function(err){ | 								.catch(function(err){ | ||||||
| 									// XXX
 | 									logger && logger.emit('error', err) | ||||||
|  | 								}) | ||||||
|  | 								.then(function(){ | ||||||
|  | 									logger && logger.emit('done', to) | ||||||
| 								}) | 								}) | ||||||
| 						}) | 						}) | ||||||
| 				} | 				}) | ||||||
| 			}) | 			}) | ||||||
|  | 
 | ||||||
|  | 			// NOTE: if we are to use .saveIndex(..) here, do not forget
 | ||||||
|  | 			// 		to reset .changes
 | ||||||
|  | 			file.writeIndex( | ||||||
|  | 				this.prepareIndexForWrite(json, true).prepared,  | ||||||
|  | 				index_path,  | ||||||
|  | 				this.config['index-filename-template'],  | ||||||
|  | 				logger || this.logger) | ||||||
|  | 			 | ||||||
| 		}], | 		}], | ||||||
|  | 	 | ||||||
|  | 	// XXX use options:
 | ||||||
|  | 	// 		- level dir name
 | ||||||
|  | 	// 		- size
 | ||||||
|  | 	// 		- filename pattern
 | ||||||
|  | 	// XXX might also be good to save/load the export state to .ImageGrid-export.json
 | ||||||
|  | 	// XXX make custom previews...
 | ||||||
|  | 	// 		...should this be a function of .images.getBestPreview(..)???
 | ||||||
|  | 	exportDirs: ['File/Export as nested directories', | ||||||
|  | 		function(path, pattern, level_dir, size, logger){ | ||||||
|  | 			logger = logger || this.logger | ||||||
|  | 			var that = this | ||||||
|  | 			var base_dir = this.location.path | ||||||
|  | 			var to_dir = path | ||||||
|  | 
 | ||||||
|  | 			// get/set the config data...
 | ||||||
|  | 			// XXX should this store the last set???
 | ||||||
|  | 			level_dir = level_dir || this.config['export-level-directory-name'] || 'fav' | ||||||
|  | 			size = size || this.config['export-preview-size'] || 1000 | ||||||
|  | 			pattern = pattern || this.config['export-preview-name-pattern'] || '%f' | ||||||
|  | 
 | ||||||
|  | 			this.data.ribbon_order | ||||||
|  | 				.slice() | ||||||
|  | 				.reverse() | ||||||
|  | 				.forEach(function(ribbon){ | ||||||
|  | 					// NOTE: this is here to keep the specific path local to 
 | ||||||
|  | 					// 		this scope...
 | ||||||
|  | 					var img_dir = to_dir | ||||||
|  | 
 | ||||||
|  | 					ensureDir(pathlib.dirname(img_dir)) | ||||||
|  | 						.catch(function(err){ | ||||||
|  | 							logger && logger.emit('error', err) | ||||||
|  | 						}) | ||||||
|  | 						.then(function(){ | ||||||
|  | 							that.data.ribbons[ribbon].forEach(function(gid){ | ||||||
|  | 								var img = that.images[gid] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 								// get best preview...
 | ||||||
|  | 								var from = (img.base_path || base_dir) +'/'+ that.images.getBestPreview(gid, size).url | ||||||
|  | 
 | ||||||
|  | 								// XXX see if we need to make a preview (sharp)
 | ||||||
|  | 								// XXX
 | ||||||
|  | 
 | ||||||
|  | 								// XXX get/form image name... 
 | ||||||
|  | 								// XXX might be a good idea to connect this to the info framework...
 | ||||||
|  | 								var ext = pathlib.extname(img.name) | ||||||
|  | 								var name = pattern | ||||||
|  | 									.replace(/%f/, img.name) | ||||||
|  | 									.replace(/%n/, img.name.replace(ext, '')) | ||||||
|  | 									.replace(/%e/, ext) | ||||||
|  | 									.replace(/%gid/, gid) | ||||||
|  | 									// XXX get the correct length...
 | ||||||
|  | 									.replace(/%g/, gid.slice(-7, -1)) | ||||||
|  | 									// XXX %()m marked...
 | ||||||
|  | 									// XXX
 | ||||||
|  | 									// XXX %()b bookmarked...
 | ||||||
|  | 									// XXX
 | ||||||
|  | 									// XXX EXIF...
 | ||||||
|  | 
 | ||||||
|  | 								var to = img_dir +'/'+ name | ||||||
|  | 
 | ||||||
|  | 								copy(from, to) | ||||||
|  | 									.catch(function(err){ | ||||||
|  | 										logger && logger.emit('error', err) | ||||||
|  | 									}) | ||||||
|  | 									.then(function(){ | ||||||
|  | 										logger && logger.emit('done', to) | ||||||
|  | 									}) | ||||||
|  | 							}) | ||||||
|  | 						}) | ||||||
|  | 
 | ||||||
|  | 					to_dir += '/'+level_dir | ||||||
|  | 				}) | ||||||
|  | 		}] | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -57,33 +57,25 @@ var SlideshowActions = actions.Actions({ | |||||||
| 
 | 
 | ||||||
| 			this.suspendSlideshowTimer() | 			this.suspendSlideshowTimer() | ||||||
| 
 | 
 | ||||||
|  | 			// XXX might be a good idea to make this generic...
 | ||||||
|  | 			var _makeTogglHandler = function(toggler){ | ||||||
|  | 				return function(){ | ||||||
|  | 					var txt = $(this).find('.text').first().text() | ||||||
|  | 					that[toggler]() | ||||||
|  | 					o.client.update() | ||||||
|  | 						.then(function(){ o.client.select(txt) }) | ||||||
|  | 					that.toggleSlideshow('?') == 'on'  | ||||||
|  | 						&& o.close() | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
| 			var o = overlay.Overlay(this.ribbons.viewer,  | 			var o = overlay.Overlay(this.ribbons.viewer,  | ||||||
| 				browse.makeList( | 				browse.makeLister(null, function(path, make){ | ||||||
| 					null, | 					make(['Interval: ',  | ||||||
| 					[ | 							function(){ return that.config['slideshow-interval'] }]) | ||||||
| 						// XXX make this editable...
 | 						.on('open', function(){ | ||||||
| 						['Interval: ',  | 							var txt = $(this).find('.text').first().text() | ||||||
| 							function(){ return that.config['slideshow-interval'] }], |  | ||||||
| 						['Direction: ',  |  | ||||||
| 							function(){ return that.config['slideshow-direction'] }], |  | ||||||
| 						['Looping: ',  |  | ||||||
| 							function(){ return that.config['slideshow-looping'] }], |  | ||||||
| 
 | 
 | ||||||
| 						//'---',
 |  | ||||||
| 						[function(){  |  | ||||||
| 							return that.toggleSlideshow('?') == 'on' ? 'Stop' : 'Start' }], |  | ||||||
| 					]) |  | ||||||
| 					.open(function(evt, path){ |  | ||||||
| 						// start/stop...
 |  | ||||||
| 						if(path == 'Start' || path == 'Stop'){ |  | ||||||
| 							that.toggleSlideshow() |  | ||||||
| 							o.close() |  | ||||||
| 							return |  | ||||||
| 						} |  | ||||||
| 
 |  | ||||||
| 						// interval...
 |  | ||||||
| 						if(/interval/i.test(path)){ |  | ||||||
| 							var to_remove = [] |  | ||||||
| 							var oo = widgets.makeConfigListEditor(that, 'slideshow-intervals', { | 							var oo = widgets.makeConfigListEditor(that, 'slideshow-intervals', { | ||||||
| 									new_button: 'New...', | 									new_button: 'New...', | ||||||
| 									length_limit: that.config['slideshow-interval-max-count'], | 									length_limit: that.config['slideshow-interval-max-count'], | ||||||
| @ -107,9 +99,8 @@ var SlideshowActions = actions.Actions({ | |||||||
| 									// XXX this is ugly...
 | 									// XXX this is ugly...
 | ||||||
| 									o.focus() | 									o.focus() | ||||||
| 
 | 
 | ||||||
| 									if(that.toggleSlideshow('?') == 'on'){ | 									that.toggleSlideshow('?') == 'on' | ||||||
| 										o.close() | 										&& o.close() | ||||||
| 									} |  | ||||||
| 								}) | 								}) | ||||||
| 
 | 
 | ||||||
| 							oo.client | 							oo.client | ||||||
| @ -122,42 +113,36 @@ var SlideshowActions = actions.Actions({ | |||||||
| 
 | 
 | ||||||
| 										// XXX this is ugly...
 | 										// XXX this is ugly...
 | ||||||
| 										oo.close() | 										oo.close() | ||||||
|  | 
 | ||||||
| 										o.client.update() | 										o.client.update() | ||||||
| 										o.client.select(path.split(':')[0]) | 										o.client.select(txt) | ||||||
| 									} | 									} | ||||||
| 								}) | 								}) | ||||||
| 
 | 
 | ||||||
| 							oo.client.dom.addClass('tail-action') | 							oo.client.dom.addClass('tail-action') | ||||||
| 							oo.client.select(that.config['slideshow-interval']) | 							oo.client.select(that.config['slideshow-interval']) | ||||||
|  | 						}) | ||||||
| 
 | 
 | ||||||
| 							return | 					make(['Direction: ',  | ||||||
| 						} | 							function(){ return that.config['slideshow-direction'] }]) | ||||||
|  | 						.on('open', _makeTogglHandler('toggleSlideshowDirection')) | ||||||
|  | 					make(['Looping: ',  | ||||||
|  | 							function(){ return that.config['slideshow-looping'] }]) | ||||||
|  | 						.on('open', _makeTogglHandler('toggleSlideshowLooping')) | ||||||
| 
 | 
 | ||||||
| 						// direction...
 | 					// Start/stop...
 | ||||||
| 						if(/direction/i.test(path)){ | 					make([function(){  | ||||||
| 							that.toggleSlideshowDirection() | 							return that.toggleSlideshow('?') == 'on' ? 'Stop' : 'Start' }]) | ||||||
| 							o.client.update() | 						.on('open', function(){ | ||||||
| 
 | 							that.toggleSlideshow() | ||||||
| 						// Looping...
 |  | ||||||
| 						} else if(/looping/i.test(path)){ |  | ||||||
| 							that.toggleSlideshowLooping() |  | ||||||
| 							o.client.update() |  | ||||||
| 						} |  | ||||||
| 
 |  | ||||||
| 						// XXX this is ugly...
 |  | ||||||
| 						o.client.select(path.split(':')[0]) |  | ||||||
| 
 |  | ||||||
| 						// do not keep the dialog open during the slideshow...
 |  | ||||||
| 						if(that.toggleSlideshow('?') == 'on'){ |  | ||||||
| 							o.close() | 							o.close() | ||||||
| 						} | 						}) | ||||||
| 					})) | 				})) | ||||||
| 				.close(function(){ | 				.close(function(){ | ||||||
| 					that.resetSlideshowTimer() | 					that.resetSlideshowTimer() | ||||||
| 				}) | 				}) | ||||||
| 
 | 
 | ||||||
| 			o.client.dom.addClass('metadata-view tail-action') | 			o.client.dom.addClass('metadata-view tail-action') | ||||||
| 
 |  | ||||||
| 			o.client.select(-1) | 			o.client.select(-1) | ||||||
| 
 | 
 | ||||||
| 			return o | 			return o | ||||||
|  | |||||||
| @ -94,8 +94,15 @@ function listJSON(path, pattern){ | |||||||
| 	return gGlob(path +'/'+ pattern +'.json') | 	return gGlob(path +'/'+ pattern +'.json') | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // wrap a node style callback function into a Promise...
 | ||||||
|  | //
 | ||||||
|  | // NOTE: this is inspired by the promise module for node this stopped 
 | ||||||
|  | // 		working, and porting one method was simpler that trying to get
 | ||||||
|  | // 		to the bottom of the issue, especially with native promises...
 | ||||||
| // XXX move to someplace generic...
 | // XXX move to someplace generic...
 | ||||||
| var denodeify = function(func){ | var denodeify =  | ||||||
|  | module.denodeify = | ||||||
|  | function(func){ | ||||||
| 	return function(){ | 	return function(){ | ||||||
| 		// XXX for some reason this does not see args2array...
 | 		// XXX for some reason this does not see args2array...
 | ||||||
| 		// XXX and for some reason the error is not reported...
 | 		// XXX and for some reason the error is not reported...
 | ||||||
|  | |||||||
| @ -2189,6 +2189,48 @@ Browser.prototype.__proto__ = widget.Widget.prototype | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | /*********************************************************************/ | ||||||
|  | 
 | ||||||
|  | var ListerPrototype = Object.create(BrowserPrototype) | ||||||
|  | ListerPrototype.options = { | ||||||
|  | 	pathPrefix: '',  | ||||||
|  | 	fullPathEdit: false, | ||||||
|  | 	traversable: false, | ||||||
|  | 	flat: true, | ||||||
|  | 
 | ||||||
|  | 	// XXX not sure if we need these...
 | ||||||
|  | 	skipDisabledItems: false, | ||||||
|  | 	// NOTE: to disable this set it to false or null
 | ||||||
|  | 	disableItemPattern: '^- ', | ||||||
|  | 
 | ||||||
|  | 	elementSeparatorText: '---', | ||||||
|  | } | ||||||
|  | // XXX should we inherit or copy options???
 | ||||||
|  | // 		...inheriting might pose problems with deleting values reverting
 | ||||||
|  | // 		them to default instead of nulling them and mutable options might
 | ||||||
|  | // 		get overwritten...
 | ||||||
|  | ListerPrototype.options.__proto__ = BrowserPrototype.options | ||||||
|  | 
 | ||||||
|  | var Lister =  | ||||||
|  | module.Lister =  | ||||||
|  | object.makeConstructor('Lister',  | ||||||
|  | 		BrowserClassPrototype,  | ||||||
|  | 		ListerPrototype) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // This is a shorthand for: new List(<elem>, { data: <list> })
 | ||||||
|  | var makeLister =  | ||||||
|  | module.makeLister = function(elem, lister, options){ | ||||||
|  | 	var opts = {} | ||||||
|  | 	for(var k in options){ | ||||||
|  | 		opts[k] = rest[k] | ||||||
|  | 	} | ||||||
|  | 	opts.list = lister | ||||||
|  | 	return Lister(elem, opts) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| /*********************************************************************/ | /*********************************************************************/ | ||||||
| 
 | 
 | ||||||
| // Flat list...
 | // Flat list...
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user