reworked the location feature...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2016-06-05 03:46:24 +03:00
parent d58df1d2dc
commit 9a5c9689ee
2 changed files with 158 additions and 94 deletions

View File

@ -125,17 +125,9 @@ var FileSystemLoaderActions = actions.Actions({
'image-file-read-stat': true, 'image-file-read-stat': true,
'image-file-skip-previews': false, 'image-file-skip-previews': false,
},
// XXX should this be more general??? 'default-load-method': 'loadIndex',
reloadState: ['File/Reload viewer state...', },
function(){
if(this.location
&& this.location.method
&& this.location.path){
return this[this.location.method](this.location.path)
}
}],
// XXX is this a hack??? // XXX is this a hack???
// XXX need a more generic form... // XXX need a more generic form...
@ -253,18 +245,18 @@ var FileSystemLoaderActions = actions.Actions({
logger && logger.emit('load index', index) logger && logger.emit('load index', index)
// prepare the location data... // prepare the location data...
var location = { index.location = {
path: path, path: path,
loaded: loaded, loaded: loaded,
method: 'loadIndex', method: 'loadIndex',
} }
if(from_date){ if(from_date){
location.from = from_date index.location.from = from_date
} }
// this is the critical section, after this point we // this is the critical section, after this point we
// are doing the actual loading.... // are doing the actual loading....
that.recoverableLoad(function(){ that.load(index) }, location) that.loadOrRecover(index)
}) })
}], }],
@ -449,16 +441,14 @@ var FileSystemLoaderActions = actions.Actions({
logger) logger)
// load the data... // load the data...
.then(function(imgs){ .then(function(imgs){
that.recoverableLoad(function(){ that.loadOrRecover({
images: imgs,
data: data.Data.fromArray(imgs.keys()),
that.load({ location: {
images: imgs, path: path,
data: data.Data.fromArray(imgs.keys()), method: 'loadImages',
}) }
}, {
path: path,
method: 'loadImages',
}) })
}) })
}], }],

View File

