Merge pull request #238 from electerious/v2.6.3

v2.6.3
This commit is contained in:
Tobias Reich 2014-10-10 22:41:59 +02:00
commit 056842ba8f
21 changed files with 260 additions and 101 deletions

View File

@ -50,6 +50,7 @@ Here's a list of all available Plugins and Extensions:
| Name | Description | | | Name | Description | |
|:-----------|:------------|:------------| |:-----------|:------------|:------------|
| lycheesync | Sync Lychee with any directory containing photos | [More »](https://github.com/GustavePate/lycheesync) | | lycheesync | Sync Lychee with any directory containing photos | [More »](https://github.com/GustavePate/lycheesync) |
| lycheeupload | Upload photos to Lychee via SSH | [More »](https://github.com/r0x0r/lycheeupload) |
| Jekyll | Liquid tag for Jekyll sites that allows embedding Lychee albums | [More »](https://gist.github.com/tobru/9171700) | | Jekyll | Liquid tag for Jekyll sites that allows embedding Lychee albums | [More »](https://gist.github.com/tobru/9171700) |
| lychee-redirect | Redirect from an album-name to a Lychee-album | [More »](https://github.com/electerious/lychee-redirect) | | lychee-redirect | Redirect from an album-name to a Lychee-album | [More »](https://github.com/electerious/lychee-redirect) |
| lychee-watermark | Adds a second watermarked photo when uploading images | [More »](https://github.com/electerious/lychee-watermark) | | lychee-watermark | Adds a second watermarked photo when uploading images | [More »](https://github.com/electerious/lychee-watermark) |
@ -73,7 +74,7 @@ I am working hard on continuously developing and maintaining Lychee. Please cons
(MIT License) (MIT License)
Copyright (C) 2014 [Tobias Reich](http://electerious.com) Copyright (C) 2014 [Tobias Reich](http://electerious.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View File

@ -113,8 +113,12 @@ album = {
if (data===true) data = 1; // Avoid first album to be true if (data===true) data = 1; // Avoid first album to be true
if (data!==false&&isNumber(data)) lychee.goto(data); if (data!==false&&isNumber(data)) {
else lychee.error(null, params, data); albums.refresh();
lychee.goto(data);
} else {
lychee.error(null, params, data);
}
}); });
@ -146,9 +150,15 @@ album = {
albumIDs.forEach(function(id) { albumIDs.forEach(function(id) {
albums.json.num--; albums.json.num--;
view.albums.content.delete(id); view.albums.content.delete(id);
delete albums.json.content[id];
}); });
} else lychee.goto(""); } else {
albums.refresh();
lychee.goto("");
}
if (data!==true) lychee.error(null, params, data); if (data!==true) lychee.error(null, params, data);
@ -222,6 +232,11 @@ album = {
album.json.title = newTitle; album.json.title = newTitle;
view.album.title(); view.album.title();
if (albums.json) {
var id = albumIDs[0];
albums.json.content[id].title = newTitle;
}
} else if (visible.albums()) { } else if (visible.albums()) {
albumIDs.forEach(function(id) { albumIDs.forEach(function(id) {
@ -290,6 +305,8 @@ album = {
listed = false, listed = false,
downloadable = false; downloadable = false;
albums.refresh();
if (!visible.message()&&album.json.public==0) { if (!visible.message()&&album.json.public==0) {
modal.show("Share Album", "This album will be shared with the following properties:</p><form><div class='choice'><input type='checkbox' name='listed' value='listed' checked><h2>Visible</h2><p>Listed to visitors of your Lychee.</p></div><div class='choice'><input type='checkbox' name='downloadable' value='downloadable'><h2>Downloadable</h2><p>Visitors of your Lychee can download this album.</p></div><div class='choice'><input type='checkbox' name='password' value='password'><h2>Password protected</h2><p>Only accessible with a valid password.<input class='text' type='password' placeholder='password' value='' style='display: none;'></p></div></form><p style='display: none;'>", [["Share Album", function() { album.setPublic(album.getID(), e) }], ["Cancel", function() {}]], -170); modal.show("Share Album", "This album will be shared with the following properties:</p><form><div class='choice'><input type='checkbox' name='listed' value='listed' checked><h2>Visible</h2><p>Listed to visitors of your Lychee.</p></div><div class='choice'><input type='checkbox' name='downloadable' value='downloadable'><h2>Downloadable</h2><p>Visitors of your Lychee can download this album.</p></div><div class='choice'><input type='checkbox' name='password' value='password'><h2>Password protected</h2><p>Only accessible with a valid password.<input class='text' type='password' placeholder='password' value='' style='display: none;'></p></div></form><p style='display: none;'>", [["Share Album", function() { album.setPublic(album.getID(), e) }], ["Cancel", function() {}]], -170);

View File

@ -20,66 +20,74 @@ albums = {
startTime = new Date().getTime(); startTime = new Date().getTime();
lychee.api("getAlbums", function(data) { if(albums.json===null) {
/* Smart Albums */ lychee.api("getAlbums", function(data) {
data.unsortedAlbum = {
id: 0,
title: "Unsorted",
sysdate: data.unsortedNum + " photos",
unsorted: 1,
thumb0: data.unsortedThumb0,
thumb1: data.unsortedThumb1,
thumb2: data.unsortedThumb2
};
data.starredAlbum = { /* Smart Albums */
id: "f", data.unsortedAlbum = {
title: "Starred", id: 0,
sysdate: data.starredNum + " photos", title: "Unsorted",
star: 1, sysdate: data.unsortedNum + " photos",
thumb0: data.starredThumb0, unsorted: 1,
thumb1: data.starredThumb1, thumb0: data.unsortedThumb0,
thumb2: data.starredThumb2 thumb1: data.unsortedThumb1,
}; thumb2: data.unsortedThumb2
};
data.publicAlbum = { data.starredAlbum = {
id: "s", id: "f",
title: "Public", title: "Starred",
sysdate: data.publicNum + " photos", sysdate: data.starredNum + " photos",
public: 1, star: 1,
thumb0: data.publicThumb0, thumb0: data.starredThumb0,
thumb1: data.publicThumb1, thumb1: data.starredThumb1,
thumb2: data.publicThumb2 thumb2: data.starredThumb2
}; };
data.recentAlbum = { data.publicAlbum = {
id: "r", id: "s",
title: "Recent", title: "Public",
sysdate: data.recentNum + " photos", sysdate: data.publicNum + " photos",
recent: 1, public: 1,
thumb0: data.recentThumb0, thumb0: data.publicThumb0,
thumb1: data.recentThumb1, thumb1: data.publicThumb1,
thumb2: data.recentThumb2 thumb2: data.publicThumb2
}; };
albums.json = data; data.recentAlbum = {
id: "r",
title: "Recent",
sysdate: data.recentNum + " photos",
recent: 1,
thumb0: data.recentThumb0,
thumb1: data.recentThumb1,
thumb2: data.recentThumb2
};
durationTime = (new Date().getTime() - startTime); albums.json = data;
if (durationTime>300) waitTime = 0; else waitTime = 300 - durationTime;
if (!visible.albums()&&!visible.photo()&&!visible.album()) waitTime = 0; durationTime = (new Date().getTime() - startTime);
if (visible.album()&&lychee.content.html()==="") waitTime = 0; if (durationTime>300) waitTime = 0; else waitTime = 300 - durationTime;
if (!visible.albums()&&!visible.photo()&&!visible.album()) waitTime = 0;
if (visible.album()&&lychee.content.html()==="") waitTime = 0;
setTimeout(function() {
view.header.mode("albums");
view.albums.init();
lychee.animate(".album:nth-child(-n+50), .photo:nth-child(-n+50)", "contentZoomIn");
}, waitTime);
});
} else {
setTimeout(function() { setTimeout(function() {
view.header.mode("albums"); view.header.mode("albums");
view.albums.init(); view.albums.init();
lychee.animate(".album:nth-child(-n+50), .photo:nth-child(-n+50)", "contentZoomIn"); lychee.animate(".album:nth-child(-n+50), .photo:nth-child(-n+50)", "contentZoomIn");
}, 300);
}, waitTime); }
});
}, },
parse: function(album) { parse: function(album) {
@ -94,6 +102,12 @@ albums = {
if (!album.thumb2) album.thumb2 = "assets/img/no_images.svg"; if (!album.thumb2) album.thumb2 = "assets/img/no_images.svg";
} }
},
refresh: function() {
albums.json = null;
} }
}; };

View File

@ -34,7 +34,7 @@ build = {
title = albumJSON.title, title = albumJSON.title,
typeThumb = ""; typeThumb = "";
if (title.length>18) { if (title!==null&&title.length>18) {
title = albumJSON.title.substr(0, 18) + "..."; title = albumJSON.title.substr(0, 18) + "...";
longTitle = albumJSON.title; longTitle = albumJSON.title;
} }
@ -76,7 +76,7 @@ build = {
longTitle = "", longTitle = "",
title = photoJSON.title; title = photoJSON.title;
if (title.length>18) { if (title!==null&&title.length>18) {
title = photoJSON.title.substr(0, 18) + "..."; title = photoJSON.title.substr(0, 18) + "...";
longTitle = photoJSON.title; longTitle = photoJSON.title;
} }
@ -195,8 +195,8 @@ build = {
modal += "<h1><a class='icon-lock'></a> Sign In</h1>"; modal += "<h1><a class='icon-lock'></a> Sign In</h1>";
modal += "<a class='close icon-remove-sign'></a>"; modal += "<a class='close icon-remove-sign'></a>";
modal += "<div class='sign_in'>"; modal += "<div class='sign_in'>";
modal += "<input id='username' type='text' name='' value='' placeholder='username'>"; modal += "<input id='username' type='text' value='' placeholder='username' autocapitalize='off' autocorrect='off'>";
modal += "<input id='password' type='password' name='' value='' placeholder='password'>"; modal += "<input id='password' type='password' value='' placeholder='password'>";
modal += "</div>"; modal += "</div>";
modal += "<div id='version'>Version " + lychee.version + "<span> &#8211; <a target='_blank' href='" + lychee.updateURL + "'>Update available!</a><span></div>"; modal += "<div id='version'>Version " + lychee.version + "<span> &#8211; <a target='_blank' href='" + lychee.updateURL + "'>Update available!</a><span></div>";
modal += "<a onclick='lychee.login()' class='button active'>Sign in</a>"; modal += "<a onclick='lychee.login()' class='button active'>Sign in</a>";

View File

@ -99,6 +99,7 @@ $(document).ready(function(){
}) })
.bind(['i', 'ctrl+i'], function() { .bind(['i', 'ctrl+i'], function() {
if (visible.infobox()) view.infobox.hide(); if (visible.infobox()) view.infobox.hide();
else if (visible.multiselect()) return false;
else if (visible.infoboxbutton()) view.infobox.show(); else if (visible.infoboxbutton()) view.infobox.show();
}) })
.bind(['command+backspace', 'ctrl+backspace'], function() { .bind(['command+backspace', 'ctrl+backspace'], function() {
@ -182,11 +183,20 @@ $(document).ready(function(){
.on(event_name, ".upload_message a.close", upload.close) .on(event_name, ".upload_message a.close", upload.close)
.on("dragover", function(e) { e.preventDefault(); }, false) .on("dragover", function(e) { e.preventDefault(); }, false)
.on("drop", function(e) { .on("drop", function(e) {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
// Close open overlays or views which are correlating with the upload
if (visible.photo()) lychee.goto(album.getID());
if (visible.contextMenu()) contextMenu.close();
// Detect if dropped item is a file or a link
if (e.originalEvent.dataTransfer.files.length>0) upload.start.local(e.originalEvent.dataTransfer.files); if (e.originalEvent.dataTransfer.files.length>0) upload.start.local(e.originalEvent.dataTransfer.files);
else if (e.originalEvent.dataTransfer.getData('Text').length>3) upload.start.url(e.originalEvent.dataTransfer.getData('Text')); else if (e.originalEvent.dataTransfer.getData('Text').length>3) upload.start.url(e.originalEvent.dataTransfer.getData('Text'));
return true; return true;
}); });
/* Init */ /* Init */

View File

@ -8,8 +8,8 @@
var lychee = { var lychee = {
title: "", title: "",
version: "2.6.2", version: "2.6.3",
version_code: "020602", version_code: "020603",
api_path: "php/api.php", api_path: "php/api.php",
update_path: "http://lychee.electerious.com/version/index.php", update_path: "http://lychee.electerious.com/version/index.php",
@ -119,13 +119,23 @@ var lychee = {
params = "login&user=" + user + "&password=" + password; params = "login&user=" + user + "&password=" + password;
lychee.api(params, function(data) { lychee.api(params, function(data) {
if (data===true) { if (data===true) {
localStorage.setItem("lychee_username", user);
// Use 'try' to catch a thrown error when Safari is in private mode
try { localStorage.setItem("lychee_username", user); }
catch (err) {}
window.location.reload(); window.location.reload();
} else { } else {
// Show error and reactive button
$("#password").val("").addClass("error").focus(); $("#password").val("").addClass("error").focus();
$(".message .button.active").removeClass("pressed"); $(".message .button.active").removeClass("pressed");
} }
}); });
}, },
@ -181,7 +191,6 @@ var lychee = {
if (albumID&&photoID) { if (albumID&&photoID) {
// Trash data // Trash data
albums.json = null;
photo.json = null; photo.json = null;
// Show Photo // Show Photo
@ -194,7 +203,6 @@ var lychee = {
} else if (albumID) { } else if (albumID) {
// Trash data // Trash data
albums.json = null;
photo.json = null; photo.json = null;
// Show Album // Show Album
@ -205,7 +213,6 @@ var lychee = {
} else { } else {
// Trash data // Trash data
albums.json = null;
album.json = null; album.json = null;
photo.json = null; photo.json = null;
search.code = ""; search.code = "";

View File

@ -8,6 +8,7 @@
photo = { photo = {
json: null, json: null,
cache: null,
getID: function() { getID: function() {
@ -43,12 +44,41 @@ photo = {
view.photo.init(); view.photo.init();
lychee.imageview.show(); lychee.imageview.show();
setTimeout(function() { lychee.content.show() }, 300); setTimeout(function() {
lychee.content.show();
//photo.preloadNext(photoID, albumID);
}, 300);
}); });
}, },
//preload the next photo for better response time
preloadNext: function(photoID) {
var nextPhoto,
url;
// Never preload on mobile devices with bare RAM and
// mostly mobile internet
if (mobileBrowser()) return false;
if (album.json &&
album.json.content &&
album.json.content[photoID] &&
album.json.content[photoID].nextPhoto!="") {
nextPhoto = album.json.content[photoID].nextPhoto;
url = album.json.content[nextPhoto].url;
photo.cache = new Image();
photo.cache.src = url;
photo.cache.onload = function() { photo.cache = null };
}
},
parse: function() { parse: function() {
if (!photo.json.title) photo.json.title = "Untitled"; if (!photo.json.title) photo.json.title = "Untitled";
@ -124,6 +154,8 @@ photo = {
if (!photoIDs) return false; if (!photoIDs) return false;
if (photoIDs instanceof Array===false) photoIDs = [photoIDs]; if (photoIDs instanceof Array===false) photoIDs = [photoIDs];
albums.refresh();
params = "duplicatePhoto&photoIDs=" + photoIDs; params = "duplicatePhoto&photoIDs=" + photoIDs;
lychee.api(params, function(data) { lychee.api(params, function(data) {
@ -177,6 +209,8 @@ photo = {
// Only when search is not active // Only when search is not active
if (!visible.albums()) lychee.goto(album.getID()); if (!visible.albums()) lychee.goto(album.getID());
albums.refresh();
params = "deletePhoto&photoIDs=" + photoIDs; params = "deletePhoto&photoIDs=" + photoIDs;
lychee.api(params, function(data) { lychee.api(params, function(data) {
@ -286,6 +320,8 @@ photo = {
}); });
albums.refresh();
params = "setPhotoAlbum&photoIDs=" + photoIDs + "&albumID=" + albumID; params = "setPhotoAlbum&photoIDs=" + photoIDs + "&albumID=" + albumID;
lychee.api(params, function(data) { lychee.api(params, function(data) {
@ -310,6 +346,8 @@ photo = {
view.album.content.star(id); view.album.content.star(id);
}); });
albums.refresh();
params = "setPhotoStar&photoIDs=" + photoIDs; params = "setPhotoStar&photoIDs=" + photoIDs;
lychee.api(params, function(data) { lychee.api(params, function(data) {
@ -341,6 +379,8 @@ photo = {
album.json.content[photoID].public = (album.json.content[photoID].public==0) ? 1 : 0; album.json.content[photoID].public = (album.json.content[photoID].public==0) ? 1 : 0;
view.album.content.public(photoID); view.album.content.public(photoID);
albums.refresh();
params = "setPhotoPublic&photoID=" + photoID; params = "setPhotoPublic&photoID=" + photoID;
lychee.api(params, function(data) { lychee.api(params, function(data) {

View File

@ -215,6 +215,8 @@ var settings = {
sorting[0] = $("select#settings_type").val(); sorting[0] = $("select#settings_type").val();
sorting[1] = $("select#settings_order").val(); sorting[1] = $("select#settings_order").val();
albums.refresh();
params = "setSorting&type=" + sorting[0] + "&order=" + sorting[1]; params = "setSorting&type=" + sorting[0] + "&order=" + sorting[1];
lychee.api(params, function(data) { lychee.api(params, function(data) {

View File

@ -65,6 +65,8 @@ upload = {
} }
albums.refresh();
if (album.getID()===false) lychee.goto("0"); if (album.getID()===false) lychee.goto("0");
else album.load(albumID); else album.load(albumID);
@ -259,6 +261,8 @@ upload = {
upload.close(); upload.close();
upload.notify("Import complete"); upload.notify("Import complete");
albums.refresh();
if (album.getID()===false) lychee.goto("0"); if (album.getID()===false) lychee.goto("0");
else album.load(albumID); else album.load(albumID);
@ -306,6 +310,8 @@ upload = {
upload.close(); upload.close();
upload.notify("Import complete"); upload.notify("Import complete");
albums.refresh();
if (data==="Notice: Import only contains albums!") { if (data==="Notice: Import only contains albums!") {
if (visible.albums()) lychee.load(); if (visible.albums()) lychee.load();
else lychee.goto(""); else lychee.goto("");
@ -365,6 +371,8 @@ upload = {
upload.close(); upload.close();
upload.notify("Import complete"); upload.notify("Import complete");
albums.refresh();
if (album.getID()===false) lychee.goto("0"); if (album.getID()===false) lychee.goto("0");
else album.load(albumID); else album.load(albumID);

View File

@ -54,15 +54,21 @@ view = {
var albumID = album.getID(); var albumID = album.getID();
switch (mode) { switch (mode) {
case "albums": case "albums":
lychee.header.removeClass("view"); lychee.header.removeClass("view");
$("#tools_album, #tools_photo").hide(); $("#tools_album, #tools_photo").hide();
$("#tools_albums").show(); $("#tools_albums").show();
break; break;
case "album": case "album":
lychee.header.removeClass("view"); lychee.header.removeClass("view");
$("#tools_albums, #tools_photo").hide(); $("#tools_albums, #tools_photo").hide();
$("#tools_album").show(); $("#tools_album").show();
album.json.content === false ? $("#button_archive").hide() : $("#button_archive").show(); album.json.content === false ? $("#button_archive").hide() : $("#button_archive").show();
if (lychee.publicMode&&album.json.downloadable==="0") $("#button_archive").hide(); if (lychee.publicMode&&album.json.downloadable==="0") $("#button_archive").hide();
if (albumID==="s"||albumID==="f"||albumID==="r") { if (albumID==="s"||albumID==="f"||albumID==="r") {
@ -73,11 +79,15 @@ view = {
} else { } else {
$("#button_info_album, #button_trash_album, #button_share_album").show(); $("#button_info_album, #button_trash_album, #button_share_album").show();
} }
break; break;
case "photo": case "photo":
lychee.header.addClass("view"); lychee.header.addClass("view");
$("#tools_albums, #tools_album").hide(); $("#tools_albums, #tools_album").hide();
$("#tools_photo").show(); $("#tools_photo").show();
break; break;
} }
@ -122,27 +132,32 @@ view = {
content: { content: {
scrollPosition: 0,
init: function() { init: function() {
var smartData = "", var smartData = "",
albumsData = ""; albumsData = "";
/* Smart Albums */ /* Smart Albums */
albums.parse(albums.json.unsortedAlbum); albums.parse(albums.json.unsortedAlbum);
albums.parse(albums.json.publicAlbum); albums.parse(albums.json.publicAlbum);
albums.parse(albums.json.starredAlbum); albums.parse(albums.json.starredAlbum);
albums.parse(albums.json.recentAlbum); albums.parse(albums.json.recentAlbum);
if (!lychee.publicMode) smartData = build.divider("Smart Albums") + build.album(albums.json.unsortedAlbum) + build.album(albums.json.starredAlbum) + build.album(albums.json.publicAlbum) + build.album(albums.json.recentAlbum); if (!lychee.publicMode) smartData = build.divider("Smart Albums") + build.album(albums.json.unsortedAlbum) + build.album(albums.json.starredAlbum) + build.album(albums.json.publicAlbum) + build.album(albums.json.recentAlbum);
/* Albums */ /* Albums */
if (albums.json.content) { if (albums.json.content) {
if (!lychee.publicMode) albumsData = build.divider("Albums");
$.each(albums.json.content, function() { $.each(albums.json.content, function() {
albums.parse(this); albums.parse(this);
albumsData += build.album(this);
//display albums in reverse order
albumsData = build.album(this) + albumsData;
}); });
if (!lychee.publicMode) albumsData = build.divider("Albums") + albumsData;
} }
if (smartData===""&&albumsData==="") { if (smartData===""&&albumsData==="") {
@ -154,6 +169,11 @@ view = {
$("img[data-type!='nonretina']").retina(); $("img[data-type!='nonretina']").retina();
/* Restore scroll position */
if (view.albums.content.scrollPosition!==null) {
$("html, body").scrollTop(view.albums.content.scrollPosition);
}
}, },
title: function(albumID) { title: function(albumID) {
@ -163,7 +183,7 @@ view = {
title = albums.json.content[albumID].title; title = albums.json.content[albumID].title;
if (albums.json.content[albumID].password) prefix = "<span class='icon-lock'></span> "; if (albums.json.content[albumID].password) prefix = "<span class='icon-lock'></span> ";
if (title.length>18) { if (title!==null&&title.length>18) {
longTitle = title; longTitle = title;
title = title.substr(0, 18) + "..."; title = title.substr(0, 18) + "...";
} }
@ -251,6 +271,10 @@ view = {
$("img[data-type!='svg']").retina(); $("img[data-type!='svg']").retina();
/* Save and reset scroll position */
view.albums.content.scrollPosition = $(document).scrollTop();
$("html, body").scrollTop(0);
}, },
title: function(photoID) { title: function(photoID) {
@ -258,7 +282,7 @@ view = {
var longTitle = "", var longTitle = "",
title = album.json.content[photoID].title; title = album.json.content[photoID].title;
if (title.length>18) { if (title!==null&&title.length>18) {
longTitle = title; longTitle = title;
title = title.substr(0, 18) + "..."; title = title.substr(0, 18) + "...";
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
var gulp = require('gulp'), var gulp = require('gulp'),
plugins = require("gulp-load-plugins")(); plugins = require("gulp-load-plugins")();
paths = { var paths = {
view: [ view: [
'bower_components/jQuery/dist/jquery.min.js', 'bower_components/jQuery/dist/jquery.min.js',
'bower_components/js-md5/js/md5.min.js', 'bower_components/js-md5/js/md5.min.js',
@ -23,7 +23,14 @@ paths = {
] ]
} }
gulp.task('view', function () { var catchError = function(err) {
console.log(err.toString());
this.emit('end');
}
gulp.task('view', function() {
gulp.src(paths.view) gulp.src(paths.view)
.pipe(plugins.concat('view.js', {newLine: "\n"})) .pipe(plugins.concat('view.js', {newLine: "\n"}))
@ -32,19 +39,21 @@ gulp.task('view', function () {
}); });
gulp.task('js', function () { gulp.task('js', function() {
gulp.src(paths.js) gulp.src(paths.js)
.pipe(plugins.concat('main.js', {newLine: "\n"})) .pipe(plugins.concat('main.js', {newLine: "\n"}))
.pipe(plugins.uglify()) .pipe(plugins.uglify())
.on('error', catchError)
.pipe(gulp.dest('../assets/min/')); .pipe(gulp.dest('../assets/min/'));
}); });
gulp.task('css', function () { gulp.task('css', function() {
gulp.src(paths.css) gulp.src(paths.css)
.pipe(plugins.sass()) .pipe(plugins.sass())
.on('error', catchError)
.pipe(plugins.concat('main.css', {newLine: "\n"})) .pipe(plugins.concat('main.css', {newLine: "\n"}))
.pipe(plugins.autoprefixer('last 4 versions', '> 5%')) .pipe(plugins.autoprefixer('last 4 versions', '> 5%'))
.pipe(plugins.minifyCss()) .pipe(plugins.minifyCss())

View File

@ -1,6 +1,6 @@
{ {
"name": "Lychee", "name": "Lychee",
"version": "2.6.2", "version": "2.6.3",
"description": "Self-hosted photo-management done right.", "description": "Self-hosted photo-management done right.",
"authors": "Tobias Reich <tobias.reich.ich@gmail.com>", "authors": "Tobias Reich <tobias.reich.ich@gmail.com>",
"license": "MIT", "license": "MIT",
@ -10,11 +10,11 @@
}, },
"devDependencies": { "devDependencies": {
"gulp": "^3.8.8", "gulp": "^3.8.8",
"gulp-autoprefixer": "1.0.0", "gulp-autoprefixer": "1.0.1",
"gulp-concat": "^2.4.0", "gulp-concat": "^2.4.1",
"gulp-load-plugins": "^0.6.0", "gulp-load-plugins": "^0.7.0",
"gulp-minify-css": "^0.3.8", "gulp-minify-css": "^0.3.10",
"gulp-sass": "^0.7.3", "gulp-sass": "^1.0.0",
"gulp-uglify": "^1.0.1" "gulp-uglify": "^1.0.1"
} }
} }

View File

@ -1,3 +1,16 @@
## v2.6.3
Released ??, 2014
- `New` Caching for albums (Thanks @r0x0r, #232)
- `New` Save scroll position of albums (Thanks @r0x0r, #232)
- `New` Added Dockerfile (@renfredxh, #236)
- `Improved` Newest album on the top (Thanks @r0x0r, #232)
- `Fixed` Login in private mode (Safari)
- `Fixed` Drag & Drop with open photo
- `Fixed` Wrong modified date of the photo files
- `Fixed` Search function always returned all photos (Thanks @powentan, #234)
## v2.6.2 ## v2.6.2
Released September 12, 2014 Released September 12, 2014

View File

@ -16,7 +16,7 @@
<link rel="apple-touch-icon" href="assets/img/apple-touch-icon-iphone.png" sizes="120x120"> <link rel="apple-touch-icon" href="assets/img/apple-touch-icon-iphone.png" sizes="120x120">
<link rel="apple-touch-icon" href="assets/img/apple-touch-icon-ipad.png" sizes="152x152"> <link rel="apple-touch-icon" href="assets/img/apple-touch-icon-ipad.png" sizes="152x152">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0, maximum-scale=1.0, minimal-ui"> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1.0, maximum-scale=1.0">
<meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes">

View File

@ -10,6 +10,9 @@ if (!defined('LYCHEE')) exit('Error: Direct access is not allowed!');
function lycheeAutoloaderModules($class_name) { function lycheeAutoloaderModules($class_name) {
$modules = array('Album', 'Database', 'Import', 'Log', 'Module', 'Photo', 'Plugins', 'Session', 'Settings');
if (!in_array($class_name, $modules)) return false;
$file = LYCHEE . 'php/modules/' . $class_name . '.php'; $file = LYCHEE . 'php/modules/' . $class_name . '.php';
if (file_exists($file)!==false) require $file; if (file_exists($file)!==false) require $file;
@ -17,6 +20,9 @@ function lycheeAutoloaderModules($class_name) {
function lycheeAutoloaderAccess($class_name) { function lycheeAutoloaderAccess($class_name) {
$access = array('Access', 'Admin', 'Guest', 'Installation');
if (!in_array($class_name, $access)) return false;
$file = LYCHEE . 'php/access/' . $class_name . '.php'; $file = LYCHEE . 'php/access/' . $class_name . '.php';
if (file_exists($file)!==false) require $file; if (file_exists($file)!==false) require $file;

View File

@ -65,27 +65,27 @@ class Album extends Module {
switch ($this->albumIDs) { switch ($this->albumIDs) {
case 'f': $return['public'] = false; case 'f': $return['public'] = false;
$query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp FROM ? WHERE star = 1 " . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS)); $query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE star = 1 " . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS));
break; break;
case 's': $return['public'] = false; case 's': $return['public'] = false;
$query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp FROM ? WHERE public = 1 " . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS)); $query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE public = 1 " . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS));
break; break;
case 'r': $return['public'] = false; case 'r': $return['public'] = false;
$query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp FROM ? WHERE LEFT(id, 10) >= unix_timestamp(DATE_SUB(NOW(), INTERVAL 1 DAY)) " . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS)); $query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE LEFT(id, 10) >= unix_timestamp(DATE_SUB(NOW(), INTERVAL 1 DAY)) " . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS));
break; break;
case '0': $return['public'] = false; case '0': $return['public'] = false;
$query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp FROM ? WHERE album = 0 " . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS)); $query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE album = 0 " . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS));
break; break;
default: $query = Database::prepare($this->database, "SELECT * FROM ? WHERE id = '?' LIMIT 1", array(LYCHEE_TABLE_ALBUMS, $this->albumIDs)); default: $query = Database::prepare($this->database, "SELECT * FROM ? WHERE id = '?' LIMIT 1", array(LYCHEE_TABLE_ALBUMS, $this->albumIDs));
$albums = $this->database->query($query); $albums = $this->database->query($query);
$return = $albums->fetch_assoc(); $return = $albums->fetch_assoc();
$return['sysdate'] = date('d M. Y', $return['sysstamp']); $return['sysdate'] = date('d M. Y', $return['sysstamp']);
$return['password'] = ($return['password']=='' ? false : true); $return['password'] = ($return['password']=='' ? false : true);
$query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp FROM ? WHERE album = '?' " . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS, $this->albumIDs)); $query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE album = '?' " . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS, $this->albumIDs));
break; break;
} }
@ -101,6 +101,9 @@ class Album extends Module {
$photo['nextPhoto'] = ''; $photo['nextPhoto'] = '';
$photo['thumbUrl'] = LYCHEE_URL_UPLOADS_THUMB . $photo['thumbUrl']; $photo['thumbUrl'] = LYCHEE_URL_UPLOADS_THUMB . $photo['thumbUrl'];
# Parse url
$photo['url'] = LYCHEE_URL_UPLOADS_BIG . $photo['url'];
if (isset($photo['takestamp'])&&$photo['takestamp']!=='0') { if (isset($photo['takestamp'])&&$photo['takestamp']!=='0') {
$photo['cameraDate'] = 1; $photo['cameraDate'] = 1;
$photo['sysdate'] = date('d F Y', $photo['takestamp']); $photo['sysdate'] = date('d F Y', $photo['takestamp']);

View File

@ -24,6 +24,9 @@ class Database extends Module {
if ($database->server_version<50500) $database->set_charset('GBK'); if ($database->server_version<50500) $database->set_charset('GBK');
else $database->set_charset("utf8"); else $database->set_charset("utf8");
# Set unicode
$database->query('SET NAMES utf8;');
# Check database # Check database
if (!$database->select_db($name)) if (!$database->select_db($name))
if (!Database::createDatabase($database, $name)) exit('Error: Could not create database!'); if (!Database::createDatabase($database, $name)) exit('Error: Could not create database!');
@ -41,6 +44,7 @@ class Database extends Module {
# Check dependencies # Check dependencies
Module::dependencies(isset($database, $dbName)); Module::dependencies(isset($database, $dbName));
if (!isset($version)) return true;
# List of updates # List of updates
$updates = array( $updates = array(
@ -56,7 +60,7 @@ class Database extends Module {
# For each update # For each update
foreach ($updates as $update) { foreach ($updates as $update) {
if (isset($version)&&$update<=$version) continue; if ($update<=$version) continue;
# Load update # Load update
include(__DIR__ . '/../database/update_' . $update . '.php'); include(__DIR__ . '/../database/update_' . $update . '.php');

View File

@ -161,7 +161,7 @@ class Photo extends Module {
} }
# Set original date # Set original date
if ($info['takestamp']!=='') @touch($path, $info['takestamp']); if ($info['takestamp']!==''&&$info['takestamp']!==0) @touch($path, $info['takestamp']);
# Create Thumb # Create Thumb
if (!$this->createThumb($path, $photo_name)) { if (!$this->createThumb($path, $photo_name)) {

View File

@ -99,7 +99,8 @@ $imagick = extension_loaded('imagick');
if ($imagick===false) $imagick = '-'; if ($imagick===false) $imagick = '-';
if ($imagick===true) $imagickVersion = @Imagick::getVersion(); if ($imagick===true) $imagickVersion = @Imagick::getVersion();
if (!isset($imagickVersion)||$imagickVersion==='') $imagickVersion = '-'; if (!isset($imagickVersion, $imagickVersion['versionNumber'])||$imagickVersion==='') $imagickVersion = '-';
else $imagickVersion = $imagickVersion['versionNumber'];
$gdVersion = gd_info(); $gdVersion = gd_info();
@ -111,7 +112,7 @@ echo('PHP Version: ' . floatval(phpversion()) . PHP_EOL);
echo('MySQL Version: ' . $database->server_version . PHP_EOL); echo('MySQL Version: ' . $database->server_version . PHP_EOL);
echo('Imagick: ' . $imagick . PHP_EOL); echo('Imagick: ' . $imagick . PHP_EOL);
echo('Imagick Active: ' . $settings['imagick'] . PHP_EOL); echo('Imagick Active: ' . $settings['imagick'] . PHP_EOL);
echo('Imagick Version: ' . $imagickVersion['versionNumber'] . PHP_EOL); echo('Imagick Version: ' . $imagickVersion . PHP_EOL);
echo('GD Version: ' . $gdVersion['GD Version'] . PHP_EOL); echo('GD Version: ' . $gdVersion['GD Version'] . PHP_EOL);
?> ?>