Added 'memories' tab
Signed-off-by: James Ketrenos <james_git@ketrenos.com>
This commit is contained in:
parent
dc0dc0da3c
commit
517ea8f66e
@ -16,7 +16,7 @@
|
|||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"polymer": "Polymer/polymer#^1.4.0",
|
"polymer": "Polymer/polymer#^1.4.0",
|
||||||
"paper-tabs": "PolymerElements/paper-tabs#^1.5.0",
|
"paper-tabs": "PolymerElements/paper-tabs#^2.1.1",
|
||||||
"iron-pages": "PolymerElements/iron-pages#^1.0.7",
|
"iron-pages": "PolymerElements/iron-pages#^1.0.7",
|
||||||
"paper-toast": "PolymerElements/paper-toast#^1.2.2",
|
"paper-toast": "PolymerElements/paper-toast#^1.2.2",
|
||||||
"paper-material": "PolymerElements/paper-material#^1.0.6",
|
"paper-material": "PolymerElements/paper-material#^1.0.6",
|
||||||
@ -60,6 +60,7 @@
|
|||||||
"paper-checkbox": "^1.2.0",
|
"paper-checkbox": "^1.2.0",
|
||||||
"webcomponentsjs": "^v1.1.0",
|
"webcomponentsjs": "^v1.1.0",
|
||||||
"paper-icon-button": "^1.1.2",
|
"paper-icon-button": "^1.1.2",
|
||||||
"iron-icons": "^1.1.3"
|
"iron-icons": "^1.1.3",
|
||||||
|
"paper-tabs": "^1.5.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
<link rel="import" href="../../bower_components/iron-icons/iron-icons.html">
|
<link rel="import" href="../../bower_components/iron-icons/iron-icons.html">
|
||||||
<link rel="import" href="../../bower_components/iron-pages/iron-pages.html">
|
<link rel="import" href="../../bower_components/iron-pages/iron-pages.html">
|
||||||
<link rel="import" href="../../bower_components/iron-resizable-behavior/iron-resizable-behavior.html">
|
<link rel="import" href="../../bower_components/iron-resizable-behavior/iron-resizable-behavior.html">
|
||||||
|
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||||
|
|
||||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||||
<link rel="import" href="../../bower_components/paper-checkbox/paper-checkbox.html">
|
<link rel="import" href="../../bower_components/paper-checkbox/paper-checkbox.html">
|
||||||
@ -24,6 +25,8 @@
|
|||||||
<link rel="import" href="../../bower_components/paper-radio-group/paper-radio-group.html">
|
<link rel="import" href="../../bower_components/paper-radio-group/paper-radio-group.html">
|
||||||
<link rel="import" href="../../bower_components/paper-radio-button/paper-radio-button.html">
|
<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-spinner/paper-spinner.html">
|
||||||
|
<link rel="import" href="../../bower_components/paper-tabs/paper-tab.html">
|
||||||
|
<link rel="import" href="../../bower_components/paper-tabs/paper-tabs.html">
|
||||||
<link rel="import" href="../../bower_components/paper-toast/paper-toast.html">
|
<link rel="import" href="../../bower_components/paper-toast/paper-toast.html">
|
||||||
<script src="../../bower_components/moment/moment.js"></script>
|
<script src="../../bower_components/moment/moment.js"></script>
|
||||||
|
|
||||||
@ -56,7 +59,10 @@
|
|||||||
padding: 0.5em 1em;
|
padding: 0.5em 1em;
|
||||||
background: #ddd;
|
background: #ddd;
|
||||||
box-shadow: 0px 0px 5px black;
|
box-shadow: 0px 0px 5px black;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 64px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#breadcrumb {
|
#breadcrumb {
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
}
|
}
|
||||||
@ -70,23 +76,32 @@
|
|||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
#albums > div {
|
#pages > div {
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pages > div > div {
|
||||||
margin: 0.5em;
|
margin: 0.5em;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
#searchBox {
|
#drawer {
|
||||||
}
|
}
|
||||||
|
|
||||||
#searchContents {
|
#pages {
|
||||||
|
position: relative;
|
||||||
|
height: calc(100vh - 64px);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
height: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#searchMode {
|
#tabs {
|
||||||
padding: 0.5em 1em;
|
|
||||||
background: #ddd;
|
background: #ddd;
|
||||||
color: #444;
|
color: #444;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 64px;
|
||||||
|
box-shadow: 0px 0px 5px black;
|
||||||
}
|
}
|
||||||
|
|
||||||
#breadcrumb > div {
|
#breadcrumb > div {
|
||||||
@ -201,18 +216,21 @@
|
|||||||
border: 3px solid blue;
|
border: 3px solid blue;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<app-location route="{{route}}"></app-location>
|
<app-location route="{{route}}"></app-location>
|
||||||
|
|
||||||
<app-drawer-layout id="albumLayout" force-narrow=true>
|
<app-drawer-layout id="albumLayout"><!--force-narrow=true-->
|
||||||
<app-drawer id="searchBox" slot="drawer">
|
<app-drawer id="drawer" slot="drawer">
|
||||||
<div id="searchContents" class="layout vertical">
|
<paper-tabs attr-for-selected="tab" id="tabs" selected="{{mode}}">
|
||||||
<div id="searchMode" class="layout horizontal justified">
|
<paper-tab tab="time"><paper-icon-button icon="date-range"></paper-icon-button></paper-tab>
|
||||||
<paper-icon-button icon="folder"></paper-icon-button>
|
<paper-tab tab="memories"><paper-icon-button icon="today"></paper-icon-button></paper-tab>
|
||||||
<paper-icon-button icon="date-range"></paper-icon-button>
|
<paper-tab tab="albums"><paper-icon-button icon="folder"></paper-icon-button></paper-tab>
|
||||||
<paper-icon-button icon="today"></paper-icon-button>
|
</paper-tabs>
|
||||||
|
<iron-pages id="pages" attr-for-selected="id" selected="[[mode]]">
|
||||||
|
<div id="time"><div>... time slider ...</div></div>
|
||||||
|
<div id="memories" class="flex layout vertical">
|
||||||
|
<div>... calendar ...</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="albums" class="flex layout vertical">
|
<div id="albums" class="flex layout vertical">
|
||||||
<template is="dom-repeat" items="[[breadcrumb(path)]]">
|
<template is="dom-repeat" items="[[breadcrumb(path)]]">
|
||||||
@ -222,12 +240,12 @@
|
|||||||
<div on-tap="loadPath">[[item.name]]</div>
|
<div on-tap="loadPath">[[item.name]]</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</iron-pages>
|
||||||
</app-drawer>
|
</app-drawer>
|
||||||
<app-header-layout>
|
<app-header-layout>
|
||||||
<app-header reveals slot="header">
|
<app-header reveals slot="header">
|
||||||
<div id="header" class="layout horizontal center">
|
<div id="header" class="layout horizontal center">
|
||||||
<paper-icon-button icon="search" on-tap="searchBoxToggle"></paper-icon-button>
|
<paper-icon-button icon="search" on-tap="drawerToggle"></paper-icon-button>
|
||||||
<div id="breadcrumb" class="horizontal layout center">
|
<div id="breadcrumb" class="horizontal layout center">
|
||||||
<template is="dom-repeat" items="[[breadcrumb(path)]]">
|
<template is="dom-repeat" items="[[breadcrumb(path)]]">
|
||||||
<div on-tap="loadPath">[[item.name]] /</div>
|
<div on-tap="loadPath">[[item.name]] /</div>
|
||||||
@ -266,7 +284,7 @@
|
|||||||
type: String,
|
type: String,
|
||||||
value: "by-date"
|
value: "by-date"
|
||||||
},
|
},
|
||||||
"loading": Boolean,
|
loading: Boolean,
|
||||||
pendingPhotos: {
|
pendingPhotos: {
|
||||||
type: Array,
|
type: Array,
|
||||||
value: []
|
value: []
|
||||||
@ -295,13 +313,42 @@
|
|||||||
thumbnails: {
|
thumbnails: {
|
||||||
type: Array,
|
type: Array,
|
||||||
value: []
|
value: []
|
||||||
|
},
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
value: "time"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
observers: [
|
||||||
|
"widthChanged(calcWidth)",
|
||||||
|
"modeChanged(mode)"
|
||||||
|
],
|
||||||
|
|
||||||
shouldShowAlbums: function(order) {
|
shouldShowAlbums: function(order) {
|
||||||
return order == "by-album";
|
return order == "by-album";
|
||||||
},
|
},
|
||||||
|
|
||||||
|
changeMode: function(event) {
|
||||||
|
var mode = event.currentTarget.icon;
|
||||||
|
if (this.mode != mode) {
|
||||||
|
this.mode = mode;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
modeChanged: function(mode) {
|
||||||
|
console.log("Mode changed to " + mode);
|
||||||
|
this.path = "";
|
||||||
|
this.pendingPhotos = [];
|
||||||
|
this.visibleThumbs = [];
|
||||||
|
this.thumbnails = [];
|
||||||
|
this.cursor = null;
|
||||||
|
Polymer.dom(this.$.thumbnails).innerHTML = "";
|
||||||
|
this.next = false;
|
||||||
|
this.limit = undefined;
|
||||||
|
this._loadPhotos();
|
||||||
|
},
|
||||||
|
|
||||||
breadcrumb: function(path) {
|
breadcrumb: function(path) {
|
||||||
var crumbs = path.split("/"), parts = [];
|
var crumbs = path.split("/"), parts = [];
|
||||||
path = "";
|
path = "";
|
||||||
@ -317,20 +364,16 @@
|
|||||||
return parts;
|
return parts;
|
||||||
},
|
},
|
||||||
|
|
||||||
observers: [
|
drawerToggle: function(event) {
|
||||||
"widthChanged(calcWidth)"
|
if (this.$.drawer.opened) {
|
||||||
],
|
this.$.drawer.close();
|
||||||
|
|
||||||
searchBoxToggle: function(event) {
|
|
||||||
if (this.$.searchBox.opened) {
|
|
||||||
this.$.searchBox.close();
|
|
||||||
this.$.albumLayout.forceNarrow = true;
|
this.$.albumLayout.forceNarrow = true;
|
||||||
this.$.searchBox.resetLayout();
|
this.$.drawer.resetLayout();
|
||||||
} else {
|
} else {
|
||||||
this.$.searchBox.open();
|
this.$.drawer.open();
|
||||||
this.$.albumLayout.forceNarrow = false;
|
this.$.albumLayout.forceNarrow = false;
|
||||||
if (window.innerWidth >= 800) {
|
if (window.innerWidth >= 800) {
|
||||||
this.$.searchBox.persistent = true;
|
this.$.drawer.persistent = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -754,13 +797,16 @@
|
|||||||
query += key + "=" + encodeURIComponent(params[key]);
|
query += key + "=" + encodeURIComponent(params[key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var path = this.path || "";
|
var path = this.path || "", mode = this.mode;
|
||||||
|
if (mode != "albums") {
|
||||||
|
path = "/" + mode;
|
||||||
|
}
|
||||||
console.log("Requesting " + this.limit + " photos.");
|
console.log("Requesting " + this.limit + " photos.");
|
||||||
window.fetch("api/v1/photos" + path + query, function(path, error, xhr) {
|
window.fetch("api/v1/photos" + path + query, function(path, error, xhr) {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
|
||||||
if (path != (this.path || "")) {
|
if ((mode != this.mode) || ((mode == "albums") && (path != (this.path || "")))) {
|
||||||
console.log("Skipping results for old query. Triggering re-fetch of photos for new path.");
|
console.log("Skipping results for old query. Triggering re-fetch of photos for new path or mode.");
|
||||||
this._loadPhotos();
|
this._loadPhotos();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -865,22 +911,6 @@
|
|||||||
}
|
}
|
||||||
}.bind(this), 100);
|
}.bind(this), 100);
|
||||||
|
|
||||||
window.setInterval(function() {
|
|
||||||
function isElementInViewport(el) {
|
|
||||||
var rect = el.getBoundingClientRect(),
|
|
||||||
vWidth = window.innerWidth || doc.documentElement.clientWidth,
|
|
||||||
vHeight = window.innerHeight || doc.documentElement.clientHeight;
|
|
||||||
|
|
||||||
// Return false if it's not in the viewport
|
|
||||||
if (rect.right < 0 || rect.bottom < 0
|
|
||||||
|| rect.left > vWidth || rect.top > vHeight) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}.bind(this), 500);
|
|
||||||
|
|
||||||
this._loadAlbums();
|
this._loadAlbums();
|
||||||
this._loadPhotos();
|
this._loadPhotos();
|
||||||
|
|
||||||
|
@ -29,6 +29,76 @@ const router = express.Router();
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
router.get("/memories", function(req, res/*, next*/) {
|
||||||
|
let limit = parseInt(req.query.limit) || 50,
|
||||||
|
id, cursor, index;
|
||||||
|
|
||||||
|
if (req.query.next) {
|
||||||
|
let parts = req.query.next.split("_");
|
||||||
|
cursor = parts[0];
|
||||||
|
id = parseInt(parts[1]);
|
||||||
|
} else {
|
||||||
|
cursor = "";
|
||||||
|
id = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == -1) {
|
||||||
|
index = "";
|
||||||
|
} else {
|
||||||
|
if (id != -1) {
|
||||||
|
index = " AND ((taken=DATE(:cursor) AND id<"+id+ ") OR taken<DATE(:cursor))";
|
||||||
|
} else {
|
||||||
|
index = " AND (taken<=DATE(:cursor))";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let query = "SELECT * FROM photos WHERE strftime('%m%d',taken)=strftime('%m%d',CURRENT_TIMESTAMP) " + index + " ORDER BY taken DESC,id DESC LIMIT " + (limit * 2 + 1);
|
||||||
|
|
||||||
|
console.log("Memories query", query);
|
||||||
|
|
||||||
|
return photoDB.sequelize.query(query, {
|
||||||
|
replacements: {
|
||||||
|
cursor: cursor
|
||||||
|
},
|
||||||
|
type: photoDB.Sequelize.QueryTypes.SELECT
|
||||||
|
}).then(function(photos) {
|
||||||
|
photos.forEach(function(photo) {
|
||||||
|
for (var key in photo) {
|
||||||
|
if (photo[key] instanceof Date) {
|
||||||
|
photo[key] = moment(photo[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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 */
|
||||||
|
|
||||||
|
if (more) {
|
||||||
|
photos.splice(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
let results = {
|
||||||
|
items: photos
|
||||||
|
};
|
||||||
|
if (more) {
|
||||||
|
results.more = true;
|
||||||
|
}
|
||||||
|
return res.status(200).json(results);
|
||||||
|
}).catch(function(error) {
|
||||||
|
console.error("Query failed: " + query);
|
||||||
|
return Promise.reject(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
router.get("/*", function(req, res/*, next*/) {
|
router.get("/*", function(req, res/*, next*/) {
|
||||||
let limit = parseInt(req.query.limit) || 50,
|
let limit = parseInt(req.query.limit) || 50,
|
||||||
id, cursor, index;
|
id, cursor, index;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user