@ -19,19 +19,20 @@ var core = require('features/core')
/*********************************************************************/ /*********************************************************************/
// XXX add url scheme support...
// <method>://<path>#<current>?<other>
// XXX add .hash support for in-location .current setting when no index // XXX add .hash support for in-location .current setting when no index
// available... // available...
// XXX should this or LocationLocalStorage save/load location (now it's
// done by history)
// XXX this should provide mechaincs to define location handlers, i.e. // XXX this should provide mechaincs to define location handlers, i.e.
// a set for loader/saver per location type (.method) // a set for loader/saver per location type (.method)
// XXX revise the wording... // XXX revise the wording...
// .method?
// .path or .url // .path or .url
var LocationActions = actions.Actions({ var LocationActions = actions.Actions({
config: { config: {
'recover-load-errors-to-previous-location': true, 'recover-load-errors-to-previous-location': true,
'default-load-method': null,
}, },
// Format: // Format:
@ -39,6 +40,7 @@ var LocationActions = actions.Actions({
// path: <base-path>, // path: <base-path>,
// method: <load-method>, // method: <load-method>,
// current: <current-gid>, // current: <current-gid>,
// ...
// } // }
// //
// NOTE: these will remove the trailing '/' (or '\') from .path // NOTE: these will remove the trailing '/' (or '\') from .path
@ -64,69 +66,104 @@ var LocationActions = actions.Actions({
return this.__location return this.__location
}, },
// XXX is 'loadIndex' a good default??? // NOTE: this is a shorthand for .loadLocation(..)
// NOTE: the method is needed to enable us to get the action return
// value...
set location(value){ set location(value){
// got a path... this.loadLocation(value)
if(typeof(value) == typeof('str')){
var path = value
// XXX get a better reasonable default...
var method = this.__location
&& this.__location.method
|| undefined
var cur = this.current
// got an object...
} else {
value = JSON.parse(JSON.stringify(value))
var path = value.path = value.path
value.method = value.method
value.current = value.current
}
// normalize path if it's not root...
if(path != '/' && path != '\\'){
value.path = util.normalizePath(path)
}
this.__location = value
// XXX is 'loadIndex' a good default???
var res = this[value.method || 'loadIndex'](path)
// XXX load current...
if(res.then != null){
res.then(function(){
this.current = cur
})
} else {
this.current = cur
}
}, },
// Wrap the loader and recover if it fails...
//
// .recoverableLoad(loader, new-location)
// -> actions
//
// NOTE: this avoids load loops by attempting to recover only once...
//
// XXX should this be used in .location setter???
// XXX should this throw the error after recovering???
recoverableLoad: ['- Location/',
function(loader, location){
// this is the critical section, after this point we
// are doing the actual loading....
try {
// prepare to recover, just in case...
this.__recover = (this.__recover !== false
&& this.config['recover-load-errors-to-previous-location']) ?
this.location
: false
loader() // Load location...
//
// Reload current location...
// .loadLocation()
// -> result
//
// Load new path using current location method and data...
// .loadLocation(path)
// -> result
//
// Load new location...
// .loadLocation(location)
// -> result
// NOTE: this is almost the same as .location = location but
// here we can access the call return value.
//
// XXX not sure about where to set the .__location -- see inside...
loadLocation: ['File/Load location',
function(location){
location = location || this.location
// got a path -> load using current location data...
if(typeof(location) == typeof('str')){
location = {
path: path,
method: (this.__location && this.__location.method)
|| this.config['default-load-method'],
current: this.current,
}
// got an object...
} else {
// clone the location...
location = JSON.parse(JSON.stringify(location))
}
var method = location.method
|| this.location.method
|| this.config['default-load-method']
var cur = location.current
var path = location.path
// normalize path if it's not root...
if(path != '/' && path != '\\'){
path = location.path = util.normalizePath(path)
}
// XXX ???
this.__location = location
// NOTE: the method should set the proper location if it uses .clear()...
var res = method && this[method](path)
// load current...
if(cur){
if(res && res.then != null){
var that = this
res.then(function(){
that.current = cur
})
} else {
this.current = cur
}
}
return res
}],
// Load index with recovery...
//
// This will:
// - save recovery data (.__recover)
// - load
// - clear recovery data (if load successful)
//
// NOTE: for more info on the load protocol see: base.BaseActions.load
load: [
function(data){
var location = data.location
// prepare to recover, just in case...
this.__recover = (this.__recover !== false
&& this.config['recover-load-errors-to-previous-location']) ?
this.location
: false
return function(){
// NOTE: we are setting this after the load because the // NOTE: we are setting this after the load because the
// loader may .clear() the viewer, thus clearing the // loader may .clear() the viewer, thus clearing the
// .location too... // .location too...
@ -134,6 +171,24 @@ var LocationActions = actions.Actions({
// all went well clear the recovery data... // all went well clear the recovery data...
delete this.__recover delete this.__recover
}
}],
// Load data and recover on error...
//
// This is the same as .load(..) but will monitor for load errors
// and attempt to recover if it fails...
//
// NOTE: this avoids load loops by attempting to recover only once...
// NOTE: this is done as a wrapper because we can't catch errors in
// parent actions at this point...
loadOrRecover: ['- Location/',
function(data){
// this is the critical section, after this point we
// are doing the actual loading....
try {
this.load(data)
// something bad happened, clear and handle it... // something bad happened, clear and handle it...
} catch(err){ } catch(err){
@ -143,16 +198,7 @@ var LocationActions = actions.Actions({
// recover to last location... // recover to last location...
if(this.__recover){ if(this.__recover){
var l = this.__recover this.recover()
// NOTE: this will prevent us from entering
// a recover attempt loop...
// ...if the recovery fails we will just
// clear and stop.
this.__recover = false
// do the loading...
this.location = l
// fail... // fail...
} else { } else {
@ -164,6 +210,34 @@ var LocationActions = actions.Actions({
} }
} }
}], }],
// Recover from load error...
//
// This will:
// - get recovery data if present
// - load recovery data
// - clear recovery data
//
// NOTE: if no recovery data present (.__recover) this will do nothing.
recover: ['- File/Recover from load error',
function(){
var l = this.__recover
// nothing to recover...
if(!l){
delete this.__recover
return
}
// NOTE: this will prevent us from entering
// a recover attempt loop...
// ...if the recovery fails we will just
// clear and stop.
this.__recover = false
// do the loading...
this.location = l
}],
}) })
module.Location = core.ImageGridFeatures.Feature({ module.Location = core.ImageGridFeatures.Feature({