diff --git a/grid-n-view.html b/grid-n-view.html
index 9d89ba9..f126e32 100644
--- a/grid-n-view.html
+++ b/grid-n-view.html
@@ -93,7 +93,7 @@ var restoreScroll = function(){
- actions:
- "from selection"
- Gallery: drag-n-drop
- - drop files/images
+ - drop files/images
- drag to sort
- Gallery: remove image
- UI: mark images for deletion + delete marked
@@ -103,6 +103,10 @@ var restoreScroll = function(){
- Gallery: element (???)
- Would be nice to retain the scroll position on refresh...
- ...
+
+NOTE: if the grid behaves in an odd way on resize tweak PATCH_MARGIN value,
+ though this sould not be necessary.
+ (optimal range >1 and <3)
diff --git a/grid-n-view.js b/grid-n-view.js
index d3910fc..168d7cc 100644
--- a/grid-n-view.js
+++ b/grid-n-view.js
@@ -15,12 +15,15 @@
//---------------------------------------------------------------------
+// This compansates for any resize rounding errors in patchFlexRows(..).
+var PATCH_MARGIN = 2
+
var patchFlexRows =
function(elems, prevent_row_expansion=false, last_row_resize=1.5){
if(elems.length == 0){
return }
// NOTE: -1 here is to compensate for rounding errors...
- var W = elems[0].parentElement.clientWidth - 1
+ var W = elems[0].parentElement.clientWidth - PATCH_MARGIN
var w = 0
var h
var row = []
@@ -57,7 +60,10 @@ function(elems, prevent_row_expansion=false, last_row_resize=1.5){
// patch the row...
var nw = 0
for(var e of row){
- e.style.height = (h * r) + 'px'
+ if(r == 0 || h == 0){
+ e.style.height = ''
+ } else {
+ e.style.height = (h * r) + 'px' }
nw += e.offsetWidth }
return !!expanded }
// NOTE: this will by design skip the last row...
@@ -573,10 +579,28 @@ var Gallery = {
this.details.show()
return this },
+ __update_grid_size_timeout: undefined,
+ __update_grid_size_running: false,
__update_grid_size: function(){
- patchFlexRows(this.images,
- !this.allow_row_expansion,
- this.last_row_resize ?? 1.2)
+ // if still running then delay untill done...
+ // NOTE: this will keep only one call no matter how many times
+ // the method was actually called...
+ if(this.__update_grid_size_running){
+ var that = this
+ this.__update_grid_size_timeout
+ && clearTimeout(this.__update_grid_size_timeout)
+ this.__update_grid_size_timeout = setTimeout(function(){
+ that.__update_grid_size()
+ delete that.__update_grid_size_timeout }, 10)
+ return this }
+ // do the update...
+ this.__update_grid_size_running = true
+ try{
+ patchFlexRows(this.images,
+ !this.allow_row_expansion,
+ this.last_row_resize ?? 1.2)
+ }catch(err){ }
+ delete this.__update_grid_size_running
return this },
update: function(){
this.__update_grid_size()
@@ -603,6 +627,7 @@ var Gallery = {
// gallery.load(gallery.json('marked'))
// XXX do we handle previews here???
load: function(images, index=undefined){
+ var that = this
images = images instanceof Array ?
images
: [images]
@@ -610,12 +635,17 @@ var Gallery = {
var elems = []
for(var data of images){
if(typeof(data) == 'string'){
- var [url] = [data]
+ var [url, data] = [data, {}]
} else if(data instanceof Array){
- var [url, ...data] = data
+ var [url, caption] = data
+ data = {}
+ caption
+ ?? (data.caption = caption)
} else {
var {url, ...data} = data }
var elem = document.createElement('img')
+ elem.onload = function(){
+ that.update() }
elem.src = url
elem.setAttribute('draggable', 'true')
for(var [key, value] of Object.entries(data)){
@@ -719,16 +749,50 @@ var Gallery = {
.addEventListener('click', function(evt){
that.unmark_current
&& (that.current = null) })
- // drag...
+ // drag/drop...
+ // XXX add a local drag mode...
this.dom
.addEventListener('dragover', function(evt){
- // XXX
- })
+ evt.preventDefault()
+ evt.stopPropagation()
+ evt.dataTransfer.dropEffect = 'copy'
+ }, false)
this.dom
.addEventListener('drop', function(evt){
evt.preventDefault()
- // XXX
- })
+ evt.stopPropagation()
+ var files =
+ evt.dataTransfer.items ?
+ [...evt.dataTransfer.items]
+ .map(function(elem){
+ return elem.kind == 'file' ?
+ [elem.getAsFile()]
+ : [] })
+ .flat()
+ : [...evt.dataTransfer.files]
+
+ Promise.all(files
+ .map(function(file){
+ if(!file.type.match('image.*')){
+ return [] }
+ if(file.path){
+ return file.path
+ } else {
+ return new Promise(function(resolve, reject){
+ var reader = new FileReader()
+ reader.onload = function(f){
+ resolve(f.target.result) }
+ reader.readAsDataURL(file) }) } })
+ .flat())
+ .then(
+ function(images){
+ // no images...
+ if(images.length == 0){
+ return }
+ return that.load(images) },
+ function(err){
+ // XXX handle errors...
+ }) }, false)
// XXX
for(var img of this.images){