mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 18:30:09 +00:00
reworked sort...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
e498ce3471
commit
e64ff7513a
@ -538,14 +538,16 @@ PACK_FULL = $(BUILD_DIR)/$(APP_NAME)/ $(BUILD_DIR)/$(APP_NAME)/$(NODE_DIR)
|
|||||||
# build date...
|
# build date...
|
||||||
# NOTE: this depends on lots of stuff so as to be updated in case any of
|
# NOTE: this depends on lots of stuff so as to be updated in case any of
|
||||||
# the dependencies are touched...
|
# the dependencies are touched...
|
||||||
|
# XXX add nw version option...
|
||||||
$(BUILD_INFO): $(CSS_FILES) $(NODE_DIR) $(PROJECT_FILES) \
|
$(BUILD_INFO): $(CSS_FILES) $(NODE_DIR) $(PROJECT_FILES) \
|
||||||
$(JS_FILES) $(CSS_FILES) $(HTML_FILES)
|
$(JS_FILES) $(CSS_FILES) $(HTML_FILES)
|
||||||
$(MD) "$(@D)"
|
$(MD) "$(@D)"
|
||||||
@echo "Build info:"
|
@echo "Build info:"
|
||||||
@echo "$(APP_NAME)" | tee $(BUILD_INFO)
|
@echo "$(APP_NAME)" | tee $(BUILD_INFO)
|
||||||
@echo "$(VERSION)" | tee -a $(BUILD_INFO)
|
@echo "version: $(VERSION)" | tee -a $(BUILD_INFO)
|
||||||
@echo "$(DATE)" | tee -a $(BUILD_INFO)
|
@echo "date: $(DATE)" | tee -a $(BUILD_INFO)
|
||||||
@echo "$(COMMIT)" | tee -a $(BUILD_INFO)
|
@echo "commit: $(COMMIT)" | tee -a $(BUILD_INFO)
|
||||||
|
@echo "electron: $(ELECTRON_VERSION)" | tee -a $(BUILD_INFO)
|
||||||
|
|
||||||
|
|
||||||
%.css: %.less
|
%.css: %.less
|
||||||
@ -686,12 +688,12 @@ $(BUILD_DIR)/$(APP_NAME)-%.in-place.zip: $(TARGET_DIR)/$(ELECTRON_DIST) \
|
|||||||
cp "$<" "$@.tmp"
|
cp "$<" "$@.tmp"
|
||||||
# # setup app icon...
|
# # setup app icon...
|
||||||
# # XXX
|
# # XXX
|
||||||
# remove default_app.asar...
|
# remove default_app.asar and misc stuff...
|
||||||
$(call zipDelFrom,"$(BUILD_DIR)",$@.tmp,"$(ASAR_PATH)/default_app.asar")
|
$(call zipDelFrom,"$(BUILD_DIR)",$@.tmp,"$(ASAR_PATH)/default_app.asar")
|
||||||
|
$(call zipDelFrom,"$(BUILD_DIR)",$@.tmp,"version")
|
||||||
# rename electron stuff...
|
# rename electron stuff...
|
||||||
zipnote "$@.tmp" \
|
zipnote "$@.tmp" \
|
||||||
| sed 's/\(^@ LICENSE\)$$/\1\n@=LICENSE.electron/' \
|
| sed 's/\(^@ LICENSE\)$$/\1\n@=LICENSE.electron/' \
|
||||||
| sed 's/\(^@ version\)$$/\1\n@=version.electron/' \
|
|
||||||
| zipnote -w "$@.tmp"
|
| zipnote -w "$@.tmp"
|
||||||
# add app.asar and friends...
|
# add app.asar and friends...
|
||||||
$(MD) "$(BUILD_DIR)/$(ASAR_PATH)"
|
$(MD) "$(BUILD_DIR)/$(ASAR_PATH)"
|
||||||
|
|||||||
@ -80,6 +80,11 @@ module.SortActions = actions.Actions({
|
|||||||
'Name (natural number order)':
|
'Name (natural number order)':
|
||||||
'name-leading-sequence name path',
|
'name-leading-sequence name path',
|
||||||
|
|
||||||
|
'Ribbon order':
|
||||||
|
'sort-via-ribbons keep-position',
|
||||||
|
'Reverse ribbon order':
|
||||||
|
'sort-via-ribbons-reverse keep-position',
|
||||||
|
|
||||||
// aliases...
|
// aliases...
|
||||||
'example-sort-alias':
|
'example-sort-alias':
|
||||||
'Date "File date" Name',
|
'Date "File date" Name',
|
||||||
@ -144,20 +149,28 @@ module.SortActions = actions.Actions({
|
|||||||
// remove quotes...
|
// remove quotes...
|
||||||
.replace(/^(["'])([^'"]*)(\1)$/, '$2')
|
.replace(/^(["'])([^'"]*)(\1)$/, '$2')
|
||||||
var m = that.config['sort-methods'][name]
|
var m = that.config['sort-methods'][name]
|
||||||
|| (that.__sort_methods__ && that.__sort_methods__[name])
|
|| (that.__sort_methods__
|
||||||
|
&& that.__sort_methods__[name])
|
||||||
|| SortActions.__sort_methods__[name]
|
|| SortActions.__sort_methods__[name]
|
||||||
return typeof(m) == typeof('str') ? splitMethods(m) : m
|
return typeof(m) == typeof('str') ?
|
||||||
}
|
splitMethods(m)
|
||||||
|
: m }
|
||||||
|
|
||||||
// return a single method...
|
// return a single method...
|
||||||
if(!(methods instanceof Array)){
|
if(!(methods instanceof Array)){
|
||||||
return actions.ASIS(get(methods) || null)
|
return actions.ASIS(
|
||||||
|
get(methods)
|
||||||
|
|| that.getSortMethods(splitMethods(methods))
|
||||||
|
|| null)
|
||||||
}
|
}
|
||||||
|
|
||||||
// return multiple methods...
|
// return multiple methods...
|
||||||
var res = {}
|
var res = {}
|
||||||
methods
|
methods
|
||||||
.forEach(function(m){ res[m] = get(m) })
|
.forEach(function(m){
|
||||||
|
res[m] = m == 'reverse' ?
|
||||||
|
(res[m] || []).concat([m])
|
||||||
|
: get(m) })
|
||||||
return res
|
return res
|
||||||
}],
|
}],
|
||||||
// XXX should this count 'reverese' arity???
|
// XXX should this count 'reverese' arity???
|
||||||
@ -174,15 +187,22 @@ module.SortActions = actions.Actions({
|
|||||||
`,
|
`,
|
||||||
function(method, seen){
|
function(method, seen){
|
||||||
var that = this
|
var that = this
|
||||||
|
var reverse = false
|
||||||
seen = seen || []
|
seen = seen || []
|
||||||
if(seen.indexOf(method) >= 0){
|
if(seen.indexOf(method) >= 0){
|
||||||
throw new Error('Sort method loop detected.')
|
throw new Error('Sort method loop detected.') }
|
||||||
}
|
|
||||||
var methods = that.config['sort-methods'] || []
|
var methods = that.config['sort-methods'] || []
|
||||||
|
|
||||||
return (method instanceof Array ?
|
return (method instanceof Array ?
|
||||||
method
|
method
|
||||||
: that.getSortMethods(method))
|
: that.getSortMethods(method)
|
||||||
|
.run(function(){
|
||||||
|
return Object.entries(this)
|
||||||
|
.map(function([key, value]){
|
||||||
|
return value == null ?
|
||||||
|
key
|
||||||
|
: value })
|
||||||
|
.flat() }))
|
||||||
.map(function(method){
|
.map(function(method){
|
||||||
var a = SortActions.__sort_methods__[method]
|
var a = SortActions.__sort_methods__[method]
|
||||||
|| (that.__sort_methods__ && that.__sort_methods__[method])
|
|| (that.__sort_methods__ && that.__sort_methods__[method])
|
||||||
@ -195,6 +215,13 @@ module.SortActions = actions.Actions({
|
|||||||
: a instanceof Array ?
|
: a instanceof Array ?
|
||||||
a
|
a
|
||||||
: method })
|
: method })
|
||||||
|
// count reverse arity...
|
||||||
|
.filter(function(e){
|
||||||
|
reverse = e == 'reverse' ? !reverse : reverse
|
||||||
|
return e != 'reverse' })
|
||||||
|
.concat(reverse ?
|
||||||
|
'reverse'
|
||||||
|
: [])
|
||||||
.flat() }],
|
.flat() }],
|
||||||
|
|
||||||
// Custom sort methods...
|
// Custom sort methods...
|
||||||
@ -316,21 +343,50 @@ module.SortActions = actions.Actions({
|
|||||||
return (index[a] || 0) - (index[b] || 0) }
|
return (index[a] || 0) - (index[b] || 0) }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Keep image order in each ribbon the same but sort ribbons (i.e.
|
||||||
|
// images within ribbons) in ribbon order...
|
||||||
|
//
|
||||||
|
// e.g. all images in ribbon N are after images of ribbon <N
|
||||||
|
// and before images in ribbons >N
|
||||||
|
'sort-via-ribbons': function(reverse){
|
||||||
|
var that = this
|
||||||
|
var index = new Map(
|
||||||
|
this.data.ribbon_order
|
||||||
|
.run(function(){
|
||||||
|
return reverse ?
|
||||||
|
this.slice().reverse()
|
||||||
|
: this })
|
||||||
|
.map(function(gid){
|
||||||
|
return that.data.ribbons[gid] })
|
||||||
|
.flat()
|
||||||
|
.compact()
|
||||||
|
.map(function(e, i){
|
||||||
|
return [e, i] }))
|
||||||
|
return function(a, b){
|
||||||
|
a = index.get(a)
|
||||||
|
b = index.get(b)
|
||||||
|
return (a === undefined || b === undefined) ?
|
||||||
|
0
|
||||||
|
: a - b } },
|
||||||
|
'sort-via-ribbons-reverse': function(){
|
||||||
|
return SortActions.__sort_methods__['sort-via-ribbons'].call(this, true) },
|
||||||
|
|
||||||
// This is specifically designed to terminate sort methods to prevent
|
// This is specifically designed to terminate sort methods to prevent
|
||||||
// images that are not relevant to the previous order to stay in place
|
// images that are not relevant to the previous order to stay in place
|
||||||
//
|
//
|
||||||
|
// If this is explicitly included then 'reverse' order is ignored.
|
||||||
|
//
|
||||||
// XXX need to test how will this affect a set of images where part
|
// XXX need to test how will this affect a set of images where part
|
||||||
// of the set is sortable an part is not...
|
// of the set is sortable an part is not...
|
||||||
// XXX legacy: this is added to every sort automatically...
|
// XXX legacy: this is added to every sort automatically...
|
||||||
// ...do we still need this here???
|
// ...do we still need this here???
|
||||||
'keep-position': function(){
|
'keep-position': function(){
|
||||||
|
var order = new Map(
|
||||||
|
this.data.order
|
||||||
|
.map(function(e, i){
|
||||||
|
return [e, i] }))
|
||||||
return function(a, b){
|
return function(a, b){
|
||||||
a = this.data.order.indexOf(a)
|
return order.get(a) - order.get(b) } },
|
||||||
b = this.data.order.indexOf(b)
|
|
||||||
|
|
||||||
return a - b
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
// XXX would be nice to be able to sort a list of gids or a section
|
// XXX would be nice to be able to sort a list of gids or a section
|
||||||
// of images...
|
// of images...
|
||||||
@ -398,25 +454,24 @@ module.SortActions = actions.Actions({
|
|||||||
|
|
||||||
// special case: 'update'
|
// special case: 'update'
|
||||||
method = method == 'update' ? [] : method
|
method = method == 'update' ? [] : method
|
||||||
|
|
||||||
// defaults...
|
// defaults...
|
||||||
method = method
|
method = method
|
||||||
|| ((this.config['default-sort'] || 'image-date')
|
|| ((this.config['default-sort'] || 'image-date')
|
||||||
+ (this.config['default-sort-order'] == 'reverse' ? ' reverse' : ''))
|
+ (this.config['default-sort-order'] == 'reverse' ? ' reverse' : ''))
|
||||||
|
|
||||||
// set sort method in data...
|
// set sort method in data...
|
||||||
this.data.sort_method = typeof(method) == typeof('str') ? method : method.join(' ')
|
this.data.sort_method = typeof(method) == typeof('str') ?
|
||||||
|
method
|
||||||
|
: method.join(' ')
|
||||||
|
|
||||||
method = this.expandSortMethod(method)
|
method = this.expandSortMethod(method + (reverse ? ' reverse' : ''))
|
||||||
|
|
||||||
// get the reverse arity...
|
// get the reverse arity...
|
||||||
var i = method.indexOf('reverse')
|
reverse = method[method.length - 1] == 'reverse'
|
||||||
while(i >=0){
|
reverse
|
||||||
reverse = !reverse
|
&& method.pop()
|
||||||
|
reverse = reverse
|
||||||
method.splice(i, 1)
|
&& !method.includes('keep-position')
|
||||||
i = method.indexOf('reverse')
|
|
||||||
}
|
|
||||||
|
|
||||||
// can't sort if we know nothing about .images
|
// can't sort if we know nothing about .images
|
||||||
if(method && method.length > 0 && (!this.images || this.images.length == 0)){
|
if(method && method.length > 0 && (!this.images || this.images.length == 0)){
|
||||||
@ -428,6 +483,8 @@ module.SortActions = actions.Actions({
|
|||||||
// remove duplicate methods...
|
// remove duplicate methods...
|
||||||
// XXX should we keep the last occurrence or the first occurrence???
|
// XXX should we keep the last occurrence or the first occurrence???
|
||||||
.unique()
|
.unique()
|
||||||
|
.concat(['keep-position'])
|
||||||
|
.tailUnique()
|
||||||
.map(function(m){
|
.map(function(m){
|
||||||
return (SortActions.__sort_methods__[m]
|
return (SortActions.__sort_methods__[m]
|
||||||
|| (that.__sort_methods__ && that.__sort_methods__[m])
|
|| (that.__sort_methods__ && that.__sort_methods__[m])
|
||||||
@ -461,15 +518,7 @@ module.SortActions = actions.Actions({
|
|||||||
} else {
|
} else {
|
||||||
return +1
|
return +1
|
||||||
}
|
}
|
||||||
}}).call(that)
|
}}).call(that) })
|
||||||
})
|
|
||||||
// terminator: keep current position...
|
|
||||||
.concat([function(a, b){
|
|
||||||
a = that.data.order.indexOf(a)
|
|
||||||
b = that.data.order.indexOf(b)
|
|
||||||
|
|
||||||
return a - b
|
|
||||||
}])
|
|
||||||
|
|
||||||
// prepare the cmp function...
|
// prepare the cmp function...
|
||||||
var cmp = method.length == 1 ?
|
var cmp = method.length == 1 ?
|
||||||
@ -537,46 +586,22 @@ module.SortActions = actions.Actions({
|
|||||||
// XXX need to refactor the toggler a bit to make the
|
// XXX need to refactor the toggler a bit to make the
|
||||||
// signature simpler... (???)
|
// signature simpler... (???)
|
||||||
function(mode, _, reverse){
|
function(mode, _, reverse){
|
||||||
reverse = reverse == 'reverse' || reverse
|
reverse = reverse || ''
|
||||||
|
reverse = reverse === true ? 'reverse' : reverse
|
||||||
var cache = this.data.sort_cache = this.data.sort_cache || {}
|
var cache = this.data.sort_cache = this.data.sort_cache || {}
|
||||||
var method = this.data.sort_method
|
var method = this.data.sort_method
|
||||||
|
|
||||||
// cache sort order...
|
// cache sort order...
|
||||||
if(method == 'Manual'){
|
method == 'Manual'
|
||||||
this.saveOrder(method)
|
&& this.saveOrder(method)
|
||||||
|
|
||||||
} else if(method && !(method in cache)){
|
var sort = `"${mode}" `+ reverse
|
||||||
this.cacheOrder()
|
|
||||||
}
|
|
||||||
|
|
||||||
var sort = `"${mode}"`+ (reverse ? ' reverse' : '')
|
|
||||||
|
|
||||||
// cached order...
|
|
||||||
// XXX use load cache action...
|
|
||||||
if(mode in cache
|
|
||||||
|| sort in cache){
|
|
||||||
var order = (cache[mode] || cache[sort]).slice()
|
|
||||||
// invalid cache -> sort...
|
|
||||||
if(order.length != this.data.order.length){
|
|
||||||
// drop the cached order...
|
|
||||||
delete cache[ mode in cache ? mode : sort ]
|
|
||||||
this.sortImages(sort)
|
|
||||||
|
|
||||||
// load cache...
|
|
||||||
} else {
|
|
||||||
this.data.order = order
|
|
||||||
this.sortImages('update' + (reverse ? ' reverse' : ''))
|
|
||||||
this.data.sort_method = mode
|
|
||||||
}
|
|
||||||
|
|
||||||
// saved sort order...
|
// saved sort order...
|
||||||
} else if(this.data.sort_order
|
;(this.data.sort_order
|
||||||
&& mode in this.data.sort_order){
|
&& mode in this.data.sort_order) ?
|
||||||
this.loadOrder(mode, reverse)
|
this.loadOrder(mode, reverse == 'reverse')
|
||||||
|
: this.sortImages(sort)
|
||||||
} else {
|
|
||||||
this.sortImages(sort)
|
|
||||||
}
|
|
||||||
})],
|
})],
|
||||||
|
|
||||||
// XXX add drop/load actions...
|
// XXX add drop/load actions...
|
||||||
@ -810,6 +835,7 @@ var SortUIActions = actions.Actions({
|
|||||||
|
|
||||||
// XXX should we be able to edit modes???
|
// XXX should we be able to edit modes???
|
||||||
// XXX should this be a toggler???
|
// XXX should this be a toggler???
|
||||||
|
// XXX add "New from current order..."
|
||||||
sortDialog: ['Edit|Sort/Sort images...',
|
sortDialog: ['Edit|Sort/Sort images...',
|
||||||
widgets.makeUIDialog(function(){
|
widgets.makeUIDialog(function(){
|
||||||
var that = this
|
var that = this
|
||||||
|
|||||||
@ -144,13 +144,17 @@ Array.prototype.toMap = function(normalize){
|
|||||||
//
|
//
|
||||||
// NOTE: we are not using an Object as an index here as an Array can
|
// NOTE: we are not using an Object as an index here as an Array can
|
||||||
// contain any type of item while Object keys can only be strings...
|
// contain any type of item while Object keys can only be strings...
|
||||||
// NOTE: for an array containing only strings use a much faster .uniqueStrings(..)
|
|
||||||
// NOTE: this may not work on IE...
|
// NOTE: this may not work on IE...
|
||||||
Array.prototype.unique = function(normalize){
|
Array.prototype.unique = function(normalize){
|
||||||
return normalize ?
|
return normalize ?
|
||||||
[...new Map(this.map(function(e){ return [normalize(e), e] })).values()]
|
[...new Map(this.map(function(e){ return [normalize(e), e] })).values()]
|
||||||
: [...(new Set(this))] }
|
: [...new Set(this)] }
|
||||||
|
Array.prototype.tailUnique = function(normalize){
|
||||||
|
return this
|
||||||
|
.slice()
|
||||||
|
.reverse()
|
||||||
|
.unique(normalize)
|
||||||
|
.reverse() }
|
||||||
|
|
||||||
// Compare two arrays...
|
// Compare two arrays...
|
||||||
//
|
//
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user