Ready to deploy
Signed-off-by: James Ketrenos <james_git@ketrenos.com>
This commit is contained in:
parent
bfd872f60a
commit
1c2b7a42aa
@ -7,7 +7,7 @@
|
||||
}
|
||||
},
|
||||
"server": {
|
||||
"port": 8080
|
||||
"port": 8123
|
||||
},
|
||||
"picturesPath": "./pictures",
|
||||
"basePath": "/photos"
|
||||
|
@ -28,24 +28,23 @@
|
||||
}
|
||||
|
||||
:host > div {
|
||||
position: absolute;
|
||||
padding: 0.5em;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
opacity: 0;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
:host:hover {
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
:host:hover > div {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
div[path]:hover {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="layout vertical">
|
||||
<div>[[item.id]]</div>
|
||||
<div>[[date(item)]]</div>
|
||||
<div path on-tap="_pathTap">[[item.path]]</div>
|
||||
<div>[[item.filename]]</div>
|
||||
<div>
|
||||
[[item.name]]
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -48,11 +48,17 @@
|
||||
:host {
|
||||
}
|
||||
|
||||
#breadcrumb {
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
#albumList > div,
|
||||
#breadcrumb > div {
|
||||
margin-right: 0.5em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#albumList > div:hover,
|
||||
#breadcrumb > div:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
@ -85,7 +91,7 @@
|
||||
background-color: yellow;
|
||||
}
|
||||
|
||||
#header > * {
|
||||
#header > div > * {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
@ -102,6 +108,21 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.album-line {
|
||||
display: block;
|
||||
padding: 0.5em 0;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.album-line > div {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.album-line > div:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#content {
|
||||
margin: 1em;
|
||||
}
|
||||
@ -126,31 +147,35 @@
|
||||
|
||||
<app-header-layout reveals>
|
||||
<app-header fixed>
|
||||
<div id="header" class="layout horizontal center">
|
||||
<paper-spinner active$="[[loading]]" class="thin"></paper-spinner>
|
||||
<paper-radio-group selected="{{order}}">
|
||||
<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 id="header" class="layout vertical start">
|
||||
<div class="layout horizontal center">
|
||||
<paper-spinner active$="[[loading]]" class="thin"></paper-spinner>
|
||||
<paper-radio-group selected="{{order}}">
|
||||
<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)]]">
|
||||
<div on-tap="loadPath">[[item.name]] /</div>
|
||||
</template></div>
|
||||
</div>
|
||||
</app-header>
|
||||
<div id="content">
|
||||
<div id="thumbnails" class="thumbnails layout horizontal wrap"></div>
|
||||
<div id="magic"></div>
|
||||
<div class="layout horizontal">
|
||||
<paper-button disabled$="[[!prev]]" on-tap="loadPrevPhotos">prev</paper-button>
|
||||
<paper-button disabled$="[[!next]]" on-tap="loadNextPhotos">next</paper-button>
|
||||
</div>
|
||||
<div class="folders layout horizontal wrap">
|
||||
<template is="dom-repeat" items="[[photos.paths]]">
|
||||
<div info="[[item]]" on-tap="_pathTap" >[[item.filepath]]</div>
|
||||
<div id="content" class="layout horizontal">
|
||||
<div id="albumList" hidden$="[[!showAlbums]]">
|
||||
<template is="dom-repeat" items="[[albums.children]]">
|
||||
<div on-tap="loadPath">[[item.name]]</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="layout vertical">
|
||||
<div id="thumbnails" class="thumbnails layout horizontal wrap"></div>
|
||||
<div id="magic"></div>
|
||||
<div class="layout horizontal">
|
||||
<paper-button disabled$="[[!prev]]" on-tap="loadPrevPhotos">prev</paper-button>
|
||||
<paper-button disabled$="[[!next]]" on-tap="loadNextPhotos">next</paper-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
<paper-toast id="toast"></paper-toast>
|
||||
@ -186,9 +211,21 @@
|
||||
type: Boolean,
|
||||
value: false,
|
||||
reflectToAttribute: true
|
||||
},
|
||||
showAlbums: {
|
||||
type: Boolean,
|
||||
computed: "shouldShowAlbums(order)"
|
||||
},
|
||||
path: {
|
||||
type: String,
|
||||
value: ""
|
||||
}
|
||||
},
|
||||
|
||||
shouldShowAlbums: function(order) {
|
||||
return order == "by-album";
|
||||
},
|
||||
|
||||
breadcrumb: function(path) {
|
||||
var crumbs = path.split("/"), parts = [];
|
||||
path = "";
|
||||
@ -210,7 +247,9 @@
|
||||
],
|
||||
|
||||
orderChanged: function(order) {
|
||||
|
||||
console.log("Order: " + order);
|
||||
Polymer.dom(this.$.thumbnails).innerHTML = "";
|
||||
this.appendItems(this.photos);
|
||||
},
|
||||
|
||||
onLimitPerFolderChanged: function(event) {
|
||||
@ -246,6 +285,7 @@
|
||||
Polymer.dom(this.$.thumbnails).innerHTML = "";
|
||||
this.photos = [];
|
||||
this.next = false;
|
||||
this._loadAlbums();
|
||||
this._loadPhotos();
|
||||
},
|
||||
|
||||
@ -257,6 +297,7 @@
|
||||
Polymer.dom(this.$.thumbnails).innerHTML = "";
|
||||
this.photos = [];
|
||||
this.next = false;
|
||||
this._loadAlbums();
|
||||
this._loadPhotos();
|
||||
},
|
||||
|
||||
@ -370,7 +411,11 @@
|
||||
},
|
||||
|
||||
appendItems: function(photos) {
|
||||
var thisDay;
|
||||
if (!photos) {
|
||||
return;
|
||||
}
|
||||
|
||||
var thisDay, lastPath = null;
|
||||
if (this.limitPerFolder) {
|
||||
console.log("Max per day: " + this.cols);
|
||||
}
|
||||
@ -411,6 +456,26 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (this.order == "by-album") {
|
||||
if (lastPath != photo.path) {
|
||||
lastPath = photo.path;
|
||||
var albumBlock = document.createElement("div");
|
||||
albumBlock.classList.add("album-line");
|
||||
albumBlock.classList.add("layout");
|
||||
albumBlock.classList.add("horizontal");
|
||||
var trail = this.breadcrumb(lastPath);
|
||||
trail.forEach(function(crumb) {
|
||||
var div = document.createElement("div");
|
||||
div.path = crumb.path;
|
||||
div.textContent = crumb.name + " /";
|
||||
div.addEventListener("tap", this.pathTapped.bind(this));
|
||||
albumBlock.appendChild(div);
|
||||
}.bind(this));
|
||||
|
||||
Polymer.dom(this.$.thumbnails).appendChild(albumBlock);
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.limitPerFolder || thisDay < this.cols) {
|
||||
Polymer.dom(this.$.thumbnails).appendChild(thumbnail);
|
||||
thisDay++;
|
||||
@ -429,6 +494,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
pathTapped: function(event) {
|
||||
this.path = event.currentTarget.path;
|
||||
Polymer.dom(this.$.thumbnails).innerHTML = "";
|
||||
this.photos = [];
|
||||
this.next = false;
|
||||
this._loadAlbums();
|
||||
this._loadPhotos();
|
||||
},
|
||||
|
||||
_loadPhotos: function(start, dir, append) {
|
||||
if (this.loading == true) {
|
||||
return;
|
||||
@ -500,6 +574,35 @@
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
_loadAlbums: function() {
|
||||
if (this.loadingAlbums == true) {
|
||||
return;
|
||||
}
|
||||
this.loadingAlbums = true;
|
||||
|
||||
window.fetch("api/v1/albums" + (this.path || ""), function(error, xhr) {
|
||||
this.loadingAlbums = false;
|
||||
if (error) {
|
||||
console.error(JSON.stringify(error, null, 2));
|
||||
return;
|
||||
}
|
||||
|
||||
var results;
|
||||
try {
|
||||
results = JSON.parse(xhr.responseText);
|
||||
} catch (___) {
|
||||
this.$.toast.text = "Unable to load/parse album list.";
|
||||
this.$.toast.setAttribute("error", true);
|
||||
this.$.toast.updateStyles();
|
||||
this.$.toast.show();
|
||||
console.error("Unable to parse photos");
|
||||
return;
|
||||
}
|
||||
|
||||
this.albums = results;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
onResize: function(event) {
|
||||
this.debounce("resize", function() {
|
||||
var width = Math.max(this.$.placeholder.offsetWidth || 0, 200);
|
||||
@ -547,6 +650,7 @@
|
||||
|
||||
}.bind(this), 500);
|
||||
|
||||
this._loadAlbums();
|
||||
this._loadPhotos();
|
||||
|
||||
this.onResize();
|
||||
|
@ -34,6 +34,7 @@ function init() {
|
||||
autoIncrement: true
|
||||
},
|
||||
path: Sequelize.STRING,
|
||||
name: Sequelize.STRING,
|
||||
parentId: {
|
||||
type: Sequelize.INTEGER,
|
||||
allowNull: true
|
||||
@ -53,6 +54,7 @@ function init() {
|
||||
primaryKey: true,
|
||||
autoIncrement: true
|
||||
},
|
||||
name: Sequelize.STRING,
|
||||
path: Sequelize.STRING,
|
||||
filename: Sequelize.STRING,
|
||||
added: Sequelize.DATE,
|
||||
|
@ -40,7 +40,7 @@ router.get("/*", function(req, res/*, next*/) {
|
||||
}
|
||||
}
|
||||
|
||||
return photoDB.sequelize.query("SELECT * FROM albums WHERE parentId=:parentId", {
|
||||
return photoDB.sequelize.query("SELECT * FROM albums WHERE parentId=:parentId ORDER BY name", {
|
||||
replacements: {
|
||||
parentId: parent.id
|
||||
},
|
||||
|
@ -18,6 +18,7 @@ function scanDir(parent, path) {
|
||||
re = new RegExp("\.((" + extensions.join(")|(") + "))$", "i"),
|
||||
replacements = {
|
||||
path: path.slice(picturesPath.length),
|
||||
name: path.replace(/.*\//, "").replace(/_/g, " "),
|
||||
parent: parent || null
|
||||
};
|
||||
|
||||
@ -34,7 +35,7 @@ function scanDir(parent, path) {
|
||||
}).then(function(results) {
|
||||
if (results.length == 0) {
|
||||
// console.log("Adding " + path + " under " + parent, replacements);
|
||||
return photoDB.sequelize.query("INSERT INTO albums (path,parentId) VALUES(:path,:parent)", {
|
||||
return photoDB.sequelize.query("INSERT INTO albums (path,parentId,name) VALUES(:path,:parent,:name)", {
|
||||
replacements: replacements
|
||||
}).then(function(results) {
|
||||
return results[1].lastID;
|
||||
@ -288,6 +289,7 @@ function triggerWatcher() {
|
||||
|
||||
let replacements = {
|
||||
albumId: albumId,
|
||||
name: file.replace(/.[^.]*$/, ""),
|
||||
path: path,
|
||||
filename: file,
|
||||
width: metadata.width,
|
||||
@ -327,8 +329,8 @@ function triggerWatcher() {
|
||||
|
||||
return resize.then(function() {
|
||||
return photoDB.sequelize.query("INSERT INTO photos " +
|
||||
"(albumId,path,filename,added,modified,taken,width,height)" +
|
||||
"VALUES(:albumId,:path,:filename,DATE(:added),DATE(:modified),DATE(:taken),:width,:height)", {
|
||||
"(albumId,path,filename,added,modified,taken,width,height,name)" +
|
||||
"VALUES(:albumId,:path,:filename,DATE(:added),DATE(:modified),DATE(:taken),:width,:height,:name)", {
|
||||
replacements: replacements
|
||||
});
|
||||
}).catch(function(error) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user