Load all photos into pendingPhotos, then create DIVs on demand. Also add scroller pager
Signed-off-by: James Ketrenos <james_git@ketrenos.com>
This commit is contained in:
parent
588a261796
commit
41ef463799
@ -90,15 +90,27 @@
|
||||
color: white;
|
||||
}
|
||||
|
||||
#pager {
|
||||
margin-top: 0.5em;
|
||||
position: fixed;
|
||||
display: block;
|
||||
opacity: 0;
|
||||
right: 5px;
|
||||
border-radius: 0.25em;
|
||||
padding: 0.5em;
|
||||
width: 120px;
|
||||
background-color: rgb(16, 0, 16);
|
||||
color: white;
|
||||
text-align: center;
|
||||
transition: opacity 0.5s ease-in-out;
|
||||
-webkit-transition: opacity 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
#toast[error] {
|
||||
--paper-toast-background-color: red;
|
||||
--paper-toast-color: white;
|
||||
}
|
||||
|
||||
app-header {
|
||||
background-color: yellow;
|
||||
}
|
||||
|
||||
#thumbnails {
|
||||
/* justify-content: space-between;*/
|
||||
}
|
||||
@ -192,6 +204,7 @@
|
||||
<div hidden$="[[loading]]">~ the end ~</div>
|
||||
</div>
|
||||
</app-drawer-layout>
|
||||
<div id="pager">pager</div>
|
||||
<paper-toast id="toast"></paper-toast>
|
||||
<photo-lightbox tabindex="0" id="lightbox" on-close="lightBoxClose" on-next="lightBoxNext" on-previous="lightBoxPrevious"></photo-lightbox>
|
||||
</template>
|
||||
@ -309,11 +322,37 @@
|
||||
}
|
||||
|
||||
if (this.$.bottom.getBoundingClientRect().bottom < window.innerHeight + 200) {
|
||||
if (this.next) {
|
||||
this.loadNextPhotos();
|
||||
if (this.pendingPhotos.length) {
|
||||
this.async(this.processItems.bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
var headerHeight = this.$.header.offsetHeight;
|
||||
|
||||
var i, date = null, top = null, lowest = window.innerHeight;
|
||||
for (i = 0; i < this.visibleThumbs.length; i++) {
|
||||
var thumb = this.thumbnails[this.visibleThumbs[i]], rect = thumb.getBoundingClientRect();
|
||||
/* If no thumb is chosen yet, or this one is the highest on the page, use it */
|
||||
if (rect.top > 0 && (!top || lowest > rect.top)) {
|
||||
lowest = rect.top
|
||||
top = thumb;
|
||||
}
|
||||
}
|
||||
|
||||
if (top) {
|
||||
var photo = top.item;
|
||||
this.$.pager.style.opacity = 1;
|
||||
var date = window.moment(new Date((photo.taken || photo.modified || photo.added) + " GMT"));
|
||||
date = date.calendar(null, { sameElse: "MMM DD, YYYY" }).replace(/ at.*/, "");
|
||||
this.$.pager.textContent = date;
|
||||
this.$.pager.style.top = headerHeight +
|
||||
Math.floor((window.innerHeight - 2 * headerHeight) * (window.scrollY / document.scrollingElement.scrollHeight)) + 'px';
|
||||
|
||||
this.debounce("hide-pager", function() {
|
||||
this.$.pager.style.opacity = 0;
|
||||
}, 250);
|
||||
}
|
||||
|
||||
this.triggerVisibilityChecks();
|
||||
},
|
||||
|
||||
@ -527,13 +566,6 @@
|
||||
window.location.href = event.model.item.filepath;
|
||||
},
|
||||
|
||||
loadNextPhotos: function() {
|
||||
if (!this.cursor) {
|
||||
return;
|
||||
}
|
||||
this._loadPhotos(this.cursor.taken.toString().replace(/T.*/, "") + "_" + this.cursor.id, -1, true);
|
||||
},
|
||||
|
||||
appendItems: function(photos) {
|
||||
if (!this.pendingPhotos || !photos || photos.length == 0) {
|
||||
return;
|
||||
@ -622,19 +654,8 @@
|
||||
this.thumbnails.push(thumbnail);
|
||||
}
|
||||
|
||||
if (this.pendingPhotos.length) {
|
||||
this.async(this.processItems.bind(this));
|
||||
} else {
|
||||
// if (this.next && this.cursor) {
|
||||
// this.async(function() {
|
||||
// this._loadPhotos(this.cursor.taken.toString().replace(/T.*/, "") + "_" + this.cursor.id, -1, true, this.limit * 2);
|
||||
// }, 250);
|
||||
// } else {
|
||||
// console.log("All photos are loaded: " + this.thumbnails.length);
|
||||
// }
|
||||
/* If the viewport is at the bottom when it finishes processing, trigger to load more. */
|
||||
this.onScroll();
|
||||
}
|
||||
},
|
||||
|
||||
pathTapped: function(event) {
|
||||
@ -645,7 +666,7 @@
|
||||
this._loadPhotos();
|
||||
},
|
||||
|
||||
_loadPhotos: function(start, dir, append, limit) {
|
||||
_loadPhotos: function(start, append, limit) {
|
||||
if (this.loading == true) {
|
||||
return;
|
||||
}
|
||||
@ -653,10 +674,8 @@
|
||||
|
||||
this.limit = limit || 100;
|
||||
|
||||
dir = dir || -1;
|
||||
var params = {
|
||||
limit: this.limit,
|
||||
dir: dir
|
||||
}, query = "";
|
||||
if (start) {
|
||||
params.next = start;
|
||||
@ -674,7 +693,6 @@
|
||||
}
|
||||
|
||||
console.log("Requesting " + this.limit + " photos.");
|
||||
|
||||
window.fetch("api/v1/photos" + (this.path || "") + query, function(error, xhr) {
|
||||
this.loading = false;
|
||||
if (error) {
|
||||
@ -705,12 +723,9 @@
|
||||
|
||||
this.appendItems(results.items);
|
||||
|
||||
this.cursor = results.items[results.items.length - 1];
|
||||
|
||||
if (dir == -1) {
|
||||
this.next = results.more ? true : false;
|
||||
} else {
|
||||
this.next = true;
|
||||
if (results.more) {
|
||||
var cursor = results.items[results.items.length - 1];
|
||||
this._loadPhotos(cursor.taken.toString().replace(/T.*/, "") + "_" + cursor.id, true, this.limit * 2);
|
||||
}
|
||||
|
||||
}.bind(this));
|
||||
|
@ -26,7 +26,7 @@ const router = express.Router();
|
||||
|
||||
router.get("/*", function(req, res/*, next*/) {
|
||||
let limit = parseInt(req.query.limit) || 50,
|
||||
order = (parseInt(req.query.dir) == -1) ? "DESC" : "", id, cursor, index;
|
||||
id, cursor, index;
|
||||
|
||||
if (req.query.next) {
|
||||
let parts = req.query.next.split("_");
|
||||
@ -40,23 +40,15 @@ router.get("/*", function(req, res/*, next*/) {
|
||||
if (id == -1) {
|
||||
index = "";
|
||||
} else {
|
||||
if (order == "DESC") {
|
||||
if (id != -1) {
|
||||
index = " AND ((taken=DATE(:cursor) AND id<"+id+ ") OR taken<DATE(:cursor))";
|
||||
} else {
|
||||
index = " AND (taken<=DATE(:cursor))";
|
||||
}
|
||||
} else {
|
||||
if (id != -1) {
|
||||
index = " AND ((taken=DATE(:cursor) AND id>"+id+ ") OR taken>DATE(:cursor))";
|
||||
} else {
|
||||
index = " AND (taken>=DATE(:cursor))";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let path = decodeURI(req.url).replace(/\?.*$/, ""),
|
||||
query = "SELECT * FROM photos WHERE path LIKE :path " + index + " ORDER BY taken " + order + ",id " + order + " LIMIT " + (limit * 2 + 1);
|
||||
query = "SELECT * FROM photos WHERE path LIKE :path " + index + " ORDER BY taken DESC,id DESC LIMIT " + (limit * 2 + 1);
|
||||
|
||||
console.log("Fetching from: " + path);
|
||||
|
||||
@ -76,7 +68,6 @@ router.get("/*", function(req, res/*, next*/) {
|
||||
}
|
||||
});
|
||||
|
||||
if (order == "DESC") {
|
||||
if (cursor) {
|
||||
cursor = moment(cursor);
|
||||
photos = photos.filter(function(photo) {
|
||||
@ -86,17 +77,6 @@ router.get("/*", function(req, res/*, next*/) {
|
||||
return photo.id < id;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (cursor) {
|
||||
cursor = moment(cursor);
|
||||
photos = photos.filter(function(photo) {
|
||||
if (!cursor.isSame(photo.taken, "day")) {
|
||||
return true;
|
||||
}
|
||||
return photo.id > id;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let more = photos.length > limit; /* We queried one extra item to see if there are more than LIMIT available */
|
||||
|
||||
|
@ -34,7 +34,7 @@ function removeNewerFile(path, fileA, fileB) {
|
||||
}
|
||||
|
||||
function scanDir(parent, path) {
|
||||
let extensions = [ "jpg", "jpeg", "png", "gif", "nef" ],
|
||||
let extensions = [ "jpg", "jpeg", "png", "gif", "nef", "orf" ],
|
||||
re = new RegExp("\.((" + extensions.join(")|(") + "))$", "i"),
|
||||
replacements = {
|
||||
path: path.slice(picturesPath.length),
|
||||
@ -96,8 +96,8 @@ function scanDir(parent, path) {
|
||||
/* Remove 'thumbs' and 'raw' directories from being processed */
|
||||
files = files.filter(function(file) {
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
/* If this file has an original NEF on the system, don't add the JPG to the DB */
|
||||
if (/\.nef$/i.exec(files[i]) && file == files[i].replace(/\.nef$/i, ".jpg")) {
|
||||
/* If this file has an original NEF/ORF on the system, don't add the JPG to the DB */
|
||||
if (/\.(nef|orf)$/i.exec(files[i]) && file == files[i].replace(/\.(nef|orf)$/i, ".jpg")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -138,7 +138,7 @@ function scanDir(parent, path) {
|
||||
|
||||
const replacements = {
|
||||
path: path.slice(picturesPath.length),
|
||||
filename: file.replace(/\.nef$/i, ".jpg") /* We will be converting from NEF => JPG */
|
||||
filename: file.replace(/\.(nef|orf)$/i, ".jpg") /* We will be converting from NEF/ORF => JPG */
|
||||
};
|
||||
|
||||
replacements.path = replacements.path || "/";
|
||||
@ -218,13 +218,13 @@ function existsPromise(path) {
|
||||
})
|
||||
}
|
||||
|
||||
function convertNefToJpg(path, file) {
|
||||
function convertRawToJpg(path, file) {
|
||||
console.log("Converting " + path + "/" + file);
|
||||
|
||||
path = picturesPath + path;
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
fs.stat(path + "/" + file.replace(/\.nef$/i, ".jpg"), function(err, stats) {
|
||||
fs.stat(path + "/" + file.replace(/\.(nef|orf)$/i, ".jpg"), function(err, stats) {
|
||||
if (!err) {
|
||||
console.log("Skipping already converted file: " + file);
|
||||
return resolve();
|
||||
@ -238,7 +238,7 @@ function convertNefToJpg(path, file) {
|
||||
"--compression=90",
|
||||
"--exif",
|
||||
"--overwrite",
|
||||
"--output", path + "/" + file.replace(/\.nef$/i, ".jpg"),
|
||||
"--output", path + "/" + file.replace(/\.(nef|orf)$/i, ".jpg"),
|
||||
path + "/" + file
|
||||
]);
|
||||
|
||||
@ -309,16 +309,16 @@ function triggerWatcher() {
|
||||
|
||||
let tmp = Promise.resolve(file);
|
||||
/* If this is a Nikon RAW file, convert it to JPG and move to /raw dir */
|
||||
if (/\.nef$/i.exec(file)) {
|
||||
tmp = existsPromise(picturesPath + path + "/" + file.replace(/\.nef$/i, ".jpg")).then(function(exists) {
|
||||
if (/\.(nef|orf)$/i.exec(file)) {
|
||||
tmp = existsPromise(picturesPath + path + "/" + file.replace(/\.(nef|orf)$/i, ".jpg")).then(function(exists) {
|
||||
if (exists) {
|
||||
return file.replace(/\.nef$/i, ".jpg"); /* We converted from NEF => JPG */
|
||||
return file.replace(/\.(nef|orf)$/i, ".jpg"); /* We converted from NEF/ORF => JPG */
|
||||
}
|
||||
|
||||
return mkdirPromise(picturesPath + path + "/raw").then(function() {
|
||||
return convertNefToJpg(path, file);
|
||||
return convertRawToJpg(path, file);
|
||||
}).then(function() {
|
||||
return file.replace(/\.nef$/i, ".jpg"); /* We converted from NEF => JPG */
|
||||
return file.replace(/\.(nef|orf)$/i, ".jpg"); /* We converted from NEF/ORF => JPG */
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -418,18 +418,18 @@ function triggerWatcher() {
|
||||
console.error("Error reading image " + src + ": ", error);
|
||||
return moveCorrupt(path, file).then(function() {
|
||||
|
||||
/* If the original file was not a NEF, we are done... */
|
||||
if (!/\.nef$/i.exec(entry[1])) {
|
||||
/* If the original file was not a NEF/ORF, we are done... */
|
||||
if (!/\.(nef|orf)$/i.exec(entry[1])) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* ... otherwise, attempt to re-convert the NEF->JPG and then resize again */
|
||||
/* ... otherwise, attempt to re-convert the NEF/ORF->JPG and then resize again */
|
||||
for (var i = 0; i < triedClean.length; i++) {
|
||||
if (triedClean[i] == path + "/" + file) {
|
||||
/* Move the NEF to /corrupt as well so it isn't re-checked again and again... */
|
||||
/* Move the NEF/ORF to /corrupt as well so it isn't re-checked again and again... */
|
||||
// return moveCorrupt(path, entry[1]);
|
||||
|
||||
console.error("Already attempted to convert NEF to JPG: " + path + "/" + file);
|
||||
console.error("Already attempted to convert NEF/ORF to JPG: " + path + "/" + file);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user