Dynamically load items as viewed.
Signed-off-by: James Ketrenos <james_git@ketrenos.com>
This commit is contained in:
parent
c49310ef71
commit
35258af897
@ -48,7 +48,8 @@
|
||||
"iron-a11y-keys": "PolymerElements/iron-a11y-keys#^1.0.0",
|
||||
"iron-a11y-keys-behavior": "PolymerElements/iron-a11y-keys-behavior#^1.0.0",
|
||||
"es6-shim": "^0.35.3",
|
||||
"paper-radio-group": "PolymerElements/paper-radio-group#^2.2.0"
|
||||
"paper-radio-group": "PolymerElements/paper-radio-group#^2.2.0",
|
||||
"moment": "^2.22.2"
|
||||
},
|
||||
"resolutions": {
|
||||
"polymer": "^1.4.0",
|
||||
|
12
frontend/elements/photo-thumbnail.html
Normal file → Executable file
12
frontend/elements/photo-thumbnail.html
Normal file → Executable file
@ -14,10 +14,10 @@
|
||||
@apply --photo-thumbnail;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
background-color: #ccc;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
background-position: 50% 50%;
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
overflow: hidden;
|
||||
@ -71,11 +71,15 @@
|
||||
|
||||
observers: [
|
||||
"widthChanged(width)",
|
||||
"thumbChanged(thumbpath)"
|
||||
"thumbChanged(thumbpath, visible)"
|
||||
],
|
||||
|
||||
thumbChanged: function(thumbpath) {
|
||||
this.style.backgroundImage = "url(" + thumbpath + ")";
|
||||
thumbChanged: function(thumbpath, visible) {
|
||||
if (visible) {
|
||||
this.style.backgroundImage = "url(" + thumbpath + ")";
|
||||
} else {
|
||||
this.style.backgroundImage = "";
|
||||
}
|
||||
},
|
||||
|
||||
widthChanged: function(width) {
|
||||
|
@ -24,6 +24,7 @@
|
||||
<link rel="import" href="../../bower_components/paper-radio-button/paper-radio-button.html">
|
||||
<link rel="import" href="../../bower_components/paper-spinner/paper-spinner.html">
|
||||
<link rel="import" href="../../bower_components/paper-toast/paper-toast.html">
|
||||
<script src="../../bower_components/moment/moment.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Droid+Sans+Mono" />
|
||||
|
||||
@ -101,29 +102,34 @@
|
||||
*/
|
||||
|
||||
.date-line {
|
||||
display: block;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
padding: 0.5em 0;
|
||||
width: 100%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.album-line {
|
||||
display: block;
|
||||
padding: 0.5em 0;
|
||||
width: 100%;
|
||||
.date-line .album-line {
|
||||
cursor: pointer;
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
.album-line > div {
|
||||
.album-line > div:not(:last-child) {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.album-line > div:first-child {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
.album-line > div:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
photo-thumbnail {
|
||||
--photo-thumbnail: {
|
||||
border: 3px solid rgba(0, 0, 0, 0);
|
||||
border: 3px solid white;
|
||||
};
|
||||
}
|
||||
|
||||
@ -157,7 +163,6 @@
|
||||
<paper-radio-button name="by-date">By date</paper-radio-button>
|
||||
<paper-radio-button name="by-album">By album</paper-radio-button>
|
||||
</paper-radio-group>
|
||||
<paper-checkbox checked$="[[limitPerFolder]]" on-checked-changed="onLimitPerFolderChanged">Limit per folder</paper-checkbox>
|
||||
<paper-checkbox checked$="[[breakOnDayChange]]" on-checked-changed="onBreakOnDayChanged">Break on day change</paper-checkbox>
|
||||
</div>
|
||||
<div id="breadcrumb" class="horizontal layout center"><template is="dom-repeat" items="[[breadcrumb(path)]]">
|
||||
@ -166,7 +171,7 @@
|
||||
</div>
|
||||
</app-header>
|
||||
<div id="content" fullbleed class="flex layout vertical">
|
||||
<div id="thumbnails" class="thumbnails layout horizontal wrap"></div>
|
||||
<div id="thumbnails" class="layout horizontal wrap"></div>
|
||||
<div id="magic"></div>
|
||||
<div class="layout horizontal">
|
||||
<paper-button disabled$="[[!prev]]" on-tap="loadPrevPhotos">prev</paper-button>
|
||||
@ -205,11 +210,6 @@
|
||||
value: true,
|
||||
reflectToAttribute: true
|
||||
},
|
||||
limitPerFolder: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
reflectToAttribute: true
|
||||
},
|
||||
showAlbums: {
|
||||
type: Boolean,
|
||||
computed: "shouldShowAlbums(order)"
|
||||
@ -259,17 +259,6 @@
|
||||
this.appendItems(this.photos);
|
||||
},
|
||||
|
||||
onLimitPerFolderChanged: function(event) {
|
||||
if (!this.photos) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.limitPerFolder = event.detail.value;
|
||||
|
||||
Polymer.dom(this.$.thumbnails).innerHTML = "";
|
||||
|
||||
this.appendItems(this.photos);
|
||||
},
|
||||
onBreakOnDayChanged: function(event) {
|
||||
if (!this.photos) {
|
||||
return;
|
||||
@ -308,11 +297,37 @@
|
||||
this._loadPhotos();
|
||||
},
|
||||
|
||||
|
||||
isThumbInView: function(el) {
|
||||
var rect = el.getBoundingClientRect(),
|
||||
height = (window.innerHeight || document.documentElement.clientHeight),
|
||||
width = (window.innerWidth || document.documentElement.clientWidth);
|
||||
|
||||
return ((rect.top <= height) && ((rect.top + rect.height) >= 0) &&
|
||||
(rect.left <= width) && ((rect.left + rect.width) >= 0));
|
||||
},
|
||||
|
||||
onScroll: function(event) {
|
||||
if (this.disableScrolling) {
|
||||
event.preventDefault();
|
||||
window.scrollTo(this.topStickX, this.topStickY);
|
||||
return;
|
||||
}
|
||||
|
||||
this.triggerVisibilityChecks();
|
||||
},
|
||||
|
||||
|
||||
triggerVisibilityChecks: function() {
|
||||
this.debounce("hide-or-show", function() {
|
||||
var thumbs = this.querySelectorAll("photo-thumbnail"), visible;
|
||||
thumbs.forEach(function(thumb) {
|
||||
visible = this.isThumbInView(thumb);
|
||||
if (thumb.visible != visible) {
|
||||
thumb.visible = visible;
|
||||
}
|
||||
}.bind(this));
|
||||
}, 250);
|
||||
},
|
||||
|
||||
findPhoto: function(photo) {
|
||||
@ -422,17 +437,12 @@
|
||||
return;
|
||||
}
|
||||
|
||||
var thisDay, lastPath = null;
|
||||
if (this.limitPerFolder) {
|
||||
console.log("Max per day: " + this.cols);
|
||||
}
|
||||
|
||||
var lastPath = null;
|
||||
var albums = this.querySelectorAll(".album-line");
|
||||
if (albums.length) {
|
||||
lastPath = albums[albums.length - 1];
|
||||
}
|
||||
|
||||
thisDay = 0;
|
||||
for (var i = 0; i < photos.length; i++) {
|
||||
var photo = photos[i],
|
||||
thumbnail = document.createElement("photo-thumbnail"),
|
||||
@ -443,6 +453,34 @@
|
||||
thumbnail.addEventListener("load-album", this.loadAlbum.bind(this));
|
||||
datetime = (photo.taken || photo.modified || photo.added).replace(/T.*$/, "");
|
||||
|
||||
var dateBlock = this.querySelector("#date-" + datetime), thumbnails;
|
||||
if (!dateBlock) {
|
||||
dateBlock = document.createElement("div");
|
||||
dateBlock.id = "date-" + datetime;
|
||||
dateBlock.classList.add("date-line");
|
||||
dateBlock.classList.add("layout");
|
||||
dateBlock.classList.add("vertical");
|
||||
var header = document.createElement("div");
|
||||
header.classList.add("header");
|
||||
header.classList.add("layout");
|
||||
header.classList.add("center");
|
||||
header.classList.add("horizontal");
|
||||
var div = document.createElement("div");
|
||||
div.classList.add("date");
|
||||
div.textContent = window.moment(datetime, "YYYY-MM-DD").calendar(null, { sameElse: "MMM DD, YYYY" });
|
||||
Polymer.dom(dateBlock).appendChild(header);
|
||||
Polymer.dom(header).appendChild(div);
|
||||
thumbnails = document.createElement("div");
|
||||
thumbnails.classList.add("thumbnails");
|
||||
thumbnails.classList.add("layout");
|
||||
thumbnails.classList.add("horizontal");
|
||||
thumbnails.classList.add("wrap");
|
||||
Polymer.dom(dateBlock).appendChild(thumbnails);
|
||||
Polymer.dom(this.$.thumbnails).appendChild(dateBlock);
|
||||
} else {
|
||||
thumbnails = Polymer.dom(dateBlock).querySelector(".thumbnails");
|
||||
}
|
||||
|
||||
if (this.order == "by-album") {
|
||||
if (lastPath != photo.path) {
|
||||
lastPath = photo.path;
|
||||
@ -459,52 +497,15 @@
|
||||
albumBlock.appendChild(div);
|
||||
}.bind(this));
|
||||
|
||||
Polymer.dom(this.$.thumbnails).appendChild(albumBlock);
|
||||
var header = dateBlock.querySelector(".header");
|
||||
Polymer.dom(header).appendChild(albumBlock);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.breakOnDayChange) {
|
||||
var dateBlock = this.querySelector("#date-" + datetime);
|
||||
if (!dateBlock) {
|
||||
dateBlock = document.createElement("div");
|
||||
dateBlock.id = "date-" + datetime;
|
||||
dateBlock.classList.add("date-line");
|
||||
dateBlock.textContent = datetime;
|
||||
Polymer.dom(this.$.thumbnails).appendChild(dateBlock);
|
||||
thisDay = 0;
|
||||
} else {
|
||||
if (this.limitPerFolder) {
|
||||
var thumbs = [], el = dateBlock.nextElementSibling;
|
||||
while (el && el.tagName == "PHOTO-THUMBNAIL") {
|
||||
thumbs.push(el);
|
||||
el = el.nextElementSibling;
|
||||
}
|
||||
thisDay = thumbs.length;
|
||||
while (thisDay > this.cols) {
|
||||
Polymer.dom(thumbs[thisDay - 1].parentElement).removeChild(thumbs[thisDay - 1]);
|
||||
thisDay--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!this.limitPerFolder || thisDay < this.cols) {
|
||||
Polymer.dom(this.$.thumbnails).appendChild(thumbnail);
|
||||
thisDay++;
|
||||
}
|
||||
|
||||
if (this.limitPerFolder && thisDay == this.cols) {
|
||||
while (i + 1 < photos.length) {
|
||||
photo = photos[i + 1];
|
||||
if (datetime != (photo.taken || photo.modified || photo.added).replace(/T.*$/, "")) {
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
thisDay = 0;
|
||||
}
|
||||
Polymer.dom(thumbnails).appendChild(thumbnail);
|
||||
}
|
||||
|
||||
this.triggerVisibilityChecks();
|
||||
},
|
||||
|
||||
pathTapped: function(event) {
|
||||
@ -617,6 +618,7 @@
|
||||
},
|
||||
|
||||
onResize: function(event) {
|
||||
this.triggerVisibilityChecks();
|
||||
this.debounce("resize", function() {
|
||||
var width = Math.max(this.$.placeholder.offsetWidth || 0, 200);
|
||||
|
||||
|
8
server/app.js
Normal file → Executable file
8
server/app.js
Normal file → Executable file
@ -84,10 +84,14 @@ app.set("port", serverConfig.port);
|
||||
const server = require("http").createServer(app);
|
||||
|
||||
db.then(function(photoDB) {
|
||||
console.log("DB connected. Opening server.");
|
||||
server.listen(serverConfig.port);
|
||||
return photoDB;
|
||||
}).then(function(photoDB) {
|
||||
console.log("Scanning.");
|
||||
return scanner.scan(photoDB);
|
||||
}).then(function() {
|
||||
console.log("Done scanning. Opening server.");
|
||||
server.listen(serverConfig.port);
|
||||
console.log("Scanning completed.");
|
||||
}).catch(function(error) {
|
||||
console.error(error);
|
||||
process.exit(-1);
|
||||
|
2
server/routes/photos.js
Normal file → Executable file
2
server/routes/photos.js
Normal file → Executable file
@ -55,7 +55,7 @@ router.get("/*", function(req, res/*, next*/) {
|
||||
}
|
||||
}
|
||||
|
||||
let query = "SELECT * FROM photos WHERE path LIKE :path " + index + " ORDER BY taken " + order + ",id " + order + " LIMIT " + (limit * 2 + 1);
|
||||
let query = "SELECT * FROM photos WHERE path LIKE :path " + index + " ORDER BY taken " + order + ",id " + order;// + " LIMIT " + (limit * 2 + 1);
|
||||
return photoDB.sequelize.query(query, {
|
||||
replacements: {
|
||||
cursor: cursor,
|
||||
|
Loading…
x
Reference in New Issue
Block a user