New:
- Protect public albums with passwords
- Export to Dropbox
- Sharing-Link is displayed directly inside the sharing-dropdown
- Delete photos with cmd+backspace

Improved:
- Massive speed improvements
- Changing the title, starring, description, etc. is now instant
- Longer filenames for pictures (more security)

ShortLinks are removed for more independency and privacy.
There are a lot of changes under the hood, including a lot of bug fixes and improvements. Please report every bug you find!

How to update:
1. Replace all files, excluding `uploads/` and `php/config.php`
2. Open `php/update.php` in your browser
This commit is contained in:
Tobias Reich 2013-09-03 11:59:30 +02:00
parent 4e5c836b8d
commit 34413640e4
25 changed files with 2119 additions and 1072 deletions

View File

@ -427,28 +427,6 @@
}
}
/* shake ------------------------------------------------*/
@-webkit-keyframes shake {
0%, 100% { -webkit-transform: translateX(0); }
10%, 30%, 50%, 70%, 90% { -webkit-transform: translateX(-10px); }
20%, 40%, 60%, 80% { -webkit-transform: translateX(10px); }
}
@-moz-keyframes shake {
0%, 100% { -moz-transform: translateX(0);}
10%, 30%, 50%, 70%, 90% { -moz-transform: translateX(-10px); }
20%, 40%, 60%, 80% { -moz-transform: translateX(10px); }
}
@-o-keyframes shake {
0%, 100% { -o-transform: translateX(0);}
10%, 30%, 50%, 70%, 90% { -o-transform: translateX(-10px); }
20%, 40%, 60%, 80% { -o-transform: translateX(10px); }
}
@keyframes shake {
0%, 100% { transform: translateX(0);}
10%, 30%, 50%, 70%, 90% { transform: translateX(-10px); }
20%, 40%, 60%, 80% { transform: translateX(10px); }
}
/* pulse ------------------------------------------------*/
@-webkit-keyframes pulse {
0% {

View File

@ -167,23 +167,6 @@ body { background-color: #222; background-image: url(../img/background.jpg); fon
animation-duration: .3s;
animation-fill-mode: forwards;
}
.shake {
-webkit-animation-name: shake;
-webkit-animation-duration: 1s;
-webkit-animation-timing-function: ease-out;
-webkit-animation-fill-mode: forwards;
-moz-animation-name: shake;
-moz-animation-duration: .3s;
-moz-animation-fill-mode: forwards;
-o-animation-name: shake;
-o-animation-duration: 1s;
-o-animation-timing-function: ease-out;
-o-animation-fill-mode: forwards;
animation-name: shake;
animation-duration: 1s;
animation-timing-function: ease-out;
animation-fill-mode: forwards;
}
/* Loading ------------------------------------------------*/
#loading {
@ -440,7 +423,7 @@ header {
position: absolute;
width: 200px;
height: 200px;
background-image: url(../img/checks.png);
background-color: #222;
border-radius: 3px;
box-shadow: 0px 1px 5px #111;
border: 3px solid #ccc;
@ -483,7 +466,7 @@ header {
position: absolute;
width: 200px;
height: 200px;
background-image: url(../img/checks.png);
background-color: #222;
border-radius: 3px;
box-shadow: 0px 1px 5px #111;
border: 3px solid #ccc;
@ -504,7 +487,6 @@ header {
background: -o-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,0) 20%,rgba(0,0,0,0.9) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,0) 20%,rgba(0,0,0,0.9) 100%); /* IE10+ */
background: linear-gradient(top, rgba(0,0,0,0) 0%,rgba(0,0,0,0) 20%,rgba(0,0,0,0.9) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00000000', endColorstr='#e6000000',GradientType=0 ); /* IE6-9 */
}
.photo .overlay {
opacity: 0;
@ -569,7 +551,6 @@ header {
background: -o-linear-gradient(top, rgba(0,0,0,1) 0%,rgba(0,0,0,0) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, rgba(0,0,0,1) 0%,rgba(0,0,0,0) 100%); /* IE10+ */
background: linear-gradient(top, rgba(0,0,0,1) 0%,rgba(0,0,0,0) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#000000', endColorstr='#00000000',GradientType=0 ); /* IE6-9 */
opacity: .4;
}
.album .badge.icon-star::after {
@ -740,6 +721,9 @@ header {
text-shadow: 0px -1px 0px #222;
line-height: 20px;
}
.message p b {
font-weight: bold;
}
.message .button {
float: right;
margin: 15px 15px 15px 0px;
@ -882,24 +866,27 @@ header {
color: #888;
}
/* Copy Link ------------------------------------------------*/
.copylink {
/* Copy Link, Password ------------------------------------------------*/
.message .copylink, .message .password {
float: left;
width: 95%;
padding: 7px 10px 9px 10px;
margin-top: 10px;
margin-top: 20px;
background-color: #444;
color: #fff;
text-shadow: 0px 1px 0px #222;
border: none;
border: 1px solid #111;
box-shadow: 0px 1px 0px #777;
box-shadow: 0px 1px 0px #666, inset 0px 0px 3px #333, 0px 0px 5px #005ecc;
outline: none;
border-radius: 5px;
}
.message .copylink {
margin-bottom: 20px;
}
/* Image View ------------------------------------------------*/
#image_view {
#imageview {
position: fixed;
display: none;
width: 100%;
@ -908,11 +895,11 @@ header {
box-shadow: 0px 2px 4px #000;
-webkit-transition: background-color .3s;
}
#image_view.full {
#imageview.full {
background-color: #111;
}
#image_view #image {
#imageview #image {
position: absolute;
top: 70px;
right: 30px;
@ -936,7 +923,7 @@ header {
animation-duration: .3s;
animation-fill-mode: forwards;
}
#image_view #image.small {
#imageview #image.small {
top: 50%;
right: auto;
bottom: auto;
@ -944,7 +931,7 @@ header {
}
/* Previous/Next Buttons ------------------------------------------------*/
#image_view a {
#imageview a {
position: fixed;
top: 50%;
margin-top: -10px;
@ -955,21 +942,21 @@ header {
opacity: .1;
z-index: 1;
}
#image_view a:hover {
#imageview a:hover {
opacity: .9;
}
#image_view a#previous {
#imageview a#previous {
left: 20px;
-webkit-transition: left .3s;
}
#image_view.full a#previous {
#imageview.full a#previous {
left: -50px;
}
#image_view a#next {
#imageview a#next {
right: 20px;
-webkit-transition: right .3s
}
#image_view.full a#next {
#imageview.full a#next {
right: -50px;
}
@ -1153,6 +1140,11 @@ header {
background-image: -ms-linear-gradient(top, #6a84f2, #3959ef);
background-image: linear-gradient(top, #6a84f2, #3959ef);
}
.contextmenu tr.no_hover:hover {
cursor: inherit;
background-color: inherit;
background-image: none;
}
.contextmenu tr.separator {
float: left;
height: 1px;
@ -1178,6 +1170,9 @@ header {
box-shadow: inset 0px 1px 0px rgba(255,255,255,.1);
text-shadow: 0px -1px 0px rgba(0,0,0,.7);
}
.contextmenu tr.no_hover:hover td {
box-shadow: none;
}
.contextmenu tr a {
float: left;
width: 10px;
@ -1185,6 +1180,24 @@ header {
text-align: center;
}
/* Direct Link Input ------------------------------------------------*/
.contextmenu #link {
float: right;
width: 140px;
margin: 0px -10px -1px 0px;
padding: 4px 6px 5px 6px;
background-color: #444;
color: #fff;
border: none;
border: 1px solid #111;
box-shadow: 0px 1px 0px rgba(255,255,255,.1);
outline: none;
border-radius: 5px;
}
.contextmenu tr a#link_icon {
padding-top: 4px;
}
/* Upload ------------------------------------------------*/
#upload {
display: none;
@ -1327,7 +1340,7 @@ header {
/* Screen behavior -------------------------------------------------*/
@media only screen and (max-width: 900px) {
#title { margin: 0px 30%; width: 50%; }
#title { margin: 0px 20%; width: 40%; }
#title.view { margin: 11px 20% 0px 20%; width: 60%; }
#title span { display: none; }
@ -1372,7 +1385,7 @@ header {
height: 100px;
margin: 30px 5% -10px 5%;
}
.add_album .icon {
margin-top: 18px;
font-size: 50px;

32
index.html Executable file → Normal file
View File

@ -66,7 +66,7 @@
<div id="content"></div>
<!-- ImageView -->
<div id="image_view"></div>
<div id="imageview"></div>
<!-- Infobox -->
<div id="infobox"></div>
@ -79,22 +79,26 @@
</div>
<!-- JS -->
<script type="text/javascript" src="js/frameworks.js"></script>
<script defer type="text/javascript" src="js/frameworks.js"></script>
<!-- Development
<script type="text/javascript" src="js/modules/lychee.js"></script>
<script type="text/javascript" src="js/modules/build.js"></script>
<script type="text/javascript" src="js/modules/albums.js"></script>
<script type="text/javascript" src="js/modules/photos.js"></script>
<script type="text/javascript" src="js/modules/visible.js"></script>
<script type="text/javascript" src="js/modules/loadingBar.js"></script>
<script type="text/javascript" src="js/modules/contextMenu.js"></script>
<script type="text/javascript" src="js/modules/search.js"></script> -->
<!-- Development
<script defer type="text/javascript" src="js/modules/lychee.js"></script>
<script defer type="text/javascript" src="js/modules/build.js"></script>
<script defer type="text/javascript" src="js/modules/view.js"></script>
<script defer type="text/javascript" src="js/modules/password.js"></script>
<script defer type="text/javascript" src="js/modules/modal.js"></script>
<script defer type="text/javascript" src="js/modules/album.js"></script>
<script defer type="text/javascript" src="js/modules/albums.js"></script>
<script defer type="text/javascript" src="js/modules/photo.js"></script>
<script defer type="text/javascript" src="js/modules/visible.js"></script>
<script defer type="text/javascript" src="js/modules/loadingBar.js"></script>
<script defer type="text/javascript" src="js/modules/contextMenu.js"></script>
<script defer type="text/javascript" src="js/modules/search.js"></script> -->
<!-- Production -->
<script type="text/javascript" src="js/functions.js"></script>
<!-- Production -->
<script defer type="text/javascript" src="js/functions.js"></script>
<script type="text/javascript" src="js/main.js"></script>
<script defer type="text/javascript" src="js/main.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -5,77 +5,87 @@
* @copyright 2013 by Philipp Maurer, Tobias Reich
*/
/* Modules */
lychee.init("php/api.php", "");
$(document).ready(function(){
/* Event Name */
if (mobileBrowser()) event_name = "touchend";
else event_name = "click";
/* Init */
lychee.init();
/* Toolbar */
$("#button_signout").on(event_name, lychee.logout);
$("#button_download").on(event_name, function() {
link = $("#image_view #image").css("background-image").replace(/"/g,"").replace(/url\(|\)$/ig, "");
window.open(link,"_newtab");
});
/* Event Name */
var event_name = (mobileBrowser()) ? "touchend" : "click";
/* Notifications */
if (window.webkitNotifications) window.webkitNotifications.requestPermission();
/* Tooltips */
if (!mobileBrowser()) $(".tools").tipsy({gravity: 'n'});
/* Header */
$("#button_share").on(event_name, function(e) {
if ($("#button_share a.active").length) contextMenu.share(lychee.image_view.attr("data-id"), e.pageX, e.pageY);
else photos.setPublic(e);
if (photo.json.public==1||photo.json.public==2) contextMenu.sharePhoto(photo.getID(), e);
else photo.setPublic(photo.getID(), e);
});
$("#button_share_album").on(event_name, function(e) {
if ($("#button_share_album a.active").length) contextMenu.share_album(lychee.content.attr("data-id"), e.pageX, e.pageY);
else albums.setPublic(e);
if (album.json.public==1) contextMenu.shareAlbum(album.getID(), e);
else modal.show("Share Album", "All photos inside this album will be public and visible for everyone. Existing public photos will have the same sharing permission as this album. Are your sure you want to share this album?", [["Share Album", function() { album.setPublic(album.getID(), e) }], ["Cancel", function() {}]]);
});
$("#button_trash_album").on(event_name, function() { albums.deleteDialog(lychee.content.attr("data-id")) });
$("#button_move").on(event_name, function(e) { contextMenu.move(lychee.image_view.attr("data-id"), e.pageX, e.pageY) });
$("#button_trash").on(event_name, function() { photos.deleteDialog() });
$("#button_edit_album").on(event_name, function() { albums.setTitle() });
$("#button_edit").on(event_name, function() { photos.setTitle() });
$("#button_info").on(event_name, function() { photos.showInfobox() });
$("#button_archive").on(event_name, function() { albums.getArchive() });
$("#button_star").on(event_name, function() { photos.setStar() });
$(".copylink").on(event_name, function() { $(this).select() });
$("#button_signout").on(event_name, lychee.logout);
$("#button_download").on(event_name, function() { window.open(photo.getDirectLink(),"_newtab") });
$("#button_trash_album").on(event_name, function() { album.delete(album.getID()) });
$("#button_move").on(event_name, function(e) { contextMenu.move(photo.getID(), e) });
$("#button_trash").on(event_name, function() { photo.delete() });
$("#button_edit_album").on(event_name, function() { album.setTitle() });
$("#button_edit").on(event_name, function() { photo.setTitle(photo.getID()) });
$("#button_info").on(event_name, function() { view.photo.showInfobox() });
$("#button_archive").on(event_name, function() { album.getArchive(album.getID()) });
$("#button_star").on(event_name, function() { photo.setStar(photo.getID()) });
/* Search */
$("#search").on("keyup click", function() { search.find($(this).val()) });
/* Back Buttons */
$("#button_back_home").on(event_name, function() { lychee.goto("") });
$("#button_back").on(event_name, function() { lychee.goto("a" + lychee.content.attr("data-id")) });
$("#button_back").on(event_name, function() { lychee.goto("a" + album.getID()) });
/* Image View */
$("#image_view")
.on(event_name, "a#previous", photos.previous)
.on(event_name, "a#next", photos.next);
lychee.imageview
.on(event_name, "a#previous", function() {
if (photo.json&&photo.json.previousPhoto) lychee.goto("a" + album.getID() + "p" + photo.json.previousPhoto)
})
.on(event_name, "a#next", function() {
if (photo.json&&photo.json.nextPhoto) lychee.goto("a" + album.getID() + "p" + photo.json.nextPhoto)
});
/* Infobox */
$("#infobox")
.on(event_name, ".header a", function() { photos.hideInfobox() })
.on(event_name, "#edit_title", function() { photos.setTitle() })
.on(event_name, "#edit_description", function() { photos.setDescription() });
.on(event_name, ".header a", function() { view.photo.hideInfobox() })
.on(event_name, "#edit_title", function() { photo.setTitle(photo.getID()) })
.on(event_name, "#edit_description", function() { photo.setDescription(photo.getID()) });
/* Keyboard */
Mousetrap
.bind('n', function(e) { $("body").append(build.addModal) })
.bind('n', function(e) { if (!visible.message()) $("body").append(build.addModal) })
.bind('u', function(e) { $("#auswahl").html(""); $("#upload_files").click() })
.bind('s', function(e) { if (visible.imageview()) $("#button_star").click() })
.bind('f', function(e) { if (visible.imageview()) $("#button_download").click() })
.bind('i', function(e) { if (visible.imageview()) photos.showInfobox() })
.bind('backspace', function(e) { if (visible.imageview()) photos.deleteDialog() })
.bind('left', function(e) { if (visible.imageview()) photos.previous() })
.bind('right', function(e) { if (visible.imageview()) photos.next() });
.bind('s', function(e) { if (visible.photo()) $("#button_star").click() })
.bind('f', function(e) { if (visible.photo()) $("#button_download").click() })
.bind('command+backspace', function(e) { if (visible.photo()&&!visible.message()) photo.delete() })
.bind('left', function(e) { if (visible.photo()) $("#imageview a#previous").click() })
.bind('right', function(e) { if (visible.photo()) $("#imageview a#next").click() })
.bind('i', function(e) {
if (visible.infobox()) view.photo.hideInfobox();
else if (visible.photo()) view.photo.showInfobox();
});
Mousetrap.bindGlobal('enter', function(e) {
if ($(".message .button.active").length) $(".message .button.active").addClass("pressed").click()
});
Mousetrap.bindGlobal('esc', function(e) {
Mousetrap.bindGlobal(['esc', 'command+up'], function(e) {
e.preventDefault();
if ($(".message").length) lychee.closeModal();
else if (visible.infobox()) photos.hideInfobox();
else if (visible.imageview()) lychee.goto("a" + lychee.content.attr("data-id"));
if (visible.message()) modal.close();
else if (visible.contextMenu()) contextMenu.close();
else if (visible.infobox()) view.photo.hideInfobox();
else if (visible.photo()) lychee.goto("a" + album.getID());
else if (visible.album()) lychee.goto("");
else if (visible.albums()&&$("#search").val().length!=0) search.reset();
});
@ -83,30 +93,32 @@ $(document).ready(function(){
$(document)
/* Login */
.on(event_name, "#button_signin", function() { lychee.showLogin() })
.on(event_name, "#button_signin", function() { lychee.loginDialog() })
.on("keyup", "#password", function() { if ($(this).val().length>0) $(this).removeClass("error") })
/* Toolbar */
.on(event_name, "#title.editable", function() { if (visible.imageview()) photos.setTitle(); else albums.setTitle(); })
/* Header */
.on(event_name, "#title.editable", function() {
if (visible.photo()) photo.setTitle(photo.getID());
else album.setTitle();
})
/* Navigation */
.on("click", ".album", function() { lychee.goto("a" + $(this).attr("data-id")) })
.on("click", ".photo", function() {
if (lychee.content.attr("data-id")!="") lychee.goto("a" + lychee.content.attr("data-id") + "p" + $(this).attr("data-id"));
else lychee.goto("a" + $(this).attr("data-album-id") + "p" + $(this).attr("data-id"));
})
.on("click", ".photo", function() { lychee.goto("a" + album.getID() + "p" + $(this).attr("data-id")) })
/* Modal */
.on(event_name, ".message .close", lychee.closeModal)
.on(event_name, ".message .close", modal.close)
.on(event_name, ".message .button:first", function() { modal.fns[0](); modal.close(); })
.on(event_name, ".message .button:last", function() { modal.fns[1](); modal.close(); })
/* Add Dialog */
.on(event_name, ".button_add", function() { $("body").append(build.addModal) })
.on(event_name, "#add_album", albums.add)
.on(event_name, "#add_link", lychee.importUrl)
.on(event_name, "#add_album", album.add)
.on(event_name, "#add_link", function() { photo.add.url() })
.on(event_name, "#add_photo", function() { $("#auswahl").html(""); $("#upload_files").click() })
/* Upload */
.on("change", "#upload_files", function() { lychee.closeModal(); lychee.upload(this.files); })
.on("change", "#upload_files", function() { modal.close(); photo.add.files(this.files); })
/* Context Menu */
.on("contextmenu", ".photo", contextMenu.photo)
@ -114,22 +126,22 @@ $(document).ready(function(){
.on(event_name, ".contextmenu_bg", contextMenu.close)
/* Infobox */
.on(event_name, "#infobox_overlay", function() { photos.hideInfobox() })
.on(event_name, "#infobox_overlay", function() { view.photo.hideInfobox() })
/* Controls */
.bind("mouseenter", lychee.showControls)
.bind("mouseleave", lychee.hideControls)
.bind("mouseenter", view.header.show)
.bind("mouseleave", view.header.hide)
/* Upload */
.on("dragover", function(e) { e.preventDefault(); }, false)
.on("drop", function(e) {
e.stopPropagation();
e.preventDefault();
lychee.upload(e.originalEvent.dataTransfer.files);
photo.add.files(e.originalEvent.dataTransfer.files);
return true;
});
/* Init */
lychee.ready();
/* Run */
lychee.run();
});

244
js/modules/album.js Normal file
View File

@ -0,0 +1,244 @@
/**
* @name album.js
* @author Philipp Maurer
* @author Tobias Reich
* @copyright 2013 by Philipp Maurer, Tobias Reich
*
* Album Module
* Takes care of every action an album can handle and execute.
*/
album = {
json: null,
getID: function() {
var id;
if (photo.json) id = photo.json.album;
else if (album.json) id = album.json.id;
else id = $(".album:hover, .album.active").attr("data-id");
// Search
if (!id) id = $(".photo:hover, .photo.active").attr("data-album-id");
if (id) return id;
else return false;
},
load: function(albumID, refresh) {
var startTime,
params,
durationTime,
waitTime,
photosData = "";
password.get(albumID, function() {
if (!refresh) {
loadingBar.show();
lychee.animate(".album, .photo", "contentZoomOut");
lychee.animate(".divider", "fadeOut");
}
startTime = new Date().getTime();
params = "getAlbum&albumID=" + albumID + "&password=" + password.value;
lychee.api(params, "json", function(data) {
if (data=="HTTP/1.1 403 Album private!") {
lychee.setMode("view");
return false;
}
if (data=="HTTP/1.1 403 Wrong password!") {
album.load(albumID, refresh);
return false;
}
album.json = data;
durationTime = (new Date().getTime() - startTime);
if (durationTime>300) waitTime = 0; else if (refresh) waitTime = 0; else waitTime = 300 - durationTime;
if (!visible.albums()&&!visible.photo()&&!visible.album()) waitTime = 0;
$.timer(waitTime, function() {
view.album.init();
if (!refresh) {
lychee.animate(".album, .photo", "contentZoomIn");
view.header.mode("album");
}
}, false);
});
});
},
parse: function(photo) {
if (photo&&photo.thumbUrl) photo.thumbUrl = lychee.upload_path_thumb + photo.thumbUrl;
else if (!album.json.title) album.json.title = "Untitled";
},
add: function() {
var title = prompt("Please enter a title for this album:", "Untitled"),
params;
if (title.length>0&&title.length<31) {
modal.close();
params = "addAlbum&title=" + escape(encodeURI(title));
lychee.api(params, "text", function(data) {
if (data) lychee.goto("a" + data);
else loadingBar.show("error");
});
} else if (title.length>0) loadingBar.show("error", "Error", "Title to short or too long. Please try another one!");
},
delete: function(albumID) {
var params,
buttons,
albumTitle;
buttons = [
["Delete Album and Photos", function() {
params = "deleteAlbum&albumID=" + albumID + "&delAll=true";
lychee.api(params, "text", function(data) {
if (visible.albums()) view.albums.content.delete(albumID);
else lychee.goto("");
if (!data) loadingBar.show("error");
});
}],
["Keep Album", function() {}]
];
if (albumID==0) {
buttons[0][0] = "Clear Unsorted";
modal.show("Clear Unsorted", "Are you sure you want to delete all photos from 'Unsorted'?<br>This action can't be undone!", buttons)
} else {
if (album.json) albumTitle = album.json.title;
else if (albums.json) albumTitle = albums.json.content[albumID].title;
modal.show("Delete Album", "Are you sure you want to delete the album '" + albumTitle + "' and all of the photos it contains? This action can't be undone!", buttons);
}
},
setTitle: function(albumID) {
var oldTitle = "",
newTitle,
params;
if (!albumID) albumID = album.getID();
if (album.json) oldTitle = album.json.title;
else if (albums.json) oldTitle = albums.json.content[albumID].title;
newTitle = prompt("Please enter a new title for this album:", oldTitle);
if (albumID!=""&&albumID!=null&&albumID&&newTitle.length>0&&newTitle.length<31) {
if (visible.album()) {
album.json.title = newTitle;
view.album.title();
} else if (visible.albums()) {
albums.json.content[albumID].title = newTitle;
view.albums.content.title(albumID);
}
params = "setAlbumTitle&albumID=" + albumID + "&title=" + escape(encodeURI(newTitle));
lychee.api(params, "text", function(data) {
if (!data) loadingBar.show("error");
});
} else if (newTitle.length>0) loadingBar.show("error", "Error", "New title to short or too long. Please try another one!");
},
setPublic: function(albumID, e) {
var params;
if (visible.album()) {
album.json.public = (album.json.public==0) ? 1 : 0;
album.json.password = (album.json.public==false) ? true : false;
view.album.public();
if (album.json.public==1) contextMenu.shareAlbum(albumID, e);
}
params = "setAlbumPublic&albumID=" + albumID;
lychee.api(params, "text", function(data) {
if (!data) loadingBar.show("error");
});
},
share: function(service) {
var link = "",
url = location.href;
switch (service) {
case 0:
link = "https://twitter.com/share?url=" + encodeURI(url);
break;
case 1:
link = "http://www.facebook.com/sharer.php?u=" + encodeURI(url) + "&t=" + encodeURI(album.json.title);
break;
case 2:
link = "mailto:?subject=" + encodeURI(album.json.title) + "&body=" + encodeURI("Hi! Check this out: " + url);
break;
default:
link = "";
break;
}
if (link.length>5) location.href = link;
},
getArchive: function(albumID) {
var link;
if (location.href.indexOf("index.html")>0) link = location.href.replace(location.hash, "").replace("index.html", "php/api.php?function=getAlbumArchive&albumID=" + albumID);
else link = location.href.replace(location.hash, "") + "php/api.php?function=getAlbumArchive&albumID=" + albumID;
location.href = link;
}
}

353
js/modules/albums.js Executable file → Normal file
View File

@ -10,75 +10,67 @@
albums = {
json: null,
load: function() {
lychee.animate(".album, .photo", "contentZoomOut");
var startTime,
durationTime,
unsortedAlbum,
starredAlbum,
publicAlbum,
smartData = "",
albumsData = "";
/* Search */
lychee.content.attr("data-search", "");
lychee.animate(".album, .photo", "contentZoomOut");
lychee.animate(".divider", "fadeOut");
startTime = new Date().getTime();
lychee.api("getAlbums", "json", function(data) {
/* Smart Albums */
data.unsortedAlbum = {
id: 0,
title: "Unsorted",
sysdate: data.unsortedNum + " photos",
unsorted: 1,
thumb0: data.unsortedThumb0,
thumb1: data.unsortedThumb1,
thumb2: data.unsortedThumb2
}
data.starredAlbum = {
id: "f",
title: "Starred",
sysdate: data.starredNum + " photos",
star: 1,
thumb0: data.starredThumb0,
thumb1: data.starredThumb1,
thumb2: data.starredThumb2
}
data.publicAlbum = {
id: "s",
title: "Public",
sysdate: data.publicNum + " photos",
public: 1,
thumb0: data.publicThumb0,
thumb1: data.publicThumb1,
thumb2: data.publicThumb2
}
albums.json = data;
durationTime = (new Date().getTime() - startTime);
if (durationTime>300) waitTime = 0; else waitTime = 300 - durationTime;
if (!visible.albums()&&!visible.photo()&&!visible.album()) waitTime = 0;
$.timer(waitTime,function(){
$("#tools_album, #tools_photo").hide();
$("#tools_albums").show();
/* Smart Albums */
unsortedAlbum = new Object();
unsortedAlbum.id = 0;
unsortedAlbum.title = "Unsorted";
unsortedAlbum.sysdate = data.unsortNum + " photos";
unsortedAlbum.unsorted = 1;
if (data.unsortThumb0) unsortedAlbum.thumb0 = lychee.upload_path + data.unsortThumb0; else unsortedAlbum.thumb0 = "";
if (data.unsortThumb1) unsortedAlbum.thumb1 = lychee.upload_path + data.unsortThumb1; else unsortedAlbum.thumb1 = "";
if (data.unsortThumb2) unsortedAlbum.thumb2 = lychee.upload_path + data.unsortThumb2; else unsortedAlbum.thumb2 = "";
starredAlbum = new Object();
starredAlbum.id = "f";
starredAlbum.title = "Starred";
starredAlbum.sysdate = data.starredNum + " photos";
starredAlbum.star = 1;
if (data.starredThumb0) starredAlbum.thumb0 = lychee.upload_path + data.starredThumb0; else starredAlbum.thumb0 = "";
if (data.starredThumb1) starredAlbum.thumb1 = lychee.upload_path + data.starredThumb1; else starredAlbum.thumb1 = "";
if (data.starredThumb2) starredAlbum.thumb2 = lychee.upload_path + data.starredThumb2; else starredAlbum.thumb2 = "";
publicAlbum = new Object();
publicAlbum.id = "s";
publicAlbum.title = "Public";
publicAlbum.sysdate = data.publicNum + " photos";
publicAlbum.public = 1;
if (data.publicThumb0) publicAlbum.thumb0 = lychee.upload_path + data.publicThumb0; else publicAlbum.thumb0 = "";
if (data.publicThumb1) publicAlbum.thumb1 = lychee.upload_path + data.publicThumb1; else publicAlbum.thumb1 = "";
if (data.publicThumb2) publicAlbum.thumb2 = lychee.upload_path + data.publicThumb2; else publicAlbum.thumb2 = "";
if (lychee.publicMode) smartData = "";
else smartData = build.divider("Smart Albums") + build.album(unsortedAlbum) + build.album(starredAlbum) + build.album(publicAlbum);
/* Albums */
if (data.albums) {
albumsData = build.divider("Albums");
$.each(data.album, function() { albumsData += build.album(this); });
} else albumsData = "";
if (smartData==""&&albumsData=="") $("body").append(build.no_content("picture"));
else {
lychee.content.html(smartData + albumsData);
lychee.animate(".album, .photo", "contentZoomIn");
}
document.title = "Lychee";
lychee.headerTitle.html("Albums").removeClass("editable");
$("img").retina();
view.header.mode("albums");
view.albums.init();
lychee.animate(".album, .photo", "contentZoomIn");
});
@ -86,253 +78,18 @@ albums = {
},
loadInfo: function(albumID, password) {
if (albumID=="f"||albumID=="s"||albumID==0) {
lychee.headerTitle.removeClass("editable");
$("#button_edit_album, #button_trash_album, #button_share_album").hide();
lychee.api("getSmartInfo", "json", function(data) {
switch (albumID) {
case "f":
document.title = "Lychee - Starred";
lychee.headerTitle.html("Starred<span> - " + data.starredNum + " photos</span>");
break;
case "s":
document.title = "Lychee - Public";
lychee.headerTitle.html("Public<span> - " + data.publicNum + " photos</span>");
break;
case "0":
document.title = "Lychee - Unsorted";
lychee.headerTitle.html("Unsorted<span> - " + data.unsortNum + " photos</span>");
$("#button_trash_album").show();
break;
}
});
parse: function(album) {
if (album.password&&lychee.publicMode) {
album.thumb0 = "img/password.png";
album.thumb1 = "img/password.png";
album.thumb2 = "img/password.png";
} else {
/*if (lychee.publicMode&&password==undefined) {
password = localStorage.getItem("album" + albumID);
if (password==null) {
if (lychee.publicMode) password = prompt("Please enter a password for this album:", ""); else password = "";
if (password!="") password = hex_md5(password);
localStorage.setItem("album" + albumID, password);
}
}*/
password = "";
$("#button_edit_album, #button_trash_album, #button_share_album, .button_divider").show();
params = "getAlbumInfo&albumID=" + albumID + "&password=" + password;
lychee.api(params, "json", function(data) {
if (!data.title) data.title = "Untitled";
document.title = "Lychee - " + data.title;
lychee.headerTitle.html(data.title + "<span> - " + data.num + " photos</span>").addClass("editable");
if (data.public=="1") {
$("#button_share_album a").addClass("active");
$("#button_share_album").attr("title", "Share Album");
} else {
$("#button_share_album a").removeClass("active");
$("#button_share_album").attr("title", "Make Public");
}
});
if (album.thumb0) album.thumb0 = lychee.upload_path_thumb + album.thumb0; else album.thumb0 = "img/no_images.png";
if (album.thumb1) album.thumb1 = lychee.upload_path_thumb + album.thumb1; else album.thumb1 = "img/no_images.png";
if (album.thumb2) album.thumb2 = lychee.upload_path_thumb + album.thumb2; else album.thumb2 = "img/no_images.png";
}
},
add: function() {
title = prompt("Please enter a title for this album:", "Untitled");
lychee.closeModal();
if (title.length>0&&title.length<31) {
params = "addAlbum&title=" + escape(title);
lychee.api(params, "text", function(data) {
if (data) lychee.goto("a" + data);
else loadingBar.show("error");
});
} else if (title.length>0) loadingBar.show("error", "Error", "Title to short or too long. Please try another one!");
},
hide: function(albumID) {
$(".album[data-id='" + albumID + "']").css("opacity", 0).animate({
width: 0,
marginLeft: 0
}, 300, function() {
$(this).remove();
});
},
delete: function(albumID, delAll) {
params = "deleteAlbum&albumID=" + albumID + "&delAll=" + delAll;
lychee.api(params, "text", function(data) {
if (data) {
if (visible.albums()) albums.hide(albumID);
else lychee.goto("");
} else loadingBar.show("error");
});
},
deleteDialog: function(albumID) {
if (albumID==0) {
f1 = "albums.delete(0, true);";
f2 = "";
modal = build.modal("Clear Unsorted", "Are you sure you want to delete all photos from 'Unsorted'?<br>This action can't be undone!", ["Clear Unsorted", "Keep Photos"], [f1, f2]);
$("body").append(modal);
} else {
if (visible.albums()) albumTitle = $(".album[data-id='" + albumID + "'] .overlay h1").html();
else albumTitle = lychee.title();
f1 = "albums.delete(" + albumID + ", true);";
f2 = "albums.delete(" + albumID + ", false);";
modal = build.modal("Delete Album", "Are you sure you want to delete the album '" + albumTitle + "' and all of the photos it contains? This action can't be undone!", ["Delete Album and Photos", "Keep Photos"], [f1, f2]);
$("body").append(modal);
}
},
setTitle: function(albumID) {
if (!albumID) oldTitle = lychee.title(); else oldTitle = "";
if (!albumID) albumID = lychee.content.attr("data-id");
newTitle = prompt("Please enter a new title for this album:", oldTitle);
if (albumID!=""&&albumID!=null&&albumID&&newTitle.length>0&&newTitle.length<31) {
params = "setAlbumTitle&albumID=" + albumID + "&title=" + encodeURI(newTitle);
lychee.api(params, "text", function(data) {
if (data) {
if (visible.albums()) $(".album[data-id='" + albumID + "'] .overlay h1").html(newTitle);
else {
lychee.headerTitle.html(newTitle + "<span>" + $("#title span").html() + "</span>");
document.title = "Lychee - " + newTitle;
}
} else loadingBar.show("error");
});
} else if (newTitle.length>0) loadingBar.show("error", "Error", "New title to short or too long. Please try another one!");
},
setPublic: function(e) {
albumID = lychee.content.attr("data-id");
params = "setAlbumPublic&albumID=" + albumID;
lychee.api(params, "text", function(data) {
if (data) {
if ($("#button_share_album a.active").length) {
$("#button_share_album a").removeClass("active");
$("#button_share_album").attr("title", "Make Public");
} else {
$("#button_share_album a").addClass("active");
$("#button_share_album").attr("title", "Share Album");
contextMenu.share_album(albumID, e.pageX, e.pageY);
}
} else loadingBar.show("error");
});
},
setPassword: function(albumID, password) {
if (!albumID) albumID = lychee.content.attr("data-id");
if (!password) password = prompt("Please enter a password for this album:", "");
if (password!="") password = hex_md5(password);
params = "setAlbumPassword&albumID=" + albumID + "&password=" + password;
lychee.api(params, "text", function(data) {
if (!data) loadingBar.show("error");
});
},
/*checkAlbumPassword: function(albumID, password) {
params = "checkAlbumPassword&albumID=" + albumID + "&password=" + hex_md5(password);
lychee.api(params, "text", function(data) {
if (data) {
if (password!="") password = hex_md5(password);
localStorage.setItem("album" + albumID, password);
return true;
} else return false;
});
},*/
share: function(service, albumID) {
link = "";
url = location.href;
switch (service) {
case 0:
link = "https://twitter.com/share?url=" + encodeURI(url);
break;
case 1:
link = "http://www.facebook.com/sharer.php?u=" + encodeURI(url) + "&t=" + encodeURI(lychee.title());
break;
case 2:
link = "mailto:?subject=" + encodeURI(lychee.title()) + "&body=" + encodeURI("Hi! Check this out: " + url);
break;
case 3:
modal = build.modal("Copy Link", "Everyone can view your public albums, but only you can edit them. Use this link to share your album with others: <input class='copylink' value='" + url + "'>", ["Close"], [""]);
$("body").append(modal);
$(".copylink").focus();
break;
default:
link = "";
break;
}
if (link.length>5) location.href = link;
},
getArchive: function() {
albumID = lychee.content.attr("data-id");
if (location.href.indexOf("index.html")>0) link = location.href.replace(location.hash, "").replace("index.html", "php/api.php?function=getAlbumArchive&albumID=" + albumID);
else link = location.href.replace(location.hash, "") + "php/api.php?function=getAlbumArchive&albumID=" + albumID;
location.href = link;
}
}

View File

@ -18,38 +18,28 @@ build = {
album: function(albumJSON) {
var album = "";
if (!albumJSON) return "";
if(!albumJSON) return "";
var album = ""
title = albumJSON.title;
if (albumJSON.password&&lychee.publicMode) {
albumJSON.thumb0 = "img/password.png";
albumJSON.thumb1 = "img/password.png";
albumJSON.thumb2 = "img/password.png";
} else {
if(!albumJSON.thumb0) albumJSON.thumb0 = "img/no_images.png";
if(!albumJSON.thumb1) albumJSON.thumb1 = "img/no_images.png";
if(!albumJSON.thumb2) albumJSON.thumb2 = "img/no_images.png";
}
if(!albumJSON.title) albumJSON.title = "Untitled";
if(albumJSON.title.length>18) albumJSON.title = albumJSON.title.substr(0, 18) + "...";
if (title.length>18) title = albumJSON.title.substr(0, 18) + "...";
album += "<div class='album' data-id='" + albumJSON.id + "' data-password='" + albumJSON.password + "'>";
album += "<img src='" + lychee.upload_path + albumJSON.thumb2 + "' width='200' height='200' alt='thumb'>";
album += "<img src='" + lychee.upload_path + albumJSON.thumb1 + "' width='200' height='200' alt='thumb'>";
album += "<img src='" + lychee.upload_path + albumJSON.thumb0 + "' width='200' height='200' alt='thumb'>";
album += "<img src='" + albumJSON.thumb2 + "' width='200' height='200' alt='thumb'>";
album += "<img src='" + albumJSON.thumb1 + "' width='200' height='200' alt='thumb'>";
album += "<img src='" + albumJSON.thumb0 + "' width='200' height='200' alt='thumb'>";
album += "<div class='overlay'>";
if (albumJSON.password&&!lychee.publicMode) album += "<h1><span class='icon-lock' title='Public album with password'></span> " + albumJSON.title + "</h1>";
else album += "<h1>" + albumJSON.title + "</h1>";
if (albumJSON.password&&!lychee.publicMode) album += "<h1><span class='icon-lock'></span> " + title + "</h1>";
else album += "<h1>" + title + "</h1>";
album += "<a>" + albumJSON.sysdate + "</a>";
album += "</div>";
if(!lychee.publicMode&&albumJSON.star=="1") album += "<a class='badge red icon-star'></a>";
if(!lychee.publicMode&&albumJSON.public=="1") album += "<a class='badge red icon-share'></a>";
if(!lychee.publicMode&&albumJSON.unsorted=="1") album += "<a class='badge red icon-reorder'></a>";
if(!lychee.publicMode&&albumJSON.star==1) album += "<a class='badge red icon-star'></a>";
if(!lychee.publicMode&&albumJSON.public==1) album += "<a class='badge red icon-share'></a>";
if(!lychee.publicMode&&albumJSON.unsorted==1) album += "<a class='badge red icon-reorder'></a>";
album += "</div>";
@ -59,22 +49,22 @@ build = {
photo: function(photoJSON) {
var photo = "";
if (!photoJSON) return "";
if(photoJSON=="") return "";
if(!photoJSON.title) photoJSON.title = "";
if(!photoJSON.thumbUrl) photoJSON.thumbUrl = "img/no_image.png";
if(photoJSON.title.length>18) photoJSON.title = photoJSON.title.substr(0, 18) + "...";
var photo = "",
title = photoJSON.title;
if (title.length>18) title = photoJSON.title.substr(0, 18) + "...";
photo += "<div class='photo' data-album-id='" + photoJSON.album + "' data-id='" + photoJSON.id + "'>";
photo += "<img src='" + lychee.upload_path + photoJSON.thumbUrl + "' width='200' height='200' alt='thumb'>";
photo += "<img src='" + photoJSON.thumbUrl + "' width='200' height='200' alt='thumb'>";
photo += "<div class='overlay'>";
photo += "<h1>" + photoJSON.title + "</h1>";
photo += "<h1>" + title + "</h1>";
photo += "<a>" + photoJSON.sysdate + "</a>";
photo += "</div>";
if(photoJSON.star=="1") photo += "<a class='badge red icon-star'></a>";
if(!lychee.publicMode&&photoJSON.public=="1") photo += "<a class='badge red icon-share'></a>";
if (photoJSON.star==1) photo += "<a class='badge red icon-star'></a>";
if (!lychee.publicMode&&photoJSON.public==1&&album.json.public!=1) photo += "<a class='badge red icon-share'></a>";
photo += "</div>";
@ -98,7 +88,7 @@ build = {
},
modal: function(title, text, button, func) {
modal: function(title, text, button) {
var modal = "";
@ -110,28 +100,16 @@ build = {
$.each(button, function(index) {
if (index==0) modal += "<a onclick='message_click(" + index + ")' class='button active'>" + this + "</a>";
else modal += "<a onclick='message_click(" + index + ")' class='button'>" + this + "</a>";
if (this[0]!="") {
if (index==0) modal += "<a class='button active'>" + this[0] + "</a>";
else modal += "<a class='button'>" + this[0] + "</a>";
}
});
modal += "</div>";
modal += "<script>";
modal += "function message_click(action) {";
modal += "switch (action) {";
$.each(func, function(index) {
modal += "case " + index + ":";
modal += this.toString();
modal += "break;";
});
modal += "} lychee.closeModal(); }";
modal += "</script>";
modal += "</div>";
return modal;
@ -141,6 +119,7 @@ build = {
addModal: function() {
var modal = "";
modal += "<div class='message_overlay fadeIn'>";
modal += "<div class='message center add'>";
modal += "<h1>Add Album or Photo</h1>";
@ -167,6 +146,7 @@ build = {
signInModal: function() {
var modal = "";
modal += "<div class='message_overlay'>";
modal += "<div class='message center'>";
modal += "<h1><a class='icon-lock'></a> Sign In</h1>";
@ -186,6 +166,7 @@ build = {
uploadModal: function() {
var modal = "";
modal += "<div class='upload_overlay fadeIn'>";
modal += "<div class='upload_message center'>";
modal += "<a class='icon-upload'></a>";
@ -200,6 +181,7 @@ build = {
contextMenu: function(items) {
var menu = "";
menu += "<div class='contextmenu_bg'></div>";
menu += "<div class='contextmenu'>";
menu += "<table>";
@ -207,8 +189,10 @@ build = {
$.each(items, function(index) {
if (items[index][0]=="separator"&&items[index][1].length==0) menu += "<tr class='separator'></tr>";
else if (items[index][1].length!=0) menu += "<tr><td onclick='" + items[index][1] + "; contextMenu.close();'>" + items[index][0] + "</td></tr>";
if (items[index][0]=="separator"&&items[index][1]==-1) menu += "<tr class='separator'></tr>";
else if (items[index][1]==-1) menu += "<tr class='no_hover'><td>" + items[index][0] + "</td></tr>";
else if (items[index][2]!=undefined) menu += "<tr><td onclick='" + items[index][2] + "; window.contextMenu.close();'>" + items[index][0] + "</td></tr>";
else menu += "<tr><td onclick='window.contextMenu.fns[" + items[index][1] + "](); window.contextMenu.close();'>" + items[index][0] + "</td></tr>";
});
@ -220,36 +204,56 @@ build = {
},
infobox: function(photo, forView) {
infobox: function(photoJSON, forView) {
if (!photoJSON) return "";
var infobox = "",
public,
editTitleHTML,
editDescriptionHTML,
infos;
var infobox = "";
infobox += "<div class='header'><h1>About</h1><a class='icon-remove-sign'></a></div>";
infobox += "<div class='wrapper'>";
if (photo.public==1) photo.public = "Public"; else photo.public = "Private";
if (forView==true||lychee.publicMode) editTitleHTML = ""; else editTitleHTML = " <div id='edit_title'><a class='icon-pencil'></a></div>";
if (forView==true||lychee.publicMode) editDescriptionHTML = ""; else editDescriptionHTML = " <div id='edit_description'><a class='icon-pencil'></a></div>";
switch (photoJSON.public) {
case "0":
public = "Private";
break;
case "1":
public = "Public";
break;
case "2":
public = "Public (Album)";
break;
default:
public = "-";
break;
}
editTitleHTML = (forView==true||lychee.publicMode) ? "" : " <div id='edit_title'><a class='icon-pencil'></a></div>";
editDescriptionHTML = (forView==true||lychee.publicMode) ? "" : " <div id='edit_description'><a class='icon-pencil'></a></div>";
infos = [
["", "Basics"],
["Name", photo.title + editTitleHTML],
["Uploaded", photo.sysdate],
["Description", photo.description + editDescriptionHTML],
["Name", photoJSON.title + editTitleHTML],
["Uploaded", photoJSON.sysdate],
["Description", photoJSON.description + editDescriptionHTML],
["", "Image"],
["Size", photo.size],
["Format", photo.type],
["Resolution", photo.width + " x " + photo.height],
["Size", photoJSON.size],
["Format", photoJSON.type],
["Resolution", photoJSON.width + " x " + photoJSON.height],
["", "Camera"],
["Captured", photo.takedate],
["Make", photo.make],
["Type/Model", photo.model],
["Shutter Speed", photo.shutter],
["Aperture", photo.aperture],
["Focal Length", photo.focal],
["ISO", photo.iso],
["Captured", photoJSON.takedate],
["Make", photoJSON.make],
["Type/Model", photoJSON.model],
["Shutter Speed", photoJSON.shutter],
["Aperture", photoJSON.aperture],
["Focal Length", photoJSON.focal],
["ISO", photoJSON.iso],
["", "Share"],
["Visibility", photo.public],
["Short Link", photo.shortlink]
["Visibility", public]
];
$.each(infos, function(index) {

196
js/modules/contextMenu.js Executable file → Normal file
View File

@ -10,26 +10,35 @@
contextMenu = {
fns: null,
album: function(e) {
e.preventDefault();
mouse_x = e.pageX;
mouse_y = e.pageY;
albumID = $(this).attr("data-id");
var mouse_x = e.pageX,
mouse_y = e.pageY,
albumID = album.getID(),
items;
if (albumID=="0"||albumID=="f"||albumID=="s") return false;
mouse_y -= $(document).scrollTop();
contextMenu.fns = [
function() { album.setTitle(albumID) },
function() { album.delete(albumID) }
];
items = [
["Rename", "albums.setTitle(" + albumID + ")"],
["Delete", "albums.deleteDialog(" + albumID + ")"]
["<a class='icon-edit'></a> Rename", 0],
["<a class='icon-trash'></a> Delete", 1]
];
contextMenu.close();
$("body").css("overflow", "hidden");
$(".album[data-id='" + albumID + "']").addClass("active");
$("body").append(build.contextMenu(items));
$("body")
.css("overflow", "hidden")
.append(build.contextMenu(items));
$(".contextmenu").css({
"top": mouse_y,
"left": mouse_x
@ -40,22 +49,33 @@ contextMenu = {
photo: function(e) {
e.preventDefault();
mouse_x = e.pageX;
mouse_y = e.pageY;
photoID = $(this).attr("data-id");
var mouse_x = e.pageX,
mouse_y = e.pageY,
photoID = photo.getID(),
items;
mouse_y -= $(document).scrollTop();
contextMenu.fns = [
function() { photo.setStar(photoID) },
function() { photo.setTitle(photoID) },
function() { contextMenu.move(photoID, e) },
function() { photo.delete(photoID) }
];
items = [
["Rename", "photos.setTitle(" + photoID + ")"],
["Move to Album", "contextMenu.move(" + photoID + ", " + (mouse_x+150) + ", " + (mouse_y+$(document).scrollTop()) + ")"],
["Delete", "photos.deleteDialog(" + photoID + ")"]
["<a class='icon-star'></a> Star", 0],
["separator", -1],
["<a class='icon-edit'></a> Rename", 1],
["<a class='icon-folder-open'></a> Move", 2],
["<a class='icon-trash'></a> Delete", 3]
];
contextMenu.close();
$("body").css("overflow", "hidden");
$(".photo[data-id='" + photoID + "']").addClass("active");
$("body").append(build.contextMenu(items));
$("body")
.css("overflow", "hidden")
.append(build.contextMenu(items));
$(".contextmenu").css({
"top": mouse_y,
"left": mouse_x
@ -63,8 +83,14 @@ contextMenu = {
},
move: function(photoID, mouse_x, mouse_y) {
move: function(photoID, e) {
var mouse_x = e.pageX,
mouse_y = e.pageY,
items = [],
albumID;
contextMenu.fns = [];
mouse_y -= $(document).scrollTop();
if (!mouse_x||!mouse_y) {
@ -72,35 +98,29 @@ contextMenu = {
mouse_y = "10px";
}
if (album.getID()!=0) {
items = [
["Unsorted", 0, "photo.setAlbum(0, " + photoID + ")"],
["separator", -1]
];
}
lychee.api("getAlbums", "json", function(data) {
if (lychee.content.attr("data-id")==0) {
items = [];
} else {
items = [
["Unsorted", "photos.setAlbum(" + photoID + ", 0)"]
];
}
if (!data.albums) {
items = [
["New Album", "albums.add()"]
];
items = [["New Album", 0, "album.add()"]];
} else {
$.each(data.album, function(index) {
if (this.id!=lychee.content.attr("data-id")) {
if(!this.title) this.title = "Untitled";
items[items.length] = new Array(this.title, "photos.setAlbum(" + photoID + ", " + this.id + ")");
} else {
items[items.length] = new Array("", "");
}
$.each(data.content, function(index) {
if (this.id!=album.getID()) items.push([this.title, 0, "photo.setAlbum(" + this.id + ", " + photoID + ")"]);
});
}
contextMenu.close();
$("body").css("overflow", "hidden");
$(".photo[data-id='" + photoID + "']").addClass("active");
$("body").append(build.contextMenu(items));
$("body")
.css("overflow", "hidden")
.append(build.contextMenu(items));
if (!visible.photo()) mouse_x += $(".contextmenu").width();
$(".contextmenu").css({
"top": mouse_y,
"left": mouse_x-$(".contextmenu").width()
@ -110,7 +130,11 @@ contextMenu = {
},
share: function(photoID, mouse_x, mouse_y) {
sharePhoto: function(photoID, e) {
var mouse_x = e.pageX,
mouse_y = e.pageY,
items;
mouse_y -= $(document).scrollTop();
@ -119,30 +143,57 @@ contextMenu = {
mouse_y = "10px";
}
items = [
["<a class='icon-eye-close'></a> Make Private", "photos.setPublic()"],
["separator", ""],
["<a class='icon-twitter'></a> Twitter", "photos.share(0, " + photoID + ")"],
["<a class='icon-facebook'></a> Facebook", "photos.share(1, " + photoID + ")"],
["<a class='icon-envelope'></a> Mail", "photos.share(2, " + photoID + ")"],
["<a class='icon-link'></a> Copy Link", "photos.share(3, " + photoID + ")"]
contextMenu.fns = [
function() { photo.setPublic(photoID) },
function() { photo.share(photoID, 0) },
function() { photo.share(photoID, 1) },
function() { photo.share(photoID, 2) },
function() { photo.share(photoID, 3) }
];
if (lychee.bitlyUsername!="") items.push(["<a class='icon-link'></a> Copy Shortlink", "photos.share(4, " + photoID + ")"]);
if (document.location.hostname!="localhost") {
items = [
["<input readonly id='link' value='" + photo.getViewLink(photoID) + "'>", -1],
["separator", -1],
["<a class='icon-eye-close'></a> Make Private", 0],
["separator", -1],
["<a class='icon-twitter'></a> Twitter", 1],
["<a class='icon-facebook'></a> Facebook", 2],
["<a class='icon-envelope'></a> Mail", 3],
["<a class='icon-hdd'></a> Dropbox", 4]
];
} else {
items = [
["<input readonly id='link' value='" + photo.getViewLink(photoID) + "'>", -1],
["separator", -1],
["<a class='icon-eye-close'></a> Make Private", 0],
["separator", -1],
["<a class='icon-envelope'></a> Mail", 3]
];
}
contextMenu.close();
$("body")
.css("overflow", "hidden")
.append(build.contextMenu(items));
$(".photo[data-id='" + photoID + "']").addClass("active");
$(".contextmenu").css({
"top": mouse_y,
"left": mouse_x
"left": mouse_x+20-$(".contextmenu").width()
});
$(".contextmenu input").focus();
},
share_album: function(albumID, mouse_x, mouse_y) {
shareAlbum: function(albumID, e) {
var mouse_x = e.pageX,
mouse_y = e.pageY,
items;
mouse_y -= $(document).scrollTop();
@ -151,29 +202,60 @@ contextMenu = {
mouse_y = "10px";
}
items = [
["<a class='icon-eye-close'></a> Make Private", "albums.setPublic()"],
//["<a class='icon-key'></a> Set Password", "albums.setPassword()"],
["separator", ""],
["<a class='icon-twitter'></a> Twitter", "albums.share(0, " + albumID + ")"],
["<a class='icon-facebook'></a> Facebook", "albums.share(1, " + albumID + ")"],
["<a class='icon-envelope'></a> Mail", "albums.share(2, " + albumID + ")"],
["<a class='icon-link'></a> Copy Link", "albums.share(3, " + albumID + ")"]
contextMenu.fns = [
function() { album.setPublic(albumID) },
function() { password.set(albumID) },
function() { album.share(0) },
function() { album.share(1) },
function() { album.share(2) },
function() { password.remove(albumID) }
];
if (document.location.hostname!="localhost") {
items = [
["<input readonly id='link' value='" + location.href + "'>", -1],
["separator", -1],
["<a class='icon-eye-close'></a> Make Private", 0],
["<a class='icon-lock'></a> Set Password", 1],
["separator", -1],
["<a class='icon-twitter'></a> Twitter", 2],
["<a class='icon-facebook'></a> Facebook", 3],
["<a class='icon-envelope'></a> Mail", 4],
];
} else {
items = [
["<input readonly id='link' value='" + location.href + "'>", -1],
["separator", -1],
["<a class='icon-eye-close'></a> Make Private", 0],
["<a class='icon-lock'></a> Set Password", 1],
["separator", -1],
["<a class='icon-envelope'></a> Mail", 4],
];
}
if (album.json.password==true) items[3] = ["<a class='icon-unlock'></a> Remove Password", 5];
contextMenu.close();
$("body")
.css("overflow", "hidden")
.append(build.contextMenu(items));
$(".contextmenu").css({
"top": mouse_y,
"left": mouse_x
"left": mouse_x+20-$(".contextmenu").width()
});
$(".contextmenu input").focus();
},
close: function() {
contextMenu.js = null;
$(".contextmenu_bg, .contextmenu").remove();
$(".photo.active, .album.active").removeClass("active");
$("body").css("overflow", "scroll");

View File

@ -14,9 +14,7 @@ loadingBar = {
show: function(status, errorTitle, errorText) {
clearTimeout(lychee.loadingBar.data("timeout"));
if (status=="error"&&loadingBar.status!="error") {
if (status=="error") {
loadingBar.status = "error";
@ -31,13 +29,15 @@ loadingBar = {
.css("height", "40px");
if (visible.controls()) lychee.header.css("margin-Top", "40px");
lychee.loadingBar.data("timeout", setTimeout(function () { loadingBar.hide(true) }, 3000));
clearTimeout(lychee.loadingBar.data("timeout"));
lychee.loadingBar.data("timeout", setTimeout(function() { loadingBar.hide(true) }, 3000));
} else if (loadingBar.status==null) {
loadingBar.status = "loading";
lychee.loadingBar.data("timeout", setTimeout(function () {
clearTimeout(lychee.loadingBar.data("timeout"));
lychee.loadingBar.data("timeout", setTimeout(function() {
lychee.loadingBar
.show()
.removeClass("loading uploading error")

379
js/modules/lychee.js Executable file → Normal file
View File

@ -8,62 +8,44 @@
* This module provides the basic functions of Lychee.
*/
lychee = {
var lychee = {
init: function(api_path, upload_path) {
init: function() {
this.version = "1.2";
this.api_path = api_path;
this.upload_path = upload_path;
this.version = "1.3";
this.api_path = "php/api.php";
this.update_path = "http://lychee.electerious.com/version/index.php";
this.updateURL = "https://github.com/electerious/Lychee";
this.upload_path_thumb = "uploads/thumb/";
this.upload_path_big = "uploads/big/";
this.publicMode = false;
this.viewMode = false;
this.checkForUpdates = false;
this.bitlyUsername = "";
this.dropbox = false;
this.loadingBar = $("#loading");
this.header = $("header");
this.headerTitle = $("#title");
this.content = $("#content");
this.image_view = $("#image_view");
this.imageview = $("#imageview");
this.infobox = $("#infobox");
},
ready: function() {
if (!mobileBrowser()) $(".tools").tipsy({gravity: 'n'});
if (window.webkitNotifications) window.webkitNotifications.requestPermission();
run: function() {
lychee.api("init", "json", function(data) {
lychee.checkForUpdates = data.config.checkForUpdates;
lychee.bitlyUsername = data.config.bitlyUsername;
if (!data.loggedIn) lychee.setPublicMode();
if (!data.loggedIn) lychee.setMode("public");
$(window).bind("popstate", lychee.load);
lychee.load();
});
},
setPublicMode: function() {
this.publicMode = true;
$("#button_signout, #search, #button_trash_album, #button_share_album, #button_edit_album, .button_add, #button_archive, .button_divider").remove();
$("#button_trash, #button_move, #button_edit, #button_share, #button_star").remove();
$(document)
.on("mouseenter", "#title.editable", function() { $(this).removeClass("editable") })
.off(event_name, "#title.editable")
.off("contextmenu", ".photo")
.off("contextmenu", ".album")
.off("drop");
$("#button_signin").show();
},
api: function(params, type, callback, loading) {
if (loading==undefined) loadingBar.show();
@ -83,24 +65,11 @@ lychee = {
},
showLogin: function() {
$("body").append(build.signInModal());
$("#username").focus();
if (localStorage) {
local_username = localStorage.getItem("username");
if (local_username==null) return false;
if (local_username.length>0) $("#username").val(local_username);
$("#password").focus();
}
if (lychee.checkForUpdates) lychee.update();
},
login: function() {
user = $("input#username").val();
password = hex_md5($("input#password").val());
var user = $("input#username").val(),
password = hex_md5($("input#password").val()),
params;
params = "login&user=" + user + "&password=" + password;
lychee.api(params, "text", function(data) {
@ -115,6 +84,21 @@ lychee = {
},
loginDialog: function() {
$("body").append(build.signInModal());
$("#username").focus();
if (localStorage) {
local_username = localStorage.getItem("username");
if (local_username!=null) {
if (local_username.length>0) $("#username").val(local_username);
$("#password").focus();
}
}
if (lychee.checkForUpdates) lychee.getUpdate();
},
logout: function() {
lychee.api("logout", "text", function(data) {
@ -123,7 +107,66 @@ lychee = {
},
update: function() {
goto: function(url) {
if (url==undefined) url = "";
document.location.hash = url;
},
load: function() {
var albumID = "",
photoID = "",
hash = document.location.hash.replace("#", "");
contextMenu.close();
if (hash.indexOf("a")!=-1) albumID = hash.split("p")[0].replace("a", "");
if (hash.indexOf("p")!=-1) photoID = hash.split("p")[1];
if (albumID&&photoID) {
// Trash data
albums.json = null;
photo.json = null;
// Show Photo
if (lychee.content.html()==""||($("#search").length&&$("#search").val().length!=0)) {
lychee.content.hide();
album.load(albumID, true);
}
if (!visible.photo()) view.photo.show();
photo.load(photoID, albumID);
} else if (albumID) {
// Trash data
albums.json = null;
photo.json = null;
// Show Album
if (visible.photo()) view.photo.hide();
if (album.json&&albumID==album.json.id) view.album.title();
else album.load(albumID);
} else {
// Trash data
albums.json = null;
album.json = null;
photo.json = null;
search.code = "";
// Show Albums
if (visible.photo()) view.photo.hide();
albums.load();
}
},
getUpdate: function() {
$.ajax({
url: lychee.update_path,
@ -132,212 +175,65 @@ lychee = {
},
upload: function(files) {
setTitle: function(title, count, editable) {
pre_progress = 0;
if (title=="Albums") document.title = "Lychee";
else document.title = "Lychee - " + title;
$(".upload_overlay").remove();
$("body").append(build.uploadModal());
if (count) title += "<span> - " + count + " photos</span>";
if (editable) $("#title").addClass("editable");
else $("#title").removeClass("editable");
var formData = new FormData();
for (var i = 0; i < files.length; i++) formData.append(i, files[i]);
formData.append("function", "upload");
if (lychee.content.attr("data-id")=="") formData.append("albumID", 0);
else formData.append("albumID", lychee.content.attr("data-id"));
var xhr = new XMLHttpRequest();
xhr.open('POST', lychee.api_path);
xhr.onload = function () {
if (xhr.status===200) {
$(".progressbar div").css("width", "100%");
$(".upload_overlay").removeClass("fadeIn").css("opacity", 0);
$.timer(300,function(){ $(".upload_overlay").remove() });
if (window.webkitNotifications&&BrowserDetect.browser=="Safari") {
var popup = window.webkitNotifications.createNotification("", "Upload complete", "You can now manage your new photos.");
popup.show();
}
if (lychee.content.attr("data-id")=="") lychee.goto("a0");
else photos.load(lychee.content.attr("data-id"));
}
};
xhr.upload.onprogress = function (event) {
if (event.lengthComputable) {
var progress = (event.loaded / event.total * 100 | 0);
if (progress>pre_progress) {
$(".progressbar div").css("width", progress + "%");
pre_progress = progress;
}
if (progress>=100) $(".progressbar div").css("opacity", 0.2);
}
};
$("#upload_files").val("");
xhr.send(formData);
$("#title").html(title);
},
importUrl: function() {
setMode: function(mode) {
link = prompt("Please enter the direct link to a photo to import it:", "");
if (lychee.content.attr("data-id")=="") albumID = 0;
else albumID = lychee.content.attr("data-id");
$("#button_signout, #search, #button_trash_album, #button_share_album, #button_edit_album, .button_add, #button_archive, .button_divider").remove();
$("#button_trash, #button_move, #button_edit, #button_share, #button_star").remove();
lychee.closeModal();
$(document)
.on("mouseenter", "#title.editable", function() { $(this).removeClass("editable") })
.off("click", "#title.editable")
.off("touchend", "#title.editable")
.off("contextmenu", ".photo")
.off("contextmenu", ".album")
.off("drop");
if (link.length>3) {
Mousetrap
.unbind('n')
.unbind('u')
.unbind('s')
.unbind('backspace');
params = "importUrl&url=" + escape(link) + "&albumID=" + albumID;
lychee.api(params, "text", function(data) {
if (mode=="public") {
if (data) {
if (lychee.content.attr("data-id")=="") lychee.goto("a0");
else photos.load(lychee.content.attr("data-id"));
} else loadingBar.show("error");
$("#button_signin").show();
lychee.publicMode = true;
});
} else if (mode=="view") {
} else if (link.length>0) loadingBar.show("error", "Error", "Link to short or too long. Please try another one!");
Mousetrap.unbind('esc');
$("#button_back, a#next, a#previous").remove();
},
load: function() {
contextMenu.close();
hash = document.location.hash.replace("#", "");
albumID = "";
photoID = "";
if (hash.indexOf("a")!=-1) albumID = hash.split("p")[0].replace("a", ""); else albumID = "";
if (hash.indexOf("p")!=-1) photoID = hash.split("p")[1]; else photoID = "";
lychee.content.attr("data-id", albumID);
lychee.image_view.attr("data-id", photoID);
if (albumID&&photoID) {
// Show ImageView
if (lychee.content.html()==""||($("#search").length&&$("#search").val().length!=0)) {
lychee.content.hide();
photos.load(albumID, true);
}
photos.loadInfo(photoID, albumID);
} else if (albumID) {
// Show Album
if (visible.infobox) photos.hideInfobox();
if (!visible.controls()) lychee.showControls();
if (visible.imageview()) photos.hideView();
else photos.load(albumID, false);
} else {
// Show Albums
if (visible.infobox) photos.hideInfobox();
if (!visible.controls()) lychee.showControls();
if (visible.imageview()) photos.hideView();
albums.load();
lychee.publicMode = true;
lychee.viewMode = true;
}
},
goto: function(url) {
document.location.hash = url;
},
title: function() {
return lychee.headerTitle.html().replace($("#title span").html(), "").replace("<span></span>", "");
},
showControls: function() {
clearTimeout($(window).data("timeout"));
if (visible.imageview()) {
lychee.image_view.removeClass("full");
lychee.loadingBar.css("opacity", 1);
lychee.header.css("margin-Top", "0px");
if ($("#image_view #image.small").length>0) {
$("#image_view #image").css({
marginTop: -1*($("#image_view #image").height()/2)+20
});
} else {
$("#image_view #image").css({
top: 70,
right: 30,
bottom: 30,
left: 30
});
}
}
},
hideControls: function() {
if (visible.imageview()&&!visible.infobox()) {
clearTimeout($(window).data("timeout"));
$(window).data("timeout", setTimeout(function() {
lychee.image_view.addClass("full");
lychee.loadingBar.css("opacity", 0);
lychee.header.css("margin-Top", "-45px");
if ($("#image_view #image.small").length>0) {
$("#image_view #image").css({
marginTop: -1*($("#image_view #image").height()/2)
});
} else {
$("#image_view #image").css({
top: 0,
right: 0,
bottom: 0,
left: 0
});
}
}, 500));
}
},
closeModal: function() {
$(".message_overlay").removeClass("fadeIn").css("opacity", 0);
$.timer(300,function(){ $(".message_overlay").remove() });
},
animate: function(obj, animation) {
animations = [
var animations = [
["fadeIn", "fadeOut"],
["contentZoomIn", "contentZoomOut"]
];
if (!obj.jQuery) obj = $(obj);
for (i = 0; i < animations.length; i++) {
for (var i = 0; i < animations.length; i++) {
for (var x = 0; x < animations[i].length; x++) {
if (animations[i][x]==animation) {
obj.removeClass(animations[i][0] + " " + animations[i][1]).addClass(animation);
@ -350,6 +246,33 @@ lychee = {
},
loadDropbox: function(callback) {
if (!lychee.dropbox) {
loadingBar.show();
var g = document.createElement("script"),
s = document.getElementsByTagName("script")[0];
g.src = "https://www.dropbox.com/static/api/1/dropins.js";
g.id = "dropboxjs";
g.type = "text/javascript";
g.async = "true";
g.setAttribute("data-app-key", "iq7lioj9wu0ieqs");
g.onload = g.onreadystatechange = function() {
var rs = this.readyState;
if (rs&&rs!="complete"&&rs!="loaded") return;
lychee.dropbox = true;
loadingBar.hide();
callback();
};
s.parentNode.insertBefore(g, s);
} else callback();
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(jqXHR);

37
js/modules/modal.js Normal file
View File

@ -0,0 +1,37 @@
/**
* @name modal.js
* @author Philipp Maurer
* @author Tobias Reich
* @copyright 2013 by Philipp Maurer, Tobias Reich
*
* Modal Module
* Build, show and hide a modal.
*/
modal = {
fns: null,
show: function(title, text, buttons) {
if (!buttons) {
var buttons = [];
buttons[0] = ["", function() {}];
buttons[1] = ["", function() {}];
}
modal.fns = [buttons[0][1], buttons[1][1]];
$("body").append(build.modal(title, text, buttons));
$(".message input").focus();
},
close: function() {
modal.fns = null;
$(".message_overlay").removeClass("fadeIn").css("opacity", 0);
$.timer(300,function(){ $(".message_overlay").remove() });
}
}

105
js/modules/password.js Normal file
View File

@ -0,0 +1,105 @@
/**
* @name password.js
* @author Philipp Maurer
* @author Tobias Reich
* @copyright 2013 by Philipp Maurer, Tobias Reich
*
* Password Module
* Controls the access to password-protected albums and photos.
*/
password = {
value: "",
set: function(albumID) {
var buttons,
params;
buttons = [
["Set Password", function() {
if (visible.album()) album.json.password = true;
params = "setAlbumPassword&albumID=" + albumID + "&password=" + hex_md5($("input.password").val());
lychee.api(params, "text", function(data) {
if (!data) loadingBar.show("error");
});
}],
["Cancel", function() {}]
];
modal.show("Set Password", "Set a password to protect '" + album.json.title + "' from unauthorized viewers. Only people with this password can view this album. <input class='password' type='password' placeholder='password' value=''>", buttons);
},
get: function(albumID, callback) {
var passwd = $("input.password").val(),
params;
if (!lychee.publicMode) callback();
else if (album.json&&album.json.password==false) callback();
else if (albums.json&&albums.json.content[albumID].password==false) callback();
else if (!albums.json&&!album.json) {
// Continue without password
album.json = {password: true};
callback("");
} else if (passwd==undefined) {
// Request password
password.getDialog(albumID, callback);
} else {
// Check password
params = "checkAlbumAccess&albumID=" + albumID + "&password=" + hex_md5(passwd);
lychee.api(params, "text", function(data) {
if (data) {
password.value = hex_md5(passwd);
callback();
} else {
lychee.goto("");
loadingBar.show("error", "Error", "Access denied. Wrong password!");
}
});
}
},
getDialog: function(albumID, callback) {
var buttons;
buttons = [
["Enter", function() { password.get(albumID, callback) }],
["Cancel", lychee.goto]
];
modal.show("<a class='icon-lock'></a> Enter Password", "This album is protected with a password. Enter the password below to view the photos of this album: <input class='password' type='password' placeholder='password' value=''>", buttons);
},
remove: function(albumID) {
var params;
if (visible.album()) album.json.password = false;
params = "setAlbumPassword&albumID=" + albumID + "&password=";
lychee.api(params, "text", function(data) {
if (!data) loadingBar.show("error");
});
}
}

403
js/modules/photo.js Normal file
View File

@ -0,0 +1,403 @@
/**
* @name photo.js
* @author Philipp Maurer
* @author Tobias Reich
* @copyright 2013 by Philipp Maurer, Tobias Reich
*
* Photo Module
* Takes care of every action a photo can handle and execute.
*/
photo = {
json: null,
getID: function() {
var id;
if (photo.json) id = photo.json.id;
else id = $(".photo:hover, .photo.active").attr("data-id");
if (id) return id;
else return false;
},
load: function(photoID, albumID) {
var params,
checkPasswd;
params = "getPhoto&photoID=" + photoID + "&albumID=" + albumID + "&password=" + password.value;
lychee.api(params, "json", function(data) {
if (data=="HTTP/1.1 403 Wrong password!") {
checkPasswd = function() {
if (password.value!="") photo.load(photoID, albumID);
else setTimeout(checkPasswd, 250);
}
checkPasswd();
return false;
}
photo.json = data;
view.photo.init();
lychee.imageview.show();
$.timer(300, function() { lychee.content.show(); });
});
},
parse: function() {
if (!photo.json.title) photo.json.title = "Untitled";
photo.json.url = lychee.upload_path_big + photo.json.url;
},
add: {
files: function(files) {
var pre_progress = 0,
formData = new FormData(),
xhr = new XMLHttpRequest(),
popup,
progress;
$(".upload_overlay").remove();
$("body").append(build.uploadModal());
window.onbeforeunload = function() { return "Lychee is currently uploading!"; };
for (var i = 0; i < files.length; i++) formData.append(i, files[i]);
formData.append("function", "upload");
if (album.getID()=="") formData.append("albumID", 0);
else formData.append("albumID", album.getID());
xhr.open('POST', lychee.api_path);
xhr.onload = function() {
if (xhr.status===200) {
$(".progressbar div").css("width", "100%");
$(".upload_overlay").removeClass("fadeIn").css("opacity", 0);
$.timer(300, function() { $(".upload_overlay").remove() });
if (window.webkitNotifications&&BrowserDetect.browser=="Safari") {
popup = window.webkitNotifications.createNotification("", "Upload complete", "You can now manage your new photo.");
popup.show();
}
window.onbeforeunload = null;
if (album.getID()=="") lychee.goto("a0");
else album.load(album.getID());
}
};
xhr.upload.onprogress = function(event) {
if (event.lengthComputable) {
progress = (event.loaded / event.total * 100 | 0);
if (progress>pre_progress) {
$(".progressbar div").css("width", progress + "%");
pre_progress = progress;
}
if (progress>=100) $(".progressbar div").css("opacity", 0.2);
}
};
$("#upload_files").val("");
xhr.send(formData);
},
url: function(link) {
var albumID = album.getID();
if (!link) link = prompt("Please enter the direct link to a photo to import it:", "");
if (album.getID()=="") albumID = 0;
if (link&&link.length>3) {
modal.close();
$(".upload_overlay").remove();
$("body").append(build.uploadModal());
$(".progressbar div").css({
"opacity": 0.2,
"width": "100%"
});
params = "importUrl&url=" + escape(link) + "&albumID=" + albumID;
lychee.api(params, "text", function(data) {
$(".upload_overlay").removeClass("fadeIn").css("opacity", 0);
$.timer(300, function() { $(".upload_overlay").remove() });
if (data) {
if (album.getID()=="") lychee.goto("a0");
else album.load(album.getID());
} else loadingBar.show("error");
});
} else if (link.length>0) loadingBar.show("error", "Error", "Link to short or too long. Please try another one!");
},
dropbox: function() {
lychee.loadDropbox(function() {
Dropbox.choose({
linkType: "direct",
multiselect: false,
success: function(files) { photo.add.url(files[0].link) }
});
});
}
},
delete: function(photoID) {
var params,
buttons,
photoTitle;
if (!photoID) photoID = photo.getID();
if (visible.photo()) photoTitle = photo.json.title;
else photoTitle = album.json.content[photoID].title;
if (photoTitle=="") photoTitle = "Untitled";
buttons = [
["Delete Photo", function() {
album.json.content[photoID] = null;
view.album.content.delete(photoID);
// Only when search is not active
if (!visible.albums()) lychee.goto("a" + album.getID());
params = "deletePhoto&photoID=" + photoID;
lychee.api(params, "text", function(data) {
if (!data) loadingBar.show("error");
});
}],
["Keep Photo", function() {}]
];
modal.show("Delete Photo", "Are you sure you want to delete the photo '" + photoTitle + "'?<br>This action can't be undone!", buttons);
},
setTitle: function(photoID) {
var oldTitle = "",
newTitle,
params;
if (!photoID) photoID = photo.getID();
if (photo.json) oldTitle = photo.json.title;
else if (album.json) oldTitle = album.json.content[photoID].title;
newTitle = prompt("Please enter a new title for this photo:", oldTitle);
if (photoID!=null&&photoID&&newTitle.length<31) {
if (visible.photo()) {
photo.json.title = (newTitle=="") ? "Untitled" : newTitle;
view.photo.title(oldTitle);
}
album.json.content[photoID].title = newTitle;
view.album.content.title(photoID);
params = "setPhotoTitle&photoID=" + photoID + "&title=" + escape(encodeURI(newTitle));
lychee.api(params, "text", function(data) {
if (!data) loadingBar.show("error");
});
} else if (newTitle.length>0) loadingBar.show("error", "Error", "New title to short or too long. Please try another one!");
},
setAlbum: function(albumID, photoID) {
var params;
if (albumID>=0) {
if (visible.photo) lychee.goto("a" + album.getID());
album.json.content[photoID] = null;
view.album.content.delete(photoID);
params = "setAlbum&photoID=" + photoID + "&albumID=" + albumID;
lychee.api(params, "text", function(data) {
if (!data) loadingBar.show("error");
});
}
},
setStar: function(photoID) {
var params;
if (visible.photo()) {
photo.json.star = (photo.json.star==0) ? 1 : 0;
view.photo.star();
}
album.json.content[photoID].star = (album.json.content[photoID].star==0) ? 1 : 0;
view.album.content.star(photoID);
params = "setPhotoStar&photoID=" + photoID;
lychee.api(params, "text", function(data) {
if (!data) loadingBar.show("error");
});
},
setPublic: function(photoID, e) {
var params;
if (photo.json.public==2) {
modal.show("Public Album", "This photo is located in a public album. To make this photo private or public, edit the visibility of the associated album.", [["Show Album", function() { lychee.goto("a" + photo.json.original_album) }], ["Close", function() {}]]);
return false;
}
if (visible.photo()) {
photo.json.public = (photo.json.public==0) ? 1 : 0;
view.photo.public();
if (photo.json.public==1) contextMenu.sharePhoto(photoID, e);
}
album.json.content[photoID].public = (album.json.content[photoID].public==0) ? 1 : 0;
view.album.content.public(photoID);
params = "setPhotoPublic&photoID=" + photoID + "&url=" + photo.getViewLink(photoID);
lychee.api(params, "text", function(data) {
if (!data) loadingBar.show("error");
});
},
setDescription: function(photoID) {
var oldDescription = photo.json.description,
description = prompt("Please enter a description for this photo:", oldDescription),
params;
if (description.length>0&&description.length<160) {
if (visible.photo()) {
photo.json.description = description;
view.photo.description(oldDescription);
}
params = "setPhotoDescription&photoID=" + photoID + "&description=" + escape(description);
lychee.api(params, "text", function(data) {
if (!data) loadingBar.show("error");
});
} else if (description.length>0) loadingBar.show("error", "Error", "Description to short or too long. Please try another one!");
},
share: function(photoID, service) {
var link = "",
url = photo.getViewLink(photoID),
params,
filename = "unknown";
switch (service) {
case 0:
link = "https://twitter.com/share?url=" + encodeURI(url);
break;
case 1:
link = "http://www.facebook.com/sharer.php?u=" + encodeURI(url) + "&t=" + encodeURI(photo.json.title);
break;
case 2:
link = "mailto:?subject=" + encodeURI(photo.json.title) + "&body=" + encodeURI(url);
break;
case 3:
lychee.loadDropbox(function() {
filename = photo.json.title + "." + photo.getDirectLink().split('.').pop();
Dropbox.save(photo.getDirectLink(), filename);
});
break;
default:
link = "";
break;
}
if (link.length>5) location.href = link;
},
isSmall: function() {
var size = [
["width", false],
["height", false]
];
if (photo.json.width<$(window).width()-60) size["width"] = true;
if (photo.json.height<$(window).height()-100) size["height"] = true;
if (size["width"]&&size["height"]) return true;
else return false;
},
getDirectLink: function() {
return $("#imageview #image").css("background-image").replace(/"/g,"").replace(/url\(|\)$/ig, "");
},
getViewLink: function(photoID) {
if (location.href.indexOf("index.html")>0) return location.href.replace("index.html" + location.hash, "view.php?p=" + photoID);
else return location.href.replace(location.hash, "view.php?p=" + photoID);
}
}

View File

@ -1,5 +1,5 @@
/**
* @name photos.js
* @name search.js
* @author Philipp Maurer
* @author Tobias Reich
* @copyright 2013 by Philipp Maurer, Tobias Reich
@ -10,8 +10,15 @@
search = {
code: null,
find: function(term) {
var params,
albumsData = "",
photosData = "",
code;
clearTimeout($(window).data("timeout"));
$(window).data("timeout", setTimeout(function() {
@ -20,27 +27,37 @@ search = {
params = "search&term=" + term;
lychee.api(params, "json", function(data) {
albumsData = "";
if (data&&data.albums) $.each(data.albums, function() { albumsData += build.album(this); });
if (data&&data.albums) {
albums.json = { content: data.albums };
$.each(albums.json.content, function() {
albums.parse(this);
albumsData += build.album(this);
});
}
photosData = "";
if (data&&data.photos) $.each(data.photos, function() { photosData += build.photo(this); });
if (data&&data.photos) {
album.json = { content: data.photos };
$.each(album.json.content, function() {
album.parse(this);
photosData += build.photo(this);
});
}
if (albumsData==""&&photosData=="") code = "error";
else if (albumsData=="") code = build.divider("Photos")+photosData;
else if (photosData=="") code = build.divider("Albums")+albumsData;
else code = build.divider("Photos")+photosData+build.divider("Albums")+albumsData;
if (lychee.content.attr("data-search")!=code) {
if (search.code!=hex_md5(code)) {
$(".no_content").remove();
lychee.animate(".album, .photo", "contentZoomOut");
lychee.animate(".divider", "fadeOut");
$.timer(300,function(){
search.code = hex_md5(code);
lychee.content.attr("data-search", code);
$.timer(300,function(){
if (code=="error") $("body").append(build.no_content("search"));
else {
@ -65,9 +82,9 @@ search = {
$("#search").val("");
$(".no_content").remove();
if (lychee.content.attr("data-search")!="") {
if (search.code!="") {
lychee.content.attr("data-search", "");
search.code = "";
lychee.animate(".divider", "fadeOut");
albums.load();

395
js/modules/view.js Normal file
View File

@ -0,0 +1,395 @@
/**
* @name view.js
* @author Philipp Maurer
* @author Tobias Reich
* @copyright 2013 by Philipp Maurer, Tobias Reich
*
* UI View
* Responsible to reflect data changes to the UI.
*/
view = {
header: {
show: function() {
clearTimeout($(window).data("timeout"));
if (visible.photo()) {
lychee.imageview.removeClass("full");
lychee.loadingBar.css("opacity", 1);
lychee.header.css("margin-Top", "0px");
if ($("#imageview #image.small").length>0) {
$("#imageview #image").css({
marginTop: -1*($("#imageview #image").height()/2)+20
});
} else {
$("#imageview #image").css({
top: 70,
right: 30,
bottom: 30,
left: 30
});
}
}
},
hide: function() {
if (visible.photo()&&!visible.infobox()) {
clearTimeout($(window).data("timeout"));
$(window).data("timeout", setTimeout(function() {
lychee.imageview.addClass("full");
lychee.loadingBar.css("opacity", 0);
lychee.header.css("margin-Top", "-45px");
if ($("#imageview #image.small").length>0) {
$("#imageview #image").css({
marginTop: -1*($("#imageview #image").height()/2)
});
} else {
$("#imageview #image").css({
top: 0,
right: 0,
bottom: 0,
left: 0
});
}
}, 500));
}
},
mode: function(mode) {
var albumID;
switch (mode) {
case "albums":
$("#tools_album, #tools_photo").hide();
$("#tools_albums").show();
break;
case "album":
$("#tools_albums, #tools_photo").hide();
$("#tools_album").show();
albumID = album.getID();
if (albumID=="s"||albumID=="f") $("#button_edit_album, #button_trash_album, #button_share_album").hide();
else if (albumID==0) $("#button_edit_album, #button_share_album").hide();
else $("#button_edit_album, #button_trash_album, #button_share_album").show();
break;
case "photo":
$("#tools_albums, #tools_album").hide();
$("#tools_photo").show();
break;
}
}
},
albums: {
init: function() {
view.albums.title();
view.albums.content.init();
},
title: function() {
lychee.setTitle("Albums", null, false);
},
content: {
init: function() {
var smartData = "",
albumsData = "";
/* Smart Albums */
albums.parse(albums.json.unsortedAlbum);
albums.parse(albums.json.publicAlbum);
albums.parse(albums.json.starredAlbum);
if (!lychee.publicMode) smartData = build.divider("Smart Albums") + build.album(albums.json.unsortedAlbum) + build.album(albums.json.starredAlbum) + build.album(albums.json.publicAlbum);
/* Albums */
if (albums.json.content) {
if (!lychee.publicMode) albumsData = build.divider("Albums");
$.each(albums.json.content, function() {
albums.parse(this);
albumsData += build.album(this);
});
}
if (smartData==""&&albumsData=="") $("body").append(build.no_content("picture"));
else lychee.content.html(smartData + albumsData);
$("img").retina();
},
title: function(albumID) {
var prefix = "",
title = albums.json.content[albumID].title;
if (albums.json.content[albumID].password) prefix = "<span class='icon-lock'></span> ";
if (title.length>18) title = title.substr(0, 18) + "...";
$(".album[data-id='" + albumID + "'] .overlay h1").html(prefix + title);
},
delete: function(albumID) {
$(".album[data-id='" + albumID + "']").css("opacity", 0).animate({
width: 0,
marginLeft: 0
}, 300, function() {
$(this).remove();
});
}
}
},
album: {
init: function() {
album.parse();
view.album.title();
view.album.public();
view.album.content.init();
album.json.init = 1;
},
title: function() {
if ((visible.album()||!album.json.init)&&!visible.photo()) {
switch (album.getID()) {
case "f":
lychee.setTitle("Starred", album.json.num, false);
break;
case "s":
lychee.setTitle("Public", album.json.num, false);
break;
case "0":
lychee.setTitle("Unsorted", album.json.num, false);
break;
default:
lychee.setTitle(album.json.title, album.json.num, true);
break;
}
}
},
content: {
init: function() {
var photosData = "";
$.each(album.json.content, function() {
album.parse(this);
photosData += build.photo(this);
});
lychee.content.html(photosData);
$("img").retina();
},
title: function(photoID) {
var title = album.json.content[photoID].title;
if (title.length>18) title = title.substr(0, 18) + "...";
$(".photo[data-id='" + photoID + "'] .overlay h1").html(title);
},
star: function(photoID) {
$(".photo[data-id='" + photoID + "'] .icon-star").remove();
if (album.json.content[photoID].star==1) $(".photo[data-id='" + photoID + "']").append("<a class='badge red icon-star'></a>");
},
public: function(photoID) {
$(".photo[data-id='" + photoID + "'] .icon-share").remove();
if (album.json.content[photoID].public==1) $(".photo[data-id='" + photoID + "']").append("<a class='badge red icon-share'></a>");
},
delete: function(photoID) {
$(".photo[data-id='" + photoID + "']").css("opacity", 0).animate({
width: 0,
marginLeft: 0
}, 300, function() {
$(this).remove();
// Only when search is not active
if (!visible.albums()) {
album.json.num--;
view.album.title();
}
});
}
},
public: function() {
if (album.json.public==1) {
$("#button_share_album a").addClass("active");
$("#button_share_album").attr("title", "Share Album");
$(".photo .icon-share").remove();
} else {
$("#button_share_album a").removeClass("active");
$("#button_share_album").attr("title", "Make Public");
}
}
},
photo: {
init: function() {
photo.parse();
view.photo.infobox();
view.photo.title();
view.photo.star();
view.photo.public();
view.photo.photo();
photo.json.init = 1;
},
show: function() {
view.header.mode("photo");
// Make body not scrollable
$("body").css("overflow", "hidden");
lychee.animate(lychee.imageview, "fadeIn");
},
hide: function() {
if (!visible.controls()) view.header.show();
if (visible.infobox) view.photo.hideInfobox();
view.header.mode("album");
// Make body scrollable
$("body").css("overflow", "scroll");
// Hide Photo
lychee.animate(lychee.imageview, "fadeOut");
$.timer(300,function(){ lychee.imageview.hide() });
},
showInfobox: function() {
if (!visible.infobox()) $("body").append("<div id='infobox_overlay'></div>");
lychee.infobox.css("right", "0px");
},
hideInfobox: function() {
$("#infobox_overlay").remove();
lychee.infobox.css("right", "-320px");
},
title: function(oldTitle) {
if (photo.json.init) $("#infobox .attr_name").html($("#infobox .attr_name").html().replace(oldTitle, photo.json.title));
lychee.setTitle(photo.json.title, null, true);
},
description: function(oldDescription) {
if (photo.json.init) $("#infobox .attr_description").html($("#infobox .attr_description").html().replace(oldDescription, photo.json.description));
},
star: function() {
$("#button_star a").removeClass("icon-star-empty icon-star");
if (photo.json.star==1) {
// Starred
$("#button_star a").addClass("icon-star");
$("#button_star").attr("title", "Unstar Photo");
} else {
// Unstarred
$("#button_star a").addClass("icon-star-empty");
$("#button_star").attr("title", "Star Photo");
}
},
public: function() {
if (photo.json.public==1||photo.json.public==2) {
// Photo public
$("#button_share a").addClass("active");
$("#button_share").attr("title", "Share Photo");
if (photo.json.init) $("#infobox .attr_visibility").html("Public");
} else {
// Photo private
$("#button_share a").removeClass("active");
$("#button_share").attr("title", "Make Public");
if (photo.json.init) $("#infobox .attr_visibility").html("Private");
}
},
photo: function() {
if (visible.controls()&&photo.isSmall()) lychee.imageview.html("<a id='previous' class='icon-caret-left'></a><a id='next' class='icon-caret-right'></a><div id='image' class='small' style='background-image: url(" + photo.json.url + "); width: " + photo.json.width + "px; height: " + photo.json.height + "px; margin-top: -" + parseInt(photo.json.height/2-20) + "px; margin-left: -" + photo.json.width/2 + "px;'></div>");
else if (visible.controls()) lychee.imageview.html("<a id='previous' class='icon-caret-left'></a><a id='next' class='icon-caret-right'></a><div id='image' style='background-image: url(" + photo.json.url + ")'></div>");
else if (photo.isSmall()) lychee.imageview.html("<a id='previous' style='left: -50px' class='icon-caret-left'></a><a id='next' style='right: -50px' class='icon-caret-right'></a><div id='image' class='small' style='background-image: url(" + photo.json.url + "); width: " + photo.json.width + "px; height: " + photo.json.height + "px; margin-top: -" + parseInt(photo.json.height/2) + "px; margin-left: -" + photo.json.width/2 + "px;'></div>");
else lychee.imageview.html("<a id='previous' style='left: -50px' class='icon-caret-left'></a><a id='next' style='right: -50px' class='icon-caret-right'></a><div id='image' style='background-image: url(" + photo.json.url + "); top: 0px; right: 0px; bottom: 0px; left: 0px;'></div>");
if (!photo.json.nextPhoto||lychee.viewMode) $("a#next").hide();
if (!photo.json.previousPhoto||lychee.viewMode) $("a#previous").hide();
},
infobox: function() {
lychee.infobox.html(build.infobox(photo.json)).show();
}
}
}

View File

@ -15,8 +15,13 @@ visible = {
else return false;
},
imageview: function() {
if ($("#image_view.fadeIn").length>0) return true;
album: function() {
if ($("#tools_album").css("display")=="block") return true;
else return false;
},
photo: function() {
if ($("#imageview.fadeIn").length>0) return true;
else return false;
},
@ -26,7 +31,17 @@ visible = {
},
controls: function() {
if (lychee.loadingBar.css("opacity")>0) return true;
if (lychee.loadingBar.css("opacity")<1) return false;
else return true;
},
message: function() {
if ($(".message").length>0) return true;
else return false;
},
contextMenu: function() {
if ($(".contextmenu").length>0) return true;
else return false;
}

View File

@ -7,7 +7,7 @@
var header = $("header"),
headerTitle = $("#title"),
image_view = $("#image_view"),
imageview = $("#imageview"),
api_path = "php/api.php",
infobox = $("#infobox");
@ -27,7 +27,7 @@ $(document).ready(function(){
/* Download */
$("#button_download").on(event_name, function() {
link = $("#image_view #image").css("background-image").replace(/"/g,"").replace(/url\(|\)$/ig, "");
link = $("#imageview #image").css("background-image").replace(/"/g,"").replace(/url\(|\)$/ig, "");
window.open(link,"_newtab");
});
@ -80,17 +80,19 @@ function hideInfobox() {
function loadPhotoInfo(photoID) {
params = "function=getPhotoInfo&photoID=" + photoID + "&password=''";
params = "function=getPhoto&photoID=" + photoID + "&albumID=0&password=''";
$.ajax({type: "POST", url: api_path, data: params, dataType: "json", success: function(data) {
if (!data.title) data.title = "Untitled";
document.title = "Lychee - " + data.title;
headerTitle.html(data.title);
image_view.attr("data-id", photoID);
if (isPhotoSmall(data)) image_view.html("<div id='image' class='small' style='background-image: url(" + data.url + "); width: " + data.width + "px; height: " + data.height + "px; margin-top: -" + parseInt((data.height/2)-20) + "px; margin-left: -" + data.width/2 + "px;'></div>");
else image_view.html("<div id='image' style='background-image: url(" + data.url + "); top: 70px; right: 30px; bottom: 30px; left: 30px;'></div>");
image_view.removeClass("fadeOut").addClass("fadeIn").show();
data.url = "uploads/big/" + data.url;
imageview.attr("data-id", photoID);
if (isPhotoSmall(data)) imageview.html("<div id='image' class='small' style='background-image: url(" + data.url + "); width: " + data.width + "px; height: " + data.height + "px; margin-top: -" + parseInt((data.height/2)-20) + "px; margin-left: -" + data.width/2 + "px;'></div>");
else imageview.html("<div id='image' style='background-image: url(" + data.url + "); top: 70px; right: 30px; bottom: 30px; left: 30px;'></div>");
imageview.removeClass("fadeOut").addClass("fadeIn").show();
infobox.html(build.infobox(data, true)).show();

View File

@ -34,8 +34,8 @@ if (!empty($_POST['function'])||!empty($_GET['function'])) {
// Album Functions
if ($_POST['function']=='getAlbums') echo json_encode(getAlbums(false));
if ($_POST['function']=='getSmartInfo') echo json_encode(getSmartInfo());
if ($_POST['function']=='getAlbum'&&isset($_POST['albumID'])) echo json_encode(getAlbum($_POST['albumID']));
if ($_POST['function']=='addAlbum'&&isset($_POST['title'])) echo addAlbum($_POST['title']);
if ($_POST['function']=='getAlbumInfo'&&isset($_POST['albumID'])) echo json_encode(getAlbumInfo($_POST['albumID']));
if ($_POST['function']=='setAlbumTitle'&&isset($_POST['albumID'])&&isset($_POST['title'])) echo setAlbumTitle($_POST['albumID'], $_POST['title']);
if ($_POST['function']=='setAlbumPublic'&&isset($_POST['albumID'])) echo setAlbumPublic($_POST['albumID']);
if ($_POST['function']=='setAlbumPassword'&&isset($_POST['albumID'])&&isset($_POST['password'])) echo setAlbumPassword($_POST['albumID'], $_POST['password']);
@ -43,17 +43,13 @@ if (!empty($_POST['function'])||!empty($_GET['function'])) {
if (isset($_GET['function'])&&$_GET['function']=='getAlbumArchive'&&isset($_GET['albumID'])) getAlbumArchive($_GET['albumID']);
// Photo Functions
if ($_POST['function']=='getPhotos'&&isset($_POST['albumID'])) echo json_encode(getPhotos($_POST['albumID']));
if ($_POST['function']=='getPhotoInfo'&&isset($_POST['photoID'])) echo json_encode(getPhotoInfo($_POST['photoID']));
if ($_POST['function']=='getShortlink'&&isset($_POST['photoID'])) echo getShortlink($_POST['photoID']);
if ($_POST['function']=='setAlbum'&&isset($_POST['photoID'])&&isset($_POST['albumID'])) echo setAlbum($_POST['photoID'], $_POST['albumID']);
if ($_POST['function']=='getPhoto'&&isset($_POST['photoID'])&&isset($_POST['albumID'])) echo json_encode(getPhoto($_POST['photoID'], $_POST['albumID']));
if ($_POST['function']=='deletePhoto'&&isset($_POST['photoID'])) echo deletePhoto($_POST['photoID']);
if ($_POST['function']=='setAlbum'&&isset($_POST['photoID'])&&isset($_POST['albumID'])) echo setAlbum($_POST['photoID'], $_POST['albumID']);
if ($_POST['function']=='setPhotoTitle'&&isset($_POST['photoID'])&&isset($_POST['title'])) echo setPhotoTitle($_POST['photoID'], $_POST['title']);
if ($_POST['function']=='setPhotoStar'&&isset($_POST['photoID'])) echo setPhotoStar($_POST['photoID']);
if ($_POST['function']=='setPhotoPublic'&&isset($_POST['photoID'])&&isset($_POST['url'])) echo setPhotoPublic($_POST['photoID'], $_POST['url']);
if ($_POST['function']=='setPhotoDescription'&&isset($_POST['photoID'])&&isset($_POST['description'])) echo setPhotoDescription($_POST['photoID'], $_POST['description']);
if ($_POST['function']=='previousPhoto'&&isset($_POST['photoID'])&&isset($_POST['albumID'])) echo json_encode(previousPhoto($_POST['photoID'], $_POST['albumID'], false));
if ($_POST['function']=='nextPhoto'&&isset($_POST['photoID'])&&isset($_POST['albumID'])) echo json_encode(nextPhoto($_POST['photoID'], $_POST['albumID'], false));
// Add Function
if ($_POST['function']=='upload'&&isset($_FILES)&&isset($_POST['albumID'])) echo upload($_FILES, $_POST['albumID']);
@ -76,22 +72,33 @@ if (!empty($_POST['function'])||!empty($_GET['function'])) {
// Album Functions
if ($_POST['function']=='getAlbums') echo json_encode(getAlbums(true));
if ($_POST['function']=='getAlbumInfo'&&isset($_POST['albumID'])&&isset($_POST['password'])&&isAlbumPublic($_POST['albumID'], $_POST['password'])) echo json_encode(getAlbumInfo($_POST['albumID']));
if ($_POST['function']=='getAlbum'&&isset($_POST['albumID'])&&isset($_POST['password'])) {
if (isAlbumPublic($_POST['albumID'])) {
// Album Public
if (checkAlbumPassword($_POST['albumID'], $_POST['password'])) echo json_encode(getAlbum($_POST['albumID']));
else echo json_encode('HTTP/1.1 403 Wrong password!');
} else {
// Album Private
echo json_encode('HTTP/1.1 403 Album private!');
}
}
if ($_POST['function']=='checkAlbumAccess'&&isset($_POST['albumID'])&&isset($_POST['password'])) {
if (isAlbumPublic($_POST['albumID'])) {
// Album Public
if (checkAlbumPassword($_POST['albumID'], $_POST['password'])) echo true;
else echo false;
} else {
// Album Private
echo false;
}
}
// Photo Functions
if ($_POST['function']=='getPhotos') {
if (isset($_POST['albumID'])&&isset($_POST['password'])&&isAlbumPublic($_POST['albumID'], $_POST['password'])) echo json_encode(getPhotos($_POST['albumID']));
if ($_POST['function']=='getPhoto'&&isset($_POST['photoID'])&&isset($_POST['albumID'])&&isset($_POST['password'])) {
if (isPhotoPublic($_POST['photoID'], $_POST['password'])) echo json_encode(getPhoto($_POST['photoID'], $_POST['albumID']));
else echo json_encode('HTTP/1.1 403 Wrong password!');
}
if ($_POST['function']=='getPhotoInfo') {
if (isset($_POST['photoID'])&&isset($_POST['password'])&&isPhotoPublic($_POST['photoID'], $_POST['password'])) echo json_encode(getPhotoInfo($_POST['photoID']));
else echo json_encode('HTTP/1.1 403 Wrong password!');
}
if ($_POST['function']=='previousPhoto'&&isset($_POST['photoID'])&&isset($_POST['albumID'])) echo json_encode(previousPhoto($_POST['photoID'], $_POST['albumID'], false));
if ($_POST['function']=='nextPhoto'&&isset($_POST['photoID'])&&isset($_POST['albumID'])) echo json_encode(nextPhoto($_POST['photoID'], $_POST['albumID'], false));
// Session Functions
if ($_POST['function']=='init') echo json_encode(init('public'));
if ($_POST['function']=='login') echo login($_POST['user'], $_POST['password']);

View File

@ -23,7 +23,5 @@ $password = '1234'; //Admin Password
$checkForUpdates = true;
$thumbQuality = 95; //Quality of the Thumbs (0-100). Default: 95
$sorting = 'DESC'; //ASC or DESC sorting of albums and photos
$bitlyUsername = ''; //Your Bit.ly Username
$bitlyApi = ''; //Your Bit.ly API Key
?>

View File

@ -7,7 +7,7 @@
* @copyright 2013 by Philipp Maurer, Tobias Reich
*/
if(!defined('LYCHEE')) die('Direct access is not allowed!');
if (!defined('LYCHEE')) die('Direct access is not allowed!');
// Database Functions
function dbConnect() {
@ -21,12 +21,12 @@ function dbConnect() {
createDatabase($db, $database);
}
$query = "SELECT * FROM lychee_photos, lychee_albums;";
if(!$database->query($query)) createTables($database);
if (!$database->query($query)) createTables($database);
return $database;
}
function dbClose() {
global $database;
if(!$database->close()) {
if (!$database->close()) {
echo "Closing the connection failed!";
return false;
}
@ -35,7 +35,7 @@ function dbClose() {
function createDatabase($db, $database) {
$result = $database->query("CREATE DATABASE IF NOT EXISTS $db;");
$database->select_db($db);
if(!$result) return false;
if (!$result) return false;
return true;
}
function createTables($database) {
@ -48,7 +48,7 @@ function createTables($database) {
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;";
$result = $database->query($query);
if(!$result) return false;
if (!$result) return false;
$query = "CREATE TABLE `lychee_photos` (
`id` bigint(14) NOT NULL,
@ -56,7 +56,6 @@ function createTables($database) {
`description` varchar(160) NOT NULL,
`url` varchar(100) NOT NULL,
`public` tinyint(1) NOT NULL,
`shortlink` varchar(20) NOT NULL,
`type` varchar(10) NOT NULL,
`width` int(11) NOT NULL,
`height` int(11) NOT NULL,
@ -78,80 +77,92 @@ function createTables($database) {
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;";
$result = $database->query($query);
if(!$result) return false;
if (!$result) return false;
return true;
}
// Upload Functions
function upload($files, $albumID) {
global $database;
switch($albumID) {
// s for public (share)
case 's':
$public = 1;
$star = 0;
$albumID = 0;
break;
// f for starred (fav)
case 'f':
$star = 1;
$public = 0;
$albumID = 0;
break;
default:
$star = 0;
$public = 0;
}
foreach ($files as $file) {
switch($albumID) {
// s for public (share)
case 's':
$public = 1;
$star = 0;
$albumID = 0;
break;
// f for starred (fav)
case 'f':
$star = 1;
$public = 0;
$albumID = 0;
break;
default:
$star = 0;
$public = 0;
}
$id = str_replace('.', '', microtime(true));
while(strlen($id)<14) $id .= 0;
$tmp_name = $file["tmp_name"];
$type = getimagesize($tmp_name);
if(($type[2]!=1)&&($type[2]!=2)&&($type[2]!=3)) return false;
if (($type[2]!=1)&&($type[2]!=2)&&($type[2]!=3)) return false;
$data = $file["name"];
$data = explode('.',$data);
$data = array_reverse ($data);
$data = $data[0];
if(!is_uploaded_file($file)) {
if (copy($tmp_name, "../uploads/big/$id.$data")) {
// Import if not uploaded via web
if (!is_uploaded_file($file)) {
if (copy($tmp_name, "../uploads/big/" . md5($id) . ".$data")) {
unlink($tmp_name);
$import_name = $tmp_name;
}
} else {
move_uploaded_file($tmp_name, "../uploads/big/$id.$data");
move_uploaded_file($tmp_name, "../uploads/big/" . md5($id) . ".$data");
$import_name = "";
}
createThumb($id.".".$data);
// Create Thumb
createThumb(md5($id).".".$data);
// Read infos
$info = getCamera($id.".".$data);
$title="";
if(isset($info['type'])){$type=$info['type'];}else{$type="";}
if(isset($info['width'])){$width=$info['width'];}else{$width="";}
if(isset($info['height'])){$height=$info['height'] OR "";}else{$height="";}
if(isset($info['size'])){$size=$info['size'] OR "";}else{$size="";}
if(isset($info['date'])){$sysdate=$info['date'];}else{$sysdate="";}
if(isset($info['time'])){$systime=$info['time'];}else{$systime="";}
if(isset($info['iso'])){$iso=$info['iso'];}else{$iso="";}
if(isset($info['aperture'])){$aperture=$info['aperture'];}else{$aperture="";}
if(isset($info['make'])){$make=$info['make'];}else{$make="";}
if(isset($info['model'])){$model=$info['model'] OR "";}else{$model="";}
if(isset($info['shutter'])){$shutter=$info['shutter'];}else{$shutter="";}
if(isset($info['focal'])){$focal=$info['focal'];}else{$focal="";}
if(isset($info['takeDate'])){$takeDate=$info['takeDate'];}else{$takeDate="";}
if(isset($info['takeTime'])){$takeTime=$info['takeTime'];}else{$takeTime="";}
$info = getCamera(md5($id).".".$data);
$title = "";
if (isset($info['type'])){$type=$info['type'];} else {$type="";}
if (isset($info['width'])){$width=$info['width'];} else {$width="";}
if (isset($info['height'])){$height=$info['height'] OR "";} else {$height="";}
if (isset($info['size'])){$size=$info['size'] OR "";} else {$size="";}
if (isset($info['date'])){$sysdate=$info['date'];} else {$sysdate="";}
if (isset($info['time'])){$systime=$info['time'];} else {$systime="";}
if (isset($info['iso'])){$iso=$info['iso'];} else {$iso="";}
if (isset($info['aperture'])){$aperture=$info['aperture'];} else {$aperture="";}
if (isset($info['make'])){$make=$info['make'];} else {$make="";}
if (isset($info['model'])){$model=$info['model'] OR "";} else {$model="";}
if (isset($info['shutter'])){$shutter=$info['shutter'];} else {$shutter="";}
if (isset($info['focal'])){$focal=$info['focal'];} else {$focal="";}
if (isset($info['takeDate'])){$takeDate=$info['takeDate'];} else {$takeDate="";}
if (isset($info['takeTime'])){$takeTime=$info['takeTime'];} else {$takeTime="";}
$query = "INSERT INTO lychee_photos (id, title, url, type, width, height, size, sysdate, systime, iso, aperture, make, model, shutter, focal, takedate, taketime, thumbUrl, album, public, star, import_name)
VALUES ('$id', '$title', 'uploads/big/$id.$data', '$type', '$width', '$height', '$size', '$sysdate', '$systime', '$iso', '$aperture', '$make', '$model', '$shutter', '$focal', '$takeDate', '$takeTime', 'uploads/thumb/$id.$data', '$albumID', '$public', '$star', '$import_name');";
VALUES ('$id', '$title', '" . md5($id) . ".$data', '$type', '$width', '$height', '$size', '$sysdate', '$systime', '$iso', '$aperture', '$make', '$model', '$shutter', '$focal', '$takeDate', '$takeTime', '" . md5($id) . ".$data', '$albumID', '$public', '$star', '$import_name');";
$result = $database->query($query);
}
return true;
}
function getCamera($photoID) {
function getCamera($filename) {
global $database;
$url = "../uploads/big/$photoID";
$url = "../uploads/big/$filename";
$type = getimagesize($url);
$type = $type['mime'];
if(($type == "image/jpeg") && function_exists('exif_read_data') ){
if (($type == "image/jpeg") && function_exists('exif_read_data') ){
$exif = exif_read_data($url, "EXIF", 0);
@ -162,35 +173,33 @@ function getCamera($photoID) {
$return['width'] = $generalInfos[0];
$return['height'] = $generalInfos[1];
$size = (filesize($url) / 1024);
if($size >= 1024){$size=round($size/1024,1)." MB";}else{$size=round($size,1)." KB";}
if ($size >= 1024){$size=round($size/1024,1)." MB";} else {$size=round($size,1)." KB";}
$return['size'] = $size;
$return['date'] = date("d.m.Y",filectime($url));
$return['time'] = date("H:i:s",filectime($url));
//echo $exif['FileDateTime']."<br/>".$exif['DateTimeOriginal'];
// Camera Information
if(isset($exif['ISOSpeedRatings'])){$return['iso']="ISO-".$exif['ISOSpeedRatings'];}
if(isset($exif['COMPUTED']['ApertureFNumber'])){$return['aperture']=$exif['COMPUTED']['ApertureFNumber'];}
if(isset($exif['Make'])){$return['make']=$exif['Make'];}
if(isset($exif['Model'])){$return['model']=$exif['Model'];}
if(isset($exif['ExposureTime'])){$return['shutter']=$exif['ExposureTime']." Sek.";}
if(isset($exif['FocalLength'])){$return['focal']=($exif['FocalLength']/1)." mm";}
if(isset($exif['Software'])){$return['software']=$exif['Software'];}
if(isset($exif['DateTimeOriginal'])) {
if (isset($exif['ISOSpeedRatings'])){$return['iso']="ISO-".$exif['ISOSpeedRatings'];}
if (isset($exif['COMPUTED']['ApertureFNumber'])){$return['aperture']=$exif['COMPUTED']['ApertureFNumber'];}
if (isset($exif['Make'])){$return['make']=$exif['Make'];}
if (isset($exif['Model'])){$return['model']=$exif['Model'];}
if (isset($exif['ExposureTime'])){$return['shutter']=$exif['ExposureTime']." Sek.";}
if (isset($exif['FocalLength'])){$return['focal']=($exif['FocalLength']/1)." mm";}
if (isset($exif['Software'])){$return['software']=$exif['Software'];}
if (isset($exif['DateTimeOriginal'])) {
$exifDate = explode(" ",$exif['DateTimeOriginal']);
$date = explode(":", $exifDate[0]); $return['takeDate'] = $date[2].".".$date[1].".".$date[0];
$return['takeTime'] = $exifDate[1];
}
}else{
} else {
$exif = getimagesize($url);
$return['type'] = $exif['mime'];
$return['width'] = $exif[0];
$return['height'] = $exif[1];
$size = (filesize($url) / 1024);
if($size >= 1024){$size=round($size/1024,1)." MB";}else{$size=round($size,1)." KB";}
if ($size >= 1024){$size=round($size/1024,1)." MB";} else {$size=round($size,1)." KB";}
$return['size'] = $size;
$return['date'] = date("d.m.Y",filectime($url));
$return['time'] = date("H:i:s",filectime($url));
@ -198,23 +207,20 @@ function getCamera($photoID) {
}
return $return;
}
function createThumb($photoName, $width = 200, $width2x = 400, $height = 200, $height2x = 400) {
function createThumb($filename, $width = 200, $width2x = 400, $height = 200, $height2x = 400) {
global $database, $thumbQuality;
$photoUrl = "../uploads/big/$photoName";
$newUrl = "../uploads/thumb/$photoName";
$thumbPhotoName = explode(".", $photoName);
$photoUrl = "../uploads/big/$filename";
$newUrl = "../uploads/thumb/$filename";
$thumbPhotoName = explode(".", $filename);
$newUrl2x = "../uploads/thumb/".$thumbPhotoName[0]."@2x.".$thumbPhotoName[1];
$oldImg = getimagesize($photoUrl);
$type = $oldImg['mime'];
switch($type) {
case "image/jpeg": $sourceImg = imagecreatefromjpeg($photoUrl); break;
case "image/png": $sourceImg = imagecreatefrompng($photoUrl); break;
case "image/gif": $sourceImg = imagecreatefromgif($photoUrl); break;
default: return false;
}
// Set position and size
$thumb = imagecreatetruecolor($width, $height);
$thumb2x = imagecreatetruecolor($width2x, $height2x);
if($oldImg[0]<$oldImg[1]) {
if ($oldImg[0]<$oldImg[1]) {
$newSize = $oldImg[0];
$startWidth = 0;
$startHeight = $oldImg[1]/2 - $oldImg[0]/2;
@ -223,6 +229,14 @@ function createThumb($photoName, $width = 200, $width2x = 400, $height = 200, $h
$startWidth = $oldImg[0]/2 - $oldImg[1]/2;
$startHeight = 0;
}
// Create new image
switch($type) {
case "image/jpeg": $sourceImg = imagecreatefromjpeg($photoUrl); break;
case "image/png": $sourceImg = imagecreatefrompng($photoUrl); break;
case "image/gif": $sourceImg = imagecreatefromgif($photoUrl); break;
default: return false;
}
imagecopyresampled($thumb,$sourceImg,0,0,$startWidth,$startHeight,$width,$height,$newSize,$newSize);
imagecopyresampled($thumb2x,$sourceImg,0,0,$startWidth,$startHeight,$width2x,$height2x,$newSize,$newSize);
switch($type) {
@ -231,14 +245,15 @@ function createThumb($photoName, $width = 200, $width2x = 400, $height = 200, $h
case "image/gif": imagegif($thumb,$newUrl); imagegif($thumb2x,$newUrl2x); break;
default: return false;
}
return true;
}
// Session Functions
function init($mode) {
global $checkForUpdates, $bitlyUsername;
global $checkForUpdates;
$return["config"]["checkForUpdates"] = $checkForUpdates;
$return["config"]["bitlyUsername"] = $bitlyUsername;
if ($mode=="admin") $return["loggedIn"] = true;
else $return["loggedIn"] = false;
return $return;
@ -261,12 +276,12 @@ function logout() {
// Album Functions
function addAlbum($title) {
global $database;
$title = mysqli_real_escape_string($database, $title);
if(strlen($title)<1||strlen($title)>30) return false;
$title = mysqli_real_escape_string($database, urldecode($title));
if (strlen($title)<1||strlen($title)>30) return false;
$sysdate = date("d.m.Y");
$query = "INSERT INTO lychee_albums (title, sysdate) VALUES ('$title', '$sysdate');";
$result = $database->query($query);
if(!$result) return false;
if (!$result) return false;
return $database->insert_id;
}
function getAlbums($public) {
@ -281,12 +296,12 @@ function getAlbums($public) {
$result = $database->query($query) OR die("Error: $result <br>".$database->error);
$i=0;
while($row = $result->fetch_object()) {
$return["album"][$i]['id'] = $row->id;
$return["album"][$i]['title'] = $row->title;
$return["album"][$i]['public'] = $row->public;
$return["album"][$i]['sysdate'] = $row->sysdate;
if ($row->password=="") $return["album"][$i]['password'] = false;
else $return["album"][$i]['password'] = true;
$return["content"][$row->id]['id'] = $row->id;
$return["content"][$row->id]['title'] = $row->title;
$return["content"][$row->id]['public'] = $row->public;
$return["content"][$row->id]['sysdate'] = $row->sysdate;
if ($row->password=="") $return["content"][$row->id]['password'] = false;
else $return["content"][$row->id]['password'] = true;
// Thumbs
if (($public&&$row->password=="")||(!$public)) {
@ -295,92 +310,120 @@ function getAlbums($public) {
$result2 = $database->query($query);
$k = 0;
while($row2 = $result2->fetch_object()){
$return["album"][$i]["thumb$k"] = $row2->thumbUrl;
$return["content"][$row->id]["thumb$k"] = $row2->thumbUrl;
$k++;
}
if(!isset($return["album"][$i]["thumb0"]))$return["album"][$i]["thumb0"]="";
if(!isset($return["album"][$i]["thumb1"]))$return["album"][$i]["thumb1"]="";
if(!isset($return["album"][$i]["thumb2"]))$return["album"][$i]["thumb2"]="";
if (!isset($return["content"][$row->id]["thumb0"])) $return["content"][$row->id]["thumb0"]="";
if (!isset($return["content"][$row->id]["thumb1"])) $return["content"][$row->id]["thumb1"]="";
if (!isset($return["content"][$row->id]["thumb2"])) $return["content"][$row->id]["thumb2"]="";
}
$i++;
}
if($i==0) $return["albums"] = false;
if ($i==0) $return["albums"] = false;
else $return["albums"] = true;
return $return;
}
function getSmartInfo() {
function getAlbum($albumID) {
global $database, $sorting;
switch($albumID) {
case "f":
$return['public'] = false;
$query = "SELECT id, title, sysdate, public, star, album, thumbUrl FROM lychee_photos WHERE star = 1 ORDER BY id $sorting;";
break;
case "s":
$return['public'] = false;
$query = "SELECT id, title, sysdate, public, star, album, thumbUrl FROM lychee_photos WHERE public = 1 ORDER BY id $sorting;";
break;
case 0:
$return['public'] = false;
$query = "SELECT id, title, sysdate, public, star, album, thumbUrl FROM lychee_photos WHERE album = 0 ORDER BY id $sorting;";
default:
$result = $database->query("SELECT title, public, password FROM lychee_albums WHERE id = '$albumID';");
$row = $result->fetch_object();
$return['title'] = $row->title;
$return['public'] = $row->public;
if ($row->password=="") $return['password'] = false;
else $return['password'] = true;
$query = "SELECT id, title, sysdate, public, star, album, thumbUrl FROM lychee_photos WHERE album = '$albumID' ORDER BY id $sorting;";
break;
}
$result = $database->query($query);
$i = 0;
while($row = $result->fetch_array()) {
$return['content'][$row['id']] = $row;
$i++;
}
if ($i==0) $return['content'] = false;
$return['id'] = $albumID;
$return['num'] = $i;
return $return;
}
function getSmartInfo() {
global $database, $sorting;
// Unsorted
$query = "SELECT * FROM lychee_photos WHERE album = 0 ORDER BY id $sorting;";
$result = $database->query($query);
$i = 0;
while($row = $result->fetch_object()) {
if($i<3) $return["unsortThumb$i"] = $row->thumbUrl;
if ($i<3) $return["unsortedThumb$i"] = $row->thumbUrl;
$i++;
}
$return['unsortNum'] = $i;
$return['unsortedNum'] = $i;
// Public
$query2 = "SELECT * FROM lychee_photos WHERE public = 1 ORDER BY id $sorting;";
$result2 = $database->query($query2);
$i = 0;
while($row2 = $result2->fetch_object()) {
if($i<3) $return["publicThumb$i"] = $row2->thumbUrl;
if ($i<3) $return["publicThumb$i"] = $row2->thumbUrl;
$i++;
}
$return['publicNum'] = $i;
// Starred
$query3 = "SELECT * FROM lychee_photos WHERE star = 1 ORDER BY id $sorting;";
$result3 = $database->query($query3);
$i = 0;
while($row3 = $result3->fetch_object()) {
if($i<3) $return["starredThumb$i"] = $row3->thumbUrl;
if ($i<3) $return["starredThumb$i"] = $row3->thumbUrl;
$i++;
}
$return['starredNum'] = $i;
return $return;
}
function getAlbumInfo($albumID) {
global $database;
$query = "SELECT * FROM lychee_albums WHERE id = '$albumID';";
$result = $database->query($query);
$row = $result->fetch_object();
$return['title'] = $row->title;
$return['date'] = $row->sysdate;
$return['public'] = $row->public;
$query = "SELECT COUNT(*) AS num FROM lychee_photos WHERE album = '$albumID';";
$result = $database->query($query);
$row = $result->fetch_object();
$return['num'] = $row->num;
return $return;
}
function setAlbumTitle($albumID, $title) {
global $database;
$title = mysqli_real_escape_string($database, urldecode($title));
if(strlen($title)<1||strlen($title)>30) return false;
if (strlen($title)<1||strlen($title)>30) return false;
$query = "UPDATE lychee_albums SET title = '$title' WHERE id = '$albumID';";
$result = $database->query($query);
if(!$result) return false;
if (!$result) return false;
return true;
}
function deleteAlbum($albumID, $delAll) {
global $database;
if($delAll=="true") {
if ($delAll=="true") {
$query = "SELECT id FROM lychee_photos WHERE album = '$albumID';";
$result = $database->query($query);
$error = false;
while($row = $result->fetch_object()) {
if(!deletePhoto($row->id)) $error = true;
if (!deletePhoto($row->id)) $error = true;
}
} else {
$query = "UPDATE lychee_photos SET album = '0' WHERE album = '$albumID';";
$result = $database->query($query);
if(!$result) return false;
if (!$result) return false;
}
if($albumID!=0) {
if ($albumID!=0) {
$query = "DELETE FROM lychee_albums WHERE id = '$albumID';";
$result = $database->query($query);
if(!$result) return false;
if (!$result) return false;
}
if($error) return false;
if ($error) return false;
return true;
}
function getAlbumArchive($albumID) {
@ -408,7 +451,7 @@ function getAlbumArchive($albumID) {
$query = "SELECT * FROM lychee_albums WHERE id = '$albumID';";
$result = $database->query($query);
$row = $result->fetch_object();
if($albumID!=0&&is_numeric($albumID))$zipTitle = $row->title;
if ($albumID!=0&&is_numeric($albumID))$zipTitle = $row->title;
$filename = "../uploads/".$zipTitle.".zip";
$zip = new ZipArchive();
@ -438,64 +481,57 @@ function setAlbumPublic($albumID) {
$query = "SELECT public FROM lychee_albums WHERE id = '$albumID';";
$result = $database->query($query);
$row = $result->fetch_object();
if($row->public == 0){
if ($row->public == 0){
$public = 1;
}else{
} else {
$public = 0;
}
$query = "UPDATE lychee_albums SET public = '$public', password = NULL WHERE id = '$albumID';";
$result = $database->query($query);
if(!$result) return false;
if (!$result) return false;
if ($public==1) {
$query = "UPDATE lychee_photos SET public = 0 WHERE album = '$albumID';";
$result = $database->query($query);
if (!$result) return false;
}
return true;
}
function setAlbumPassword($albumID, $password) {
global $database;
$query = "UPDATE lychee_albums SET password = '$password' WHERE id = '$albumID';";
$result = $database->query($query);
if(!$result) return false;
if (!$result) return false;
return true;
}
function isAlbumPublic($albumID, $password) {
function checkAlbumPassword($albumID, $password) {
global $database;
$query = "SELECT public, password FROM lychee_albums WHERE id = '$albumID';";
$result = $database->query($query);
$row = $result->fetch_object();
if(($row->public == 1) && ($row->password == $password)){
return true;
}else{
return false;
}
if ($row->password=="") return true;
else if ($row->password==$password) return true;
else return false;
}
function isAlbumPublic($albumID) {
global $database;
$query = "SELECT public, password FROM lychee_albums WHERE id = '$albumID';";
$result = $database->query($query);
$row = $result->fetch_object();
if ($row->public==1) return true;
else return false;
}
// Photo Functions
function getPhotos($albumID) {
global $database, $sorting;
switch($albumID) {
case "f": $query = "SELECT id, title, sysdate, public, star, album, thumbUrl FROM lychee_photos WHERE star = 1 ORDER BY id $sorting;";
break;
case "s": $query = "SELECT id, title, sysdate, public, star, album, thumbUrl FROM lychee_photos WHERE public = 1 ORDER BY id $sorting;";
break;
default: $query = "SELECT id, title, sysdate, public, star, album, thumbUrl FROM lychee_photos WHERE album = '$albumID' ORDER BY id $sorting;";
}
$result = $database->query($query);
$i = 0;
while($row = $result->fetch_array()) {
$return[$i] = $row;
$i++;
}
if($i==0) return false;
return $return;
}
function getPhotoInfo($photoID) {
function getPhoto($photoID, $albumID) {
global $database;
if(!is_numeric($photoID)) {
if (!is_numeric($photoID)) {
$query = "SELECT COUNT(*) AS quantity FROM lychee_photos WHERE import_name = '../uploads/import/$photoID';";
$result = $database->query($query);
$row = $result->fetch_object();
if($row->quantity == 0) {
if ($row->quantity == 0) {
importPhoto($photoID, 's');
}
if(is_file("../uploads/import/$photoID")) {
if (is_file("../uploads/import/$photoID")) {
importPhoto($photoID, 's');
}
$query = "SELECT * FROM lychee_photos WHERE import_name = '../uploads/import/$photoID' ORDER BY ID DESC;";
@ -504,6 +540,32 @@ function getPhotoInfo($photoID) {
}
$result = $database->query($query);
$return = $result->fetch_array();
if ($albumID!='false') {
if ($return['album']!=0) {
$result = $database->query("SELECT public FROM lychee_albums WHERE id = " . $return['album'] . ";");
$return_album = $result->fetch_array();
if ($return_album['public']=="1") $return['public'] = "2";
}
$return['original_album'] = $return['album'];
$return['album'] = $albumID;
$nextPhoto = getNextPhotoID($photoID, $albumID, false);
if ($nextPhoto==$photoID) $return['nextPhoto'] = false;
else $return['nextPhoto'] = $nextPhoto;
$previousPhoto = getPreviousPhotoID($photoID, $albumID, false);
if ($previousPhoto==$photoID) $return['previousPhoto'] = false;
else $return['previousPhoto'] = $previousPhoto;
}
unset($return['album_public']);
return $return;
}
function downloadPhoto($photoID) {
@ -532,26 +594,17 @@ function downloadPhoto($photoID) {
}
function setPhotoPublic($photoID, $url) {
global $database;
$query = "SELECT public, shortlink FROM lychee_photos WHERE id = '$photoID';";
$query = "SELECT public FROM lychee_photos WHERE id = '$photoID';";
$result = $database->query($query);
$row = $result->fetch_object();
if($row->public == 0){
if ($row->public == 0){
$public = 1;
}else{
} else {
$public = 0;
}
if($public==0 || preg_match('/localhost/', $_SERVER['HTTP_REFERER']) || preg_match('\file:\/\/\/', $_SERVER['HTTP_REFERER'])) {
$shortlink = "";
}else{
if($row->shortlink==""){
$shortlink = urlShortner($url);
}else{
$shortlink = $row->shortlink;
}
}
$query = "UPDATE lychee_photos SET public = '$public', shortlink = '$shortlink' WHERE id = '$photoID';";
$query = "UPDATE lychee_photos SET public = '$public' WHERE id = '$photoID';";
$result = $database->query($query);
if(!$result) return false;
if (!$result) return false;
return true;
}
function setPhotoStar($photoID) {
@ -559,7 +612,7 @@ function setPhotoStar($photoID) {
$query = "SELECT star FROM lychee_photos WHERE id = '$photoID';";
$result = $database->query($query);
$row = $result->fetch_object();
if($row->star == 0) {
if ($row->star == 0) {
$star = 1;
} else {
$star = 0;
@ -568,95 +621,95 @@ function setPhotoStar($photoID) {
$result = $database->query($query);
return true;
}
function nextPhoto($photoID, $albumID, $innerCall) {
function getNextPhotoID($photoID, $albumID, $innerCall) {
global $database, $sorting;
if (!$innerCall&&$sorting=="ASC") return previousPhoto($photoID, $albumID, true);
if (!$innerCall&&$sorting=="ASC") return getPreviousPhotoID($photoID, $albumID, true);
switch($albumID) {
case 'f': $query = "SELECT * FROM lychee_photos WHERE id < '$photoID' AND star = '1' ORDER BY id DESC LIMIT 0, 1;";
case 'f': $query = "SELECT id FROM lychee_photos WHERE id < '$photoID' AND star = '1' ORDER BY id DESC LIMIT 0, 1;";
break;
case 's': $query = "SELECT * FROM lychee_photos WHERE id < '$photoID' AND public = '1' ORDER BY id DESC LIMIT 0, 1;";
case 's': $query = "SELECT id FROM lychee_photos WHERE id < '$photoID' AND public = '1' ORDER BY id DESC LIMIT 0, 1;";
break;
default: $query = "SELECT * FROM lychee_photos WHERE id < '$photoID' AND album = '$albumID' ORDER BY id DESC LIMIT 0, 1;";
default: $query = "SELECT id FROM lychee_photos WHERE id < '$photoID' AND album = '$albumID' ORDER BY id DESC LIMIT 0, 1;";
}
$result = $database->query($query);
$return = $result->fetch_array();
if(!$return || ($return==0)) {
if (!$return || ($return==0)) {
switch($albumID) {
case 'f': $query = "SELECT * FROM lychee_photos WHERE star = '1' ORDER BY id DESC LIMIT 0, 1;";
case 'f': $query = "SELECT id FROM lychee_photos WHERE star = '1' ORDER BY id DESC LIMIT 0, 1;";
break;
case 's': $query = "SELECT * FROM lychee_photos WHERE public = '1' ORDER BY id DESC LIMIT 0, 1;";
case 's': $query = "SELECT id FROM lychee_photos WHERE public = '1' ORDER BY id DESC LIMIT 0, 1;";
break;
default: $query = "SELECT * FROM lychee_photos WHERE album = '$albumID' ORDER BY id DESC LIMIT 0, 1;";
default: $query = "SELECT id FROM lychee_photos WHERE album = '$albumID' ORDER BY id DESC LIMIT 0, 1;";
}
$result = $database->query($query);
$return = $result->fetch_array();
}
return $return;
return $return['id'];
}
function previousPhoto($photoID, $albumID, $innerCall) {
function getPreviousPhotoID($photoID, $albumID, $innerCall) {
global $database, $sorting;
if (!$innerCall&&$sorting=="ASC") return nextPhoto($photoID, $albumID, true);
if (!$innerCall&&$sorting=="ASC") return getNextPhotoID($photoID, $albumID, true);
switch($albumID) {
case 'f': $query = "SELECT * FROM lychee_photos WHERE id > '$photoID' AND star = '1' ORDER BY id LIMIT 0, 1;";
case 'f': $query = "SELECT id FROM lychee_photos WHERE id > '$photoID' AND star = '1' ORDER BY id LIMIT 0, 1;";
break;
case 's': $query = "SELECT * FROM lychee_photos WHERE id > '$photoID' AND public = '1' ORDER BY id LIMIT 0, 1;";
case 's': $query = "SELECT id FROM lychee_photos WHERE id > '$photoID' AND public = '1' ORDER BY id LIMIT 0, 1;";
break;
default: $query = "SELECT * FROM lychee_photos WHERE id > '$photoID' AND album = '$albumID' ORDER BY id LIMIT 0, 1;";
default: $query = "SELECT id FROM lychee_photos WHERE id > '$photoID' AND album = '$albumID' ORDER BY id LIMIT 0, 1;";
}
$result = $database->query($query);
$return = $result->fetch_array();
if(!$return || ($return==0)) {
if (!$return || ($return==0)) {
switch($albumID) {
case 'f': $query = "SELECT * FROM lychee_photos WHERE star = '1' ORDER BY id LIMIT 0, 1;";
case 'f': $query = "SELECT id FROM lychee_photos WHERE star = '1' ORDER BY id LIMIT 0, 1;";
break;
case 's': $query = "SELECT * FROM lychee_photos WHERE public = '1' ORDER BY id LIMIT 0, 1;";
case 's': $query = "SELECT id FROM lychee_photos WHERE public = '1' ORDER BY id LIMIT 0, 1;";
break;
default: $query = "SELECT * FROM lychee_photos WHERE album = '$albumID' ORDER BY id LIMIT 0, 1;";
default: $query = "SELECT id FROM lychee_photos WHERE album = '$albumID' ORDER BY id LIMIT 0, 1;";
}
$result = $database->query($query);
$return = $result->fetch_array();
}
return $return;
return $return['id'];
}
function setAlbum($photoID, $newAlbum) {
global $database;
$query = "UPDATE lychee_photos SET album = '$newAlbum' WHERE id = '$photoID';";
$result = $database->query($query);
if(!$result) return false;
if (!$result) return false;
else return true;
}
function setPhotoTitle($photoID, $title) {
global $database;
$title = mysqli_real_escape_string($database, urldecode($title));
if(strlen($title)>30) return false;
if (strlen($title)>30) return false;
$query = "UPDATE lychee_photos SET title = '$title' WHERE id = '$photoID';";
$result = $database->query($query);
if(!$result) return false;
if (!$result) return false;
else return true;
}
function setPhotoDescription($photoID, $description) {
global $database;
$description = mysqli_real_escape_string($database, htmlentities($description));
if(strlen($description)>160) return false;
if (strlen($description)>160) return false;
$query = "UPDATE lychee_photos SET description = '$description' WHERE id = '$photoID';";
$result = $database->query($query);
if(!$result) return false;
if (!$result) return false;
return true;
}
function deletePhoto($photoID) {
global $database;
$query = "SELECT * FROM lychee_photos WHERE id = '$photoID';";
$result = $database->query($query);
if(!$result) return false;
if (!$result) return false;
$row = $result->fetch_object();
$retinaUrl = explode(".", $row->thumbUrl);
$unlink1 = unlink("../".$row->url);
$unlink2 = unlink("../".$row->thumbUrl);
$unlink3 = unlink("../".$retinaUrl[0].'@2x.'.$retinaUrl[1]);
$unlink1 = unlink("../uploads/big/".$row->url);
$unlink2 = unlink("../uploads/thumb/".$row->thumbUrl);
$unlink3 = unlink("../uploads/thumb/".$retinaUrl[0].'@2x.'.$retinaUrl[1]);
$query = "DELETE FROM lychee_photos WHERE id = '$photoID';";
$result = $database->query($query);
if(!$unlink1 || !$unlink2 || !$unlink3) return false;
if(!$result) return false;
if (!$unlink1 || !$unlink2 || !$unlink3) return false;
if (!$result) return false;
return true;
}
function importPhoto($name, $albumID) {
@ -669,7 +722,7 @@ function importPhoto($name, $albumID) {
$nameFile[0]['tmp_name'] = $tmp_name;
$nameFile[0]['error'] = 0;
$nameFile[0]['size'] = $size;
if(!upload($nameFile, $albumID)) return false;
if (!upload($nameFile, $albumID)) return false;
else return true;
}
function importUrl($url, $albumID) {
@ -685,28 +738,9 @@ function importUrl($url, $albumID) {
}
// Share Functions
function urlShortner($url) {
global $database, $bitlyUsername, $bitlyApi;
if($bitlyUsername==""||$bitlyApi=="") return false;
$url = urlencode($url);
$bitlyAPI = "http://api.bit.ly/shorten?version=2.0.1&format=xml&longUrl=$url&login=$bitlyUsername&apiKey=$bitlyApi";
$data = file_get_contents($bitlyAPI);
$xml = simplexml_load_string($data);
$shortlink = $xml->results->nodeKeyVal->shortUrl;
return $shortlink;
}
function getShortlink($photoID) {
global $database;
$query = "SELECT * FROM lychee_photos WHERE id = '$photoID';";
$result = $database->query($query);
$row = $result->fetch_object();
return $row->shortlink;
}
function facebookHeader($photoID) {
$database = dbConnect();
if(!is_numeric($photoID)) return false;
if (!is_numeric($photoID)) return false;
$query = "SELECT * FROM lychee_photos WHERE id = '$photoID';";
$result = $database->query($query);
$row = $result->fetch_object();
@ -723,7 +757,7 @@ function facebookHeader($photoID) {
function isPhotoPublic($photoID, $password) {
global $database;
$photoID = mysqli_real_escape_string($database, $photoID);
if(is_numeric($photoID)) {
if (is_numeric($photoID)) {
$query = "SELECT * FROM lychee_photos WHERE id = '$photoID';";
} else {
$query = "SELECT * FROM lychee_photos WHERE import_name = '../uploads/import/$photoID';";
@ -731,34 +765,48 @@ function isPhotoPublic($photoID, $password) {
$result = $database->query($query);
$row = $result->fetch_object();
if (!is_numeric($photoID)&&!$row) return true;
if($row->public == 1) return true;
else return isAlbumPublic($row->album, $password);
if ($row->public==1) return true;
else {
$cAP = checkAlbumPassword($row->album, $password);
$iAP = isAlbumPublic($row->album);
if ($iAP&&$cAP) return true;
else return false;
}
}
// Search Function
function search($term) {
global $database, $sorting;
$return["albums"] = "";
$term = mysqli_real_escape_string($database, $term);
$query = "SELECT * FROM lychee_photos WHERE title like '%$term%' OR description like '%$term%';";
$result = $database->query($query);
while($row = $result->fetch_array()) {
$return['photos'][] = $row;
$return['photos'][$row['id']] = $row;
}
$query = "SELECT * FROM lychee_albums WHERE title like '%$term%';";
$result = $database->query($query);
$i=0;
while($row = $result->fetch_array()) {
$return['albums'][$i] = $row;
$query2 = "SELECT thumbUrl FROM lychee_photos WHERE album = '".$row['id']."' ORDER BY id $sorting LIMIT 0, 3;";
while($row = $result->fetch_object()) {
$return["albums"][$row->id]['id'] = $row->id;
$return["albums"][$row->id]['title'] = $row->title;
$return["albums"][$row->id]['public'] = $row->public;
$return["albums"][$row->id]['sysdate'] = $row->sysdate;
if ($row->password=="") $return["albums"][$row->id]['password'] = false;
else $return["albums"][$row->id]['password'] = true;
$query2 = "SELECT thumbUrl FROM lychee_photos WHERE album = '".$row->id."' ORDER BY id $sorting LIMIT 0, 3;";
$result2 = $database->query($query2);
$k = 0;
while($row2 = $result2->fetch_object()){
$return['albums'][$i]["thumb$k"] = $row2->thumbUrl;
$return['albums'][$row->id]["thumb$k"] = $row2->thumbUrl;
$k++;
}
$i++;
}
return $return;
}

View File

@ -8,6 +8,7 @@ require('check.php');
if($error=='') {
if(!$database->query("SELECT `public` FROM `lychee_albums`;")) $database->query("ALTER TABLE `lychee_albums` ADD `public` TINYINT( 1 ) NOT NULL DEFAULT '0'");
if(!$database->query("SELECT `password` FROM `lychee_albums`;")) $database->query("ALTER TABLE `lychee_albums` ADD `password` VARCHAR( 100 ) NULL DEFAULT NULL");
$database->query("UPDATE `lychee_photos` SET url = replace(url, 'uploads/big/', ''), thumbUrl = replace(thumbUrl, 'uploads/thumb/', '')");
echo "\nUpdate complete!";
} else {
echo "\nCould not Update!";

13
readme.md Executable file → Normal file
View File

@ -2,8 +2,8 @@
#### A great looking and easy-to-use Photo-Management-System.
![Lychee ImageView](http://l.electerious.com/uploads/big/13582806160093.png)
![Lychee ImageView](http://l.electerious.com/uploads/big/13582805615704.png)
![Lychee](http://l.electerious.com/uploads/big/13582806160093.png)
![Lychee](http://l.electerious.com/uploads/big/13582805615704.png)
Lychee is a free, easy to use and great looking photo-management-system you can run on your server to manage and share photos. Just download the source and follow the instructions to install Lychee wherever you want.
@ -29,18 +29,15 @@ This shortcuts will help you to use Lychee even faster. [Keyboard Shortcuts &#18
## Browser Support
Lychee supports the latest versions of Google Chrome, Apple Safari and Mozilla Firefox. Photos you share with others can be viewed from every browser. For the best experience we are recommending to use Google Chrome or Apple Safari.
Lychee supports the latest versions of Google Chrome, Apple Safari, Mozilla Firefox and Opera. Photos you share with others can be viewed from every browser. For the best experience we are recommending to use Google Chrome or Apple Safari.
## Update
####From version 1.0/1.1 to 1.2:
####From version 1.0/1.1/1.2 to 1.3:
1. Replace all files, excluding `uploads/`
2. Open `php/config.php` and reconfigure your installation
3. Open `php/update.php` in your browser
####From version 1.2 to 1.2.x:
Replace all files, excluding `uploads/` and `php/config.php`.
## Troubleshooting
If Lychee is not working properly, try to open `php/check.php`. This file will take a look at your configuration and displays all errors it can find. Everything should work if you can see the message "Lychee is ready!".
@ -60,4 +57,4 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.SE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -48,7 +48,7 @@
</header>
<!-- ImageView -->
<div id="image_view"></div>
<div id="imageview"></div>
<!-- Infobox -->
<div id="infobox"></div>
@ -60,4 +60,4 @@
</body>
</html>
</html>>