split out ui progress reporting...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2016-11-04 23:00:34 +03:00
parent 53d1ececc4
commit a7734d00b4
7 changed files with 224 additions and 128 deletions

View File

@ -21,6 +21,7 @@ require('features/ui')
require('features/ui-partial-ribbons')
require('features/ui-single-image')
require('features/ui-chrome')
require('features/ui-progress')
require('features/keyboard')
require('features/ui-status')
require('features/ui-marks')

View File

@ -366,6 +366,7 @@ var FileSystemLoaderActions = actions.Actions({
var that = this
// XXX get a logger...
logger = logger || this.logger
logger = logger && logger.push('Load')
if(path == null){
return
@ -570,6 +571,7 @@ var FileSystemLoaderActions = actions.Actions({
// XXX get a logger...
logger = logger || this.logger
//logger = logger && logger.push('getImagesInPath')
var that = this
path = util.normalizePath(path)
@ -641,6 +643,7 @@ var FileSystemLoaderActions = actions.Actions({
return
}
logger = logger || this.logger
logger = logger && logger.push('Load images')
var that = this
path = util.normalizePath(path)
@ -692,6 +695,7 @@ var FileSystemLoaderActions = actions.Actions({
var that = this
logger = logger || this.logger
logger = logger && logger.push('Load new images')
path = util.normalizePath(path)
// cache the loaded images...
@ -1105,6 +1109,7 @@ var FileSystemCommentsActions = actions.Actions({
}
logger = logger || this.logger
logger = logger && logger.push('saveComments')
var path = this.location.path
var comments_dir = this.config['index-dir'] +'/comments'
@ -1126,6 +1131,7 @@ var FileSystemCommentsActions = actions.Actions({
}
logger = logger || this.logger
logger = logger && logger.push('Load comments')
var that = this
var loaded = this.location.loaded
@ -1746,6 +1752,7 @@ var FileSystemWriterActions = actions.Actions({
var that = this
// XXX get a logger...
logger = logger || this.logger
logger = logger && logger.push('Save')
path = path || this.location.loaded
path = path && path.length == 1 ? path[0] : path
@ -1830,6 +1837,7 @@ var FileSystemWriterActions = actions.Actions({
exportIndex: ['- File/Export/Export index',
function(path, max_size, include_orig, logger){
logger = logger || this.logger
logger = logger && logger.push('Export index')
max_size = parseInt(max_size || this.config['export-preview-size-limit']) || null
// XXX make this dependant on max_size....
@ -1953,7 +1961,8 @@ var FileSystemWriterActions = actions.Actions({
index_path,
index.date,
this.config['index-filename-template'],
logger || this.logger)
logger)
//logger || this.logger)
// set hidden file attribute on Windows...
.then(function(){
typeof(process) != 'undefined'
@ -1996,6 +2005,7 @@ var FileSystemWriterActions = actions.Actions({
exportDirs: ['- File/Export/Export ribbons as directories',
function(path, pattern, level_dir, size, logger){
logger = logger || this.logger
logger = logger && logger.push('Export dirs')
var that = this
var base_dir = this.location.path

View File

@ -81,6 +81,7 @@ core.ImageGridFeatures.Feature('viewer-testing', [
'external-editor',
// chrome...
'ui-progress',
'ui-status-log',
'ui-scale',
'ui-animation',

162
ui (gen4)/features/ui-progress.js Executable file
View File

@ -0,0 +1,162 @@
/**********************************************************************
*
*
*
**********************************************************************/
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)(
function(require){ var module={} // makes module AMD/node compatible...
/*********************************************************************/
var actions = require('lib/actions')
var features = require('lib/features')
var core = require('features/core')
/*********************************************************************/
var ProgressActions = actions.Actions({
config: {
'progress-fade-duration': 200,
'progress-done-delay': 1000,
},
// Progress bar widget...
//
// Create progress bar...
// .testProgress('text')
//
// Update progress bar (value, max, msg)...
// .testProgress('text', 0, 10)
// .testProgress('text', 10, 50, 'message')
//
// Update progress bar value (has no effect if max is not set)...
// .testProgress('text', 10)
//
// Close progress bar...
// .testProgress('text', 'close')
//
// Relative progress modification...
// .testProgress('text', '+1')
// .testProgress('text', '+0', '+1')
//
//
// XXX move configuration to .config
// XXX should we report errors and stoppages??? (error state??)
// XXX multiple containers...
// XXX shorten the nested class names...
// XXX revise styles...
showProgress: ['- Interface/Show progress bar...',
function(text, value, max){
var viewer = this.ribbons.viewer
var that = this
var msg = text instanceof Array ? text.slice(1).join(': ') : null
text = text instanceof Array ? text[0] : text
// container...
var container = viewer.find('.progress-container')
container = container.length == 0 ?
$('<div/>')
.addClass('progress-container')
.appendTo(viewer)
: container
// widget...
var widget = container.find('.progress-bar[name="'+text+'"]')
// close action...
if(value == 'close'){
widget.trigger('progressClose')
return
}
widget = widget.length == 0 ?
$('<div/>')
.addClass('progress-bar')
.attr('name', text)
.text(text)
// close button...
.append($('<span class="close">&times;</span>')
.on('click', function(){ widget.trigger('progressClose') }))
// state...
.append($('<span/>')
.addClass('progress-details'))
// bar...
.append($('<progress/>'))
// events...
.on('progressClose', function(){
widget
.fadeOut(that.config['progress-fade-duration'] || 200, function(){
$(this).remove()
})
})
.appendTo(container)
: widget
// reset closing timeout...
var timeout = widget.attr('close-timeout')
timeout && clearTimeout(JSON.parse(timeout))
// get the widget parts we are updating...
var bar = widget.find('progress')
var state = widget.find('.progress-details')
// XXX stub???
// normalize max and value...
max = max != null ?
(typeof(max) == typeof('str') && /[+-][0-9]+/.test(max) ?
parseInt(bar.attr('max') || 0) + parseInt(max)
: parseInt(max))
: bar.attr('max')
value = value != null ?
(typeof(value) == typeof('str') && /[+-][0-9]+/.test(value) ?
parseInt(bar.attr('value') || 0) + parseInt(value)
: parseInt(value))
: bar.attr('value')
// format the message...
msg = msg ? ': '+msg : ''
msg = ' '+ msg
//+ (value && value >= (max || 0) ? ' ('+value+' done)'
+ (value && value >= (max || 0) ? ' (done)'
: value && max && value != max ? ' ('+ value +' of '+ max +')'
: '...')
// update widget...
bar.attr({
value: value || '',
max: max || '',
})
state.text(msg)
// auto-close...
// XXX make this optional...
if(value && value >= (max || 0)){
widget.attr('close-timeout',
JSON.stringify(setTimeout(function(){
widget.trigger('progressClose')
}, this.config['progress-done-delay'] || 1000)))
}
// XXX what should we return??? (state, self, controller?)
}],
})
var Progress =
module.Progress = core.ImageGridFeatures.Feature({
title: '',
doc: '',
tag: 'ui-progress',
depends: [
'ui',
],
actions: ProgressActions,
})
/**********************************************************************
* vim:set ts=4 sw=4 : */ return module })

View File

@ -1111,121 +1111,6 @@ var WidgetTestActions = actions.Actions({
})],
// Progress bar widget...
//
// Create progress bar...
// .testProgress('text')
//
// Update progress bar (value, max, msg)...
// .testProgress('text', 0, 10)
// .testProgress('text', 10, 50, 'message')
//
// Update progress bar value (has no effect if max is not set)...
// .testProgress('text', 10)
//
// Close progress bar...
// .testProgress('text', 'close')
//
// Relative progress modification...
// .testProgress('text', '+1')
// .testProgress('text', '+0', '+1')
//
//
// XXX should we report errors and stoppages??? (error state??)
// XXX multiple containers...
// XXX shorten the nested class names...
// XXX revise styles...
showProgress: ['- Interface/Show progress bar...',
function(text, value, max){
var viewer = this.ribbons.viewer
var msg = text instanceof Array ? text.slice(1).join(': ') : null
text = text instanceof Array ? text[0] : text
// container...
var container = viewer.find('.progress-container')
container = container.length == 0 ?
$('<div/>')
.addClass('progress-container')
.appendTo(viewer)
: container
// widget...
var widget = container.find('.progress-bar[name="'+text+'"]')
// close action...
if(value == 'close'){
widget.trigger('progressClose')
return
}
widget = widget.length == 0 ?
$('<div/>')
.addClass('progress-bar')
.attr('name', text)
.text(text)
// close button...
.append($('<span class="close">&times;</span>')
.on('click', function(){ widget.trigger('progressClose') }))
// state...
.append($('<span/>')
.addClass('progress-details'))
// bar...
.append($('<progress/>'))
// events...
.on('progressClose', function(){
widget
.fadeOut(200, function(){
$(this).remove()
})
})
.appendTo(container)
: widget
// reset closing timeout...
var timeout = widget.attr('close-timeout')
timeout && clearTimeout(JSON.parse(timeout))
// get the widget parts we are updating...
var bar = widget.find('progress')
var state = widget.find('.progress-details')
// XXX stub???
// normalize max and value...
max = max != null ?
(typeof(max) == typeof('str') && /[+-][0-9]+/.test(max) ?
parseInt(bar.attr('max') || 0) + parseInt(max)
: parseInt(max))
: bar.attr('max')
value = value != null ?
(typeof(value) == typeof('str') && /[+-][0-9]+/.test(value) ?
parseInt(bar.attr('value') || 0) + parseInt(value)
: parseInt(value))
: bar.attr('value')
// format the message...
msg = msg ? ': '+msg : ''
msg = ' '+ msg
+ (value && value >= (max || 0) ? ' ('+value+' done)'
: value && max && value != max ? ' ('+ value +' of '+ max +')'
: ' (ready)')
// update widget...
bar.attr({
value: value || '',
max: max || '',
})
state.text(msg)
// auto-close...
// XXX make this optional...
if(value && value >= (max || 0)){
widget.attr('close-timeout',
JSON.stringify(setTimeout(function(){
widget.trigger('progressClose')
}, 1000)))
}
// XXX what should we return??? (state, self, controller?)
}],
testProgress: ['Test/Demo progress bar...',
function(text){
var done = 0

View File

@ -40,6 +40,8 @@ var INDEX_DIR = '.ImageGrid'
// Skip nested indexes from tree...
//
var skipNested = function(paths, index_dir, logger){
logger = logger && logger.push('Skipping nested')
paths = paths
.map(function(p){ return p.split(index_dir).shift() })
.sort(function(a, b){ return a.length - b.length })
@ -107,6 +109,8 @@ function(base, index_dir){
var getIndexes =
module.getIndexes =
function(base, index_dir, logger){
logger = logger && logger.push('Searching')
return new Promise(function(resolve, reject){
listIndexes(base, index_dir)
.on('error', function(err){
@ -243,6 +247,8 @@ function(list){
var groupByKeyword =
module.groupByKeyword =
function(list, from_date, logger){
logger = logger && logger.push('Grouping by keyword')
var index = {}
var queued = 0
@ -328,6 +334,8 @@ function(list, from_date, logger){
var loadSaveHistoryList =
module.loadSaveHistoryList =
function(path, index_dir, logger){
logger = logger && logger.push('Save history')
path = util.normalizePath(path)
index_dir = index_dir || INDEX_DIR
@ -467,6 +475,8 @@ function(path, index_dir, logger){
var loadIndex =
module.loadIndex =
function(path, index_dir, from_date, logger){
logger = logger && logger.push('Index')
path = util.normalizePath(path)
if(index_dir && index_dir.emit != null){
@ -921,6 +931,8 @@ var FILENAME = '${DATE}-${KEYWORD}.${EXT}'
var writeIndex =
module.writeIndex =
function(json, path, date, filename_tpl, logger){
logger = logger && logger.push('Index')
path = util.normalizePath(path)
filename_tpl = filename_tpl || FILENAME
// XXX for some reason this gets the unpatched node.js Date, so we

View File

@ -143,19 +143,44 @@ $(function(){
ig.features.features.length,
ig.features.features)
ig.logger = ig.logger || {emit: function(e, v){
console.log(' ', e, v)
// XXX HACK -- need meaningful status...
if(e == 'queued'
|| e == 'found'){
ig.showProgress('Progress', '+0', '+1')
// XXX STUB...
ig.logger = ig.logger || {
root: true,
message: null,
} else if(e == 'loaded' || e == 'done' || e == 'written'
|| e == 'skipping' || e == 'index'){
ig.showProgress('Progress', '+1')
}
}}
emit: function(e, v){
var msg = this.message
// console...
console.log(' '+ ((msg && msg.concat('')) || []).join(': '), e, v)
// progress...
// XXX HACK -- need meaningful status...
if(e == 'queued'
|| e == 'found'){
ig.showProgress(msg || ['Progress', e], '+0', '+1')
} else if(e == 'loaded' || e == 'done' || e == 'written'
|| e == 'skipping' || e == 'index'){
ig.showProgress(msg || ['Progress', e], '+1')
}
},
push: function(msg){
if(msg == null){
return this
}
var logger = Object.create(this)
logger.root = false
logger.message = logger.message == null ? [msg] : logger.message.concat([msg])
return logger
},
pop: function(){
return !this.__proto__.root ? this.__proto__ : this
},
}
// setup the viewer...