commit
2ca41af481
BIN
dist/main.css
vendored
Normal file → Executable file
BIN
dist/main.css
vendored
Normal file → Executable file
Binary file not shown.
BIN
dist/main.js
vendored
Normal file → Executable file
BIN
dist/main.js
vendored
Normal file → Executable file
Binary file not shown.
@ -1,3 +1,10 @@
|
|||||||
|
## v3.0.3
|
||||||
|
|
||||||
|
Released June 28, 2015
|
||||||
|
|
||||||
|
- `New` Skip duplicates on upload (#367, [How to activate](settings.md))
|
||||||
|
- `Fixed` Clicks not recognized when using a mouse on a touchscreen-device (#345)
|
||||||
|
|
||||||
## v3.0.2
|
## v3.0.2
|
||||||
|
|
||||||
Released June 13, 2015
|
Released June 13, 2015
|
||||||
|
@ -34,11 +34,17 @@ Less means an inferiority quality of your thumbs, but faster loading. More means
|
|||||||
|
|
||||||
If `1`, Lychee will check if you are using the latest version. The notice will be displayed beside the version-number when you sign in.
|
If `1`, Lychee will check if you are using the latest version. The notice will be displayed beside the version-number when you sign in.
|
||||||
|
|
||||||
#### Sorting
|
#### Album-Sorting
|
||||||
|
|
||||||
sorting = ORDER BY [row] [ASC|DESC]
|
sortingAlbums = ORDER BY [field] [ASC|DESC]
|
||||||
|
|
||||||
A typical part of a MySQL statement. This string will be appended to mostly every MySQL query.
|
Substring of a MySQL query. This string will be appended to all album-related MySQL queries.
|
||||||
|
|
||||||
|
#### Photo-Sorting
|
||||||
|
|
||||||
|
sortingPhotos = ORDER BY [field] [ASC|DESC]
|
||||||
|
|
||||||
|
Substring of a MySQL query. This string will be appended to all photo-related MySQL queries.
|
||||||
|
|
||||||
#### Dropbox Key
|
#### Dropbox Key
|
||||||
|
|
||||||
@ -57,3 +63,9 @@ If `1`, Lychee will use Imagick when available. Disable [Imagick](http://www.ima
|
|||||||
medium = [0|1]
|
medium = [0|1]
|
||||||
|
|
||||||
If `1`, Lychee will create a second, smaller version of your photo. This feature requires [Imagick](http://www.imagemagick.org) on your server and an activated `imagick` option the the settings table.
|
If `1`, Lychee will create a second, smaller version of your photo. This feature requires [Imagick](http://www.imagemagick.org) on your server and an activated `imagick` option the the settings table.
|
||||||
|
|
||||||
|
#### Skip Duplicates on Upload
|
||||||
|
|
||||||
|
skipDuplicates = [0|1]
|
||||||
|
|
||||||
|
Lychee will skip the upload of existing photos when actived.
|
25
php/database/update_030003.php
Normal file
25
php/database/update_030003.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
###
|
||||||
|
# @name Update to version 3.0.3
|
||||||
|
# @copyright 2015 by Tobias Reich
|
||||||
|
###
|
||||||
|
|
||||||
|
if (!defined('LYCHEE')) exit('Error: Direct access is not allowed!');
|
||||||
|
|
||||||
|
# Add skipDuplicates to settings
|
||||||
|
$query = Database::prepare($database, "SELECT `key` FROM `?` WHERE `key` = 'skipDuplicates' LIMIT 1", array(LYCHEE_TABLE_SETTINGS));
|
||||||
|
$result = $database->query($query);
|
||||||
|
if ($result->num_rows===0) {
|
||||||
|
$query = Database::prepare($database, "INSERT INTO `?` (`key`, `value`) VALUES ('skipDuplicates', '0')", array(LYCHEE_TABLE_SETTINGS));
|
||||||
|
$result = $database->query($query);
|
||||||
|
if (!$result) {
|
||||||
|
Log::error($database, 'update_030003', __LINE__, 'Could not update database (' . $database->error . ')');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set version
|
||||||
|
if (Database::setVersion($database, '030003')===false) return false;
|
||||||
|
|
||||||
|
?>
|
@ -56,7 +56,8 @@ class Database extends Module {
|
|||||||
'020602', #2.6.2
|
'020602', #2.6.2
|
||||||
'020700', #2.7.0
|
'020700', #2.7.0
|
||||||
'030000', #3.0.0
|
'030000', #3.0.0
|
||||||
'030001' #3.0.1
|
'030001', #3.0.1
|
||||||
|
'030003' #3.0.3
|
||||||
);
|
);
|
||||||
|
|
||||||
# For each update
|
# For each update
|
||||||
|
@ -40,7 +40,7 @@ class Photo extends Module {
|
|||||||
public function add($files, $albumID, $description = '', $tags = '') {
|
public function add($files, $albumID, $description = '', $tags = '') {
|
||||||
|
|
||||||
# Check dependencies
|
# Check dependencies
|
||||||
self::dependencies(isset($this->database));
|
self::dependencies(isset($this->database, $this->settings, $files));
|
||||||
|
|
||||||
# Check permissions
|
# Check permissions
|
||||||
if (hasPermissions(LYCHEE_UPLOADS)===false||
|
if (hasPermissions(LYCHEE_UPLOADS)===false||
|
||||||
@ -150,6 +150,15 @@ class Photo extends Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
# Photo already exists
|
||||||
|
# Check if the user wants to skip duplicates
|
||||||
|
if ($this->settings['skipDuplicates']==='1') {
|
||||||
|
Log::notice($this->database, __METHOD__, __LINE__, 'Skipped upload of existing photo because skipDuplicates is activated');
|
||||||
|
exit('Warning: This photo has been skipped because it\'s already in your library.');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Read infos
|
# Read infos
|
||||||
|
@ -2,9 +2,6 @@
|
|||||||
"name": "Lychee",
|
"name": "Lychee",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jQuery": "~2.1.4",
|
|
||||||
"mousetrap": "~1.5.2",
|
|
||||||
"basicContext": "~2.0.9",
|
|
||||||
"basicModal": "~2.0.8"
|
"basicModal": "~2.0.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ paths.view = {
|
|||||||
'./scripts/view/main.js'
|
'./scripts/view/main.js'
|
||||||
],
|
],
|
||||||
scripts: [
|
scripts: [
|
||||||
'bower_components/jQuery/dist/jquery.min.js',
|
'node_modules/jquery/dist/jquery.min.js',
|
||||||
'../dist/_view--javascript.js'
|
'../dist/_view--javascript.js'
|
||||||
],
|
],
|
||||||
svg: [
|
svg: [
|
||||||
@ -84,10 +84,10 @@ paths.main = {
|
|||||||
'./scripts/*.js'
|
'./scripts/*.js'
|
||||||
],
|
],
|
||||||
scripts: [
|
scripts: [
|
||||||
'bower_components/jQuery/dist/jquery.min.js',
|
'node_modules/jquery/dist/jquery.min.js',
|
||||||
'bower_components/mousetrap/mousetrap.min.js',
|
'node_modules/mousetrap/mousetrap.min.js',
|
||||||
'bower_components/mousetrap/plugins/global-bind/mousetrap-global-bind.min.js',
|
'node_modules/mousetrap/plugins/global-bind/mousetrap-global-bind.min.js',
|
||||||
'bower_components/basicContext/dist/basicContext.min.js',
|
'node_modules/basiccontext/dist/basicContext.min.js',
|
||||||
'bower_components/basicModal/dist/basicModal.min.js',
|
'bower_components/basicModal/dist/basicModal.min.js',
|
||||||
'../dist/_main--javascript.js'
|
'../dist/_main--javascript.js'
|
||||||
],
|
],
|
||||||
@ -95,7 +95,7 @@ paths.main = {
|
|||||||
'./styles/*.scss'
|
'./styles/*.scss'
|
||||||
],
|
],
|
||||||
styles: [
|
styles: [
|
||||||
'bower_components/basicContext/src/styles/main.scss',
|
'node_modules/basiccontext/src/styles/main.scss',
|
||||||
'bower_components/basicModal/src/styles/main.scss',
|
'bower_components/basicModal/src/styles/main.scss',
|
||||||
'./styles/main.scss'
|
'./styles/main.scss'
|
||||||
],
|
],
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Lychee",
|
"name": "Lychee",
|
||||||
"version": "3.0.2",
|
"version": "3.0.3",
|
||||||
"description": "Self-hosted photo-management done right.",
|
"description": "Self-hosted photo-management done right.",
|
||||||
"authors": "Tobias Reich <tobias@electerious.com>",
|
"authors": "Tobias Reich <tobias@electerious.com>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -10,15 +10,18 @@
|
|||||||
"url": "https://github.com/electerious/Lychee.git"
|
"url": "https://github.com/electerious/Lychee.git"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"basiccontext": "^3.1.2",
|
||||||
"gulp": "^3.9.0",
|
"gulp": "^3.9.0",
|
||||||
"gulp-autoprefixer": "2.3.1",
|
"gulp-autoprefixer": "2.3.1",
|
||||||
"gulp-babel": "^5.1.0",
|
"gulp-babel": "^5.1.0",
|
||||||
"gulp-concat": "^2.5.2",
|
"gulp-concat": "^2.6.0",
|
||||||
"gulp-inject": "^1.2.0",
|
"gulp-inject": "^1.3.1",
|
||||||
"gulp-load-plugins": "^0.10.0",
|
"gulp-load-plugins": "^1.0.0-rc",
|
||||||
"gulp-minify-css": "^1.1.5",
|
"gulp-minify-css": "^1.2.0",
|
||||||
"gulp-rimraf": "^0.1.1",
|
"gulp-rimraf": "^0.1.1",
|
||||||
"gulp-sass": "^2.0.1",
|
"gulp-sass": "^2.0.3",
|
||||||
"gulp-uglify": "^1.2.0"
|
"gulp-uglify": "^1.2.0",
|
||||||
|
"jquery": "^2.1.4",
|
||||||
|
"mousetrap": "^1.5.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ contextMenu.add = function(e) {
|
|||||||
{ type: 'item', title: build.iconic('folder') + 'New Album', fn: album.add }
|
{ type: 'item', title: build.iconic('folder') + 'New Album', fn: album.add }
|
||||||
];
|
];
|
||||||
|
|
||||||
basicContext.show(items, e);
|
basicContext.show(items, e.originalEvent);
|
||||||
|
|
||||||
upload.notify();
|
upload.notify();
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ contextMenu.settings = function(e) {
|
|||||||
{ type: 'item', title: build.iconic('account-logout') + 'Sign Out', fn: lychee.logout }
|
{ type: 'item', title: build.iconic('account-logout') + 'Sign Out', fn: lychee.logout }
|
||||||
];
|
];
|
||||||
|
|
||||||
basicContext.show(items, e);
|
basicContext.show(items, e.originalEvent);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ contextMenu.album = function(albumID, e) {
|
|||||||
|
|
||||||
$('.album[data-id="' + albumID + '"]').addClass('active');
|
$('.album[data-id="' + albumID + '"]').addClass('active');
|
||||||
|
|
||||||
basicContext.show(items, e, contextMenu.close);
|
basicContext.show(items, e.originalEvent, contextMenu.close);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ contextMenu.albumMulti = function(albumIDs, e) {
|
|||||||
{ type: 'item', title: build.iconic('trash') + 'Delete All', fn: function() { album.delete(albumIDs) } }
|
{ type: 'item', title: build.iconic('trash') + 'Delete All', fn: function() { album.delete(albumIDs) } }
|
||||||
];
|
];
|
||||||
|
|
||||||
basicContext.show(items, e, contextMenu.close);
|
basicContext.show(items, e.originalEvent, contextMenu.close);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ contextMenu.albumTitle = function(albumID, e) {
|
|||||||
|
|
||||||
items.unshift({ type: 'item', title: build.iconic('pencil') + 'Rename', fn: function() { album.setTitle([albumID]) } });
|
items.unshift({ type: 'item', title: build.iconic('pencil') + 'Rename', fn: function() { album.setTitle([albumID]) } });
|
||||||
|
|
||||||
basicContext.show(items, e, contextMenu.close);
|
basicContext.show(items, e.originalEvent, contextMenu.close);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -135,7 +135,7 @@ contextMenu.mergeAlbum = function(albumID, e) {
|
|||||||
|
|
||||||
if (items.length===0) return false;
|
if (items.length===0) return false;
|
||||||
|
|
||||||
basicContext.show(items, e, contextMenu.close);
|
basicContext.show(items, e.originalEvent, contextMenu.close);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ contextMenu.photo = function(photoID, e) {
|
|||||||
|
|
||||||
$('.photo[data-id="' + photoID + '"]').addClass('active');
|
$('.photo[data-id="' + photoID + '"]').addClass('active');
|
||||||
|
|
||||||
basicContext.show(items, e, contextMenu.close);
|
basicContext.show(items, e.originalEvent, contextMenu.close);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ contextMenu.photoMulti = function(photoIDs, e) {
|
|||||||
{ type: 'item', title: build.iconic('trash') + 'Delete All', fn: function() { photo.delete(photoIDs) } }
|
{ type: 'item', title: build.iconic('trash') + 'Delete All', fn: function() { photo.delete(photoIDs) } }
|
||||||
];
|
];
|
||||||
|
|
||||||
basicContext.show(items, e, contextMenu.close);
|
basicContext.show(items, e.originalEvent, contextMenu.close);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,7 +211,7 @@ contextMenu.photoTitle = function(albumID, photoID, e) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
basicContext.show(items, e, contextMenu.close);
|
basicContext.show(items, e.originalEvent, contextMenu.close);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +228,7 @@ contextMenu.photoMore = function(photoID, e) {
|
|||||||
if (!(album.json&&album.json.downloadable&&album.json.downloadable==='1')&&
|
if (!(album.json&&album.json.downloadable&&album.json.downloadable==='1')&&
|
||||||
lychee.publicMode===true) items.splice(1, 1);
|
lychee.publicMode===true) items.splice(1, 1);
|
||||||
|
|
||||||
basicContext.show(items, e);
|
basicContext.show(items, e.originalEvent);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,7 +269,7 @@ contextMenu.move = function(photoIDs, e) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
basicContext.show(items, e, contextMenu.close);
|
basicContext.show(items, e.originalEvent, contextMenu.close);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -294,7 +294,7 @@ contextMenu.sharePhoto = function(photoID, e) {
|
|||||||
{ type: 'item', title: build.iconic('ban') + 'Make Private', fn: function() { photo.setPublic(photoID) } }
|
{ type: 'item', title: build.iconic('ban') + 'Make Private', fn: function() { photo.setPublic(photoID) } }
|
||||||
];
|
];
|
||||||
|
|
||||||
basicContext.show(items, e);
|
basicContext.show(items, e.originalEvent);
|
||||||
$('.basicContext input#link').focus().select();
|
$('.basicContext input#link').focus().select();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -314,7 +314,7 @@ contextMenu.shareAlbum = function(albumID, e) {
|
|||||||
{ type: 'item', title: build.iconic('ban') + 'Make Private', fn: function() { album.setPublic(albumID, false) } }
|
{ type: 'item', title: build.iconic('ban') + 'Make Private', fn: function() { album.setPublic(albumID, false) } }
|
||||||
];
|
];
|
||||||
|
|
||||||
basicContext.show(items, e);
|
basicContext.show(items, e.originalEvent);
|
||||||
$('.basicContext input#link').focus().select();
|
$('.basicContext input#link').focus().select();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|
||||||
/* Event Name */
|
/* Event Name */
|
||||||
var eventName = ('ontouchend' in document.documentElement) ? 'touchend' : 'click';
|
var touchendSupport = (/Android|iPhone|iPad|iPod/i).test(navigator.userAgent || navigator.vendor || window.opera) && ('ontouchend' in document.documentElement),
|
||||||
|
eventName = (touchendSupport===true ? 'touchend' : 'click');
|
||||||
|
|
||||||
/* Set API error handler */
|
/* Set API error handler */
|
||||||
api.onError = lychee.error;
|
api.onError = lychee.error;
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
lychee = {
|
lychee = {
|
||||||
|
|
||||||
title: document.title,
|
title: document.title,
|
||||||
version: '3.0.2',
|
version: '3.0.3',
|
||||||
version_code: '030002',
|
version_code: '030003',
|
||||||
|
|
||||||
update_path: 'http://lychee.electerious.com/version/index.php',
|
update_path: 'http://lychee.electerious.com/version/index.php',
|
||||||
updateURL: 'https://github.com/electerious/Lychee',
|
updateURL: 'https://github.com/electerious/Lychee',
|
||||||
|
@ -44,6 +44,7 @@ upload.start = {
|
|||||||
|
|
||||||
var albumID = album.getID(),
|
var albumID = album.getID(),
|
||||||
error = false,
|
error = false,
|
||||||
|
warning = false,
|
||||||
process = function(files, file) {
|
process = function(files, file) {
|
||||||
|
|
||||||
var formData = new FormData(),
|
var formData = new FormData(),
|
||||||
@ -56,12 +57,18 @@ upload.start = {
|
|||||||
|
|
||||||
$('#upload_files').val('');
|
$('#upload_files').val('');
|
||||||
|
|
||||||
if (error===false) {
|
if (error===false&&warning===false) {
|
||||||
|
|
||||||
// Success
|
// Success
|
||||||
basicModal.close();
|
basicModal.close();
|
||||||
upload.notify('Upload complete');
|
upload.notify('Upload complete');
|
||||||
|
|
||||||
|
} else if (error===false&&warning===true) {
|
||||||
|
|
||||||
|
// Warning
|
||||||
|
$('.basicModal #basicModal__action.hidden').show();
|
||||||
|
upload.notify('Upload complete');
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Error
|
// Error
|
||||||
@ -130,23 +137,44 @@ upload.start = {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Error
|
if (xhr.responseText.substr(0, 6)==='Error:') {
|
||||||
$('.basicModal .rows .row:nth-child(' + (file.num+1) + ') .status')
|
|
||||||
.html('Error')
|
|
||||||
.addClass('error');
|
|
||||||
|
|
||||||
if (xhr.responseText.substr(0, 6)==='Error:') errorText = xhr.responseText.substr(6) + ' Please take a look at the console of your browser for further details.';
|
errorText = xhr.responseText.substr(6) + ' Please take a look at the console of your browser for further details.';
|
||||||
else errorText = 'Server returned an unknown response. Please take a look at the console of your browser for further details.';
|
error = true;
|
||||||
|
|
||||||
|
// Error Status
|
||||||
|
$('.basicModal .rows .row:nth-child(' + (file.num+1) + ') .status')
|
||||||
|
.html('Failed')
|
||||||
|
.addClass('error');
|
||||||
|
|
||||||
|
} else if (xhr.responseText.substr(0, 8)==='Warning:') {
|
||||||
|
|
||||||
|
errorText = xhr.responseText.substr(8);
|
||||||
|
warning = true;
|
||||||
|
|
||||||
|
// Warning Status
|
||||||
|
$('.basicModal .rows .row:nth-child(' + (file.num+1) + ') .status')
|
||||||
|
.html('Skipped')
|
||||||
|
.addClass('warning');
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
errorText = 'Server returned an unknown response. Please take a look at the console of your browser for further details.';
|
||||||
|
error = true;
|
||||||
|
|
||||||
|
// Error Status
|
||||||
|
$('.basicModal .rows .row:nth-child(' + (file.num+1) + ') .status')
|
||||||
|
.html('Failed')
|
||||||
|
.addClass('error');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
$('.basicModal .rows .row:nth-child(' + (file.num+1) + ') p.notice')
|
$('.basicModal .rows .row:nth-child(' + (file.num+1) + ') p.notice')
|
||||||
.html(errorText)
|
.html(errorText)
|
||||||
.show();
|
.show();
|
||||||
|
|
||||||
// Set global error
|
|
||||||
error = true;
|
|
||||||
|
|
||||||
// Throw error
|
// Throw error
|
||||||
lychee.error('Upload failed. Server returned the status code ' + xhr.status + '!', xhr, xhr.responseText);
|
if (error===true) lychee.error('Upload failed. Server returned the status code ' + xhr.status + '!', xhr, xhr.responseText);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,11 +301,14 @@
|
|||||||
animation-iteration-count: infinite;
|
animation-iteration-count: infinite;
|
||||||
|
|
||||||
&.error,
|
&.error,
|
||||||
|
&.warning,
|
||||||
&.success { animation: none; }
|
&.success { animation: none; }
|
||||||
|
|
||||||
&.error { color: rgb(213, 24, 24); }
|
&.error { color: rgb(233, 42, 0); }
|
||||||
|
|
||||||
&.success { color: rgb(42, 213, 0); }
|
&.warning { color: rgb(228, 233, 0); }
|
||||||
|
|
||||||
|
&.success { color: rgb(126, 233, 0); }
|
||||||
}
|
}
|
||||||
|
|
||||||
p.notice {
|
p.notice {
|
||||||
|
Loading…
Reference in New Issue
Block a user