BIN
dist/main.css
vendored
BIN
dist/main.js
vendored
Executable file → Normal file
BIN
dist/view.js
vendored
@ -1,6 +1,6 @@
|
||||
## v3.1.0
|
||||
|
||||
Released March ??, 2016
|
||||
Released March 29, 2016
|
||||
|
||||
**Warning**: It's no longer possible to update from Lychee versions older than 2.7.
|
||||
|
||||
@ -14,7 +14,8 @@ This updates includes a huge rewrite of the back-end. We are now using namespace
|
||||
|
||||
- `New` Empty titles for albums
|
||||
- `New` Share albums as hidden so they are only viewable with a direct link (#27)
|
||||
- `Improved` Error messages and log output
|
||||
- `New` Log failed and successful login attempts (Thanks @qligier, #382 #246)
|
||||
- `Improved` error messages and log output
|
||||
- `Improved` The search shows albums above photos (#434)
|
||||
- `Improved` Album id now based on the current microtime (#27)
|
||||
- `Improved` Back-end modules and plugins
|
||||
@ -22,6 +23,10 @@ This updates includes a huge rewrite of the back-end. We are now using namespace
|
||||
- `Improved` Default photo title now "Untitled"
|
||||
- `Improved` Move to next photo after after moving a picture (#437)
|
||||
- `Improved` Return to album overview when canceling album password input
|
||||
- `Improved` URL import now accepts photo URLs containing "?" and ":" (Thanks @qligier, #482)
|
||||
- `Improved` Replaced date by strftime to simplify date translations (Thanks @qligier, #461)
|
||||
- `Fixed` Missing icons in Safari 9.1
|
||||
- `Fixed` duplicate uploads (Thanks @qligier, #433)
|
||||
- `Fixed` incorrect escaping when using backslashes
|
||||
- `Fixed` session_start() after sending headers (#433)
|
||||
- `Fixed` error when deleting last open photo in album
|
||||
|
@ -55,4 +55,7 @@ Yes. Lychee uses ImageMagick when available.
|
||||
There's a problem with images compressed by ImageOptim. [Read more.](https://github.com/electerious/Lychee/issues/175#issuecomment-47403992)
|
||||
|
||||
#### How to change the title of the site?
|
||||
[#455](https://github.com/electerious/Lychee/issues/455)
|
||||
[#455](https://github.com/electerious/Lychee/issues/455)
|
||||
|
||||
#### How to reset username and password?
|
||||
Simply delete the whole `lychee_settings` table from the database. Lychee will regenerate it and ask you to enter a new username and password.
|
@ -93,7 +93,7 @@ final class Admin extends Access {
|
||||
Validator::required(isset($_POST['title']), __METHOD__);
|
||||
|
||||
$album = new Album(null);
|
||||
Response::json($album->add($_POST['title']));
|
||||
Response::json($album->add($_POST['title']), JSON_NUMERIC_CHECK);
|
||||
|
||||
}
|
||||
|
||||
@ -231,7 +231,7 @@ final class Admin extends Access {
|
||||
Validator::required(isset($_FILES, $_POST['albumID']), __METHOD__);
|
||||
|
||||
$photo = new Photo(null);
|
||||
Response::json($photo->add($_FILES, $_POST['albumID']));
|
||||
Response::json($photo->add($_FILES, $_POST['albumID']), JSON_NUMERIC_CHECK);
|
||||
|
||||
}
|
||||
|
||||
@ -249,7 +249,7 @@ final class Admin extends Access {
|
||||
Validator::required(isset($_POST['albumID'], $_POST['path']), __METHOD__);
|
||||
|
||||
$import = new Import();
|
||||
echo $import->server($_POST['path'], $_POST['albumID']);
|
||||
Response::json($import->server($_POST['path'], $_POST['albumID']));
|
||||
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ final class Installation extends Access {
|
||||
|
||||
Validator::required(isset($_POST['dbHost'], $_POST['dbUser'], $_POST['dbPassword'], $_POST['dbName'], $_POST['dbTablePrefix']), __METHOD__);
|
||||
|
||||
echo Config::create($_POST['dbHost'], $_POST['dbUser'], $_POST['dbPassword'], $_POST['dbName'], $_POST['dbTablePrefix']);
|
||||
Response::json(Config::create($_POST['dbHost'], $_POST['dbUser'], $_POST['dbPassword'], $_POST['dbName'], $_POST['dbTablePrefix']));
|
||||
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ final class Album {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer|false ID of the created album.
|
||||
* @return string|false ID of the created album.
|
||||
*/
|
||||
public function add($title = 'Untitled') {
|
||||
|
||||
|
@ -42,7 +42,7 @@ $config = "<?php
|
||||
?>";
|
||||
|
||||
// Save file
|
||||
if (file_put_contents(LYCHEE_CONFIG_FILE, $config)===false) return 'Warning: Could not create file!';
|
||||
if (@file_put_contents(LYCHEE_CONFIG_FILE, $config)===false) return 'Warning: Could not create file!';
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -56,7 +56,7 @@ final class Database {
|
||||
$connection = self::connect($host, $user, $password);
|
||||
|
||||
// Check if the connection was successful
|
||||
if ($connection===false) Response::error('' . $connection->connect_error);
|
||||
if ($connection===false) Response::error($connection->connect_error);
|
||||
|
||||
if (self::setCharset($connection)===false) Response::error('Could not set database charset!');
|
||||
|
||||
@ -81,7 +81,7 @@ final class Database {
|
||||
public static function connect($host = 'localhost', $user, $password) {
|
||||
|
||||
// Open a new connection to the MySQL server
|
||||
$connection = new Mysqli($host, $user, $password);
|
||||
$connection = @new Mysqli($host, $user, $password);
|
||||
|
||||
// Check if the connection was successful
|
||||
if ($connection->connect_errno) return false;
|
||||
|
@ -39,7 +39,7 @@ final class Photo {
|
||||
* Creats new photo(s).
|
||||
* Exits on error.
|
||||
* Use $returnOnError if you want to handle errors by your own.
|
||||
* @return boolean Returns true when successful.
|
||||
* @return string|false ID of the added photo.
|
||||
*/
|
||||
public function add(array $files, $albumID = 0, $returnOnError = false) {
|
||||
|
||||
@ -251,7 +251,7 @@ final class Photo {
|
||||
// Call plugins
|
||||
Plugins::get()->activate(__METHOD__, 1, func_get_args());
|
||||
|
||||
return true;
|
||||
return $id;
|
||||
|
||||
}
|
||||
|
||||
|
@ -6,19 +6,19 @@ final class Response {
|
||||
|
||||
public static function warning($msg) {
|
||||
|
||||
exit('Warning: ' . $msg);
|
||||
exit(json_encode('Warning: ' . $msg));
|
||||
|
||||
}
|
||||
|
||||
public static function error($msg) {
|
||||
|
||||
exit('Error: ' . $msg);
|
||||
exit(json_encode('Error: ' . $msg));
|
||||
|
||||
}
|
||||
|
||||
public static function json($str) {
|
||||
public static function json($str, $options = 0) {
|
||||
|
||||
exit(json_encode($str));
|
||||
exit(json_encode($str, $options));
|
||||
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,6 @@ $result = Database::execute($connection, $query, 'update_030100', __LINE__);
|
||||
if ($result===false) Response::error('Could not adjust the length of the album id field!');
|
||||
|
||||
// Set version
|
||||
// if (Database::setVersion($connection, '030100')===false) Response::error('Could not update version of database!');
|
||||
if (Database::setVersion($connection, '030100')===false) Response::error('Could not update version of database!');
|
||||
|
||||
?>
|
@ -26,7 +26,7 @@ define('LYCHEE_URL_UPLOADS_BIG', 'uploads/big/');
|
||||
define('LYCHEE_URL_UPLOADS_MEDIUM', 'uploads/medium/');
|
||||
define('LYCHEE_URL_UPLOADS_THUMB', 'uploads/thumb/');
|
||||
|
||||
function defineTablePrefix($dbTablePrefix = '') {
|
||||
function defineTablePrefix($dbTablePrefix) {
|
||||
|
||||
// This part is wrapped into a function, because it needs to be called
|
||||
// after the config-file has been loaded. Other defines are available
|
||||
@ -34,6 +34,7 @@ function defineTablePrefix($dbTablePrefix = '') {
|
||||
|
||||
// Parse table prefix
|
||||
// Old users do not have the table prefix stored in their config-file
|
||||
if (isset($dbTablePrefix)===false) $dbTablePrefix = '';
|
||||
if ($dbTablePrefix!=='') $dbTablePrefix .= '_';
|
||||
|
||||
// Define tables
|
||||
|
@ -1,5 +1,8 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @return string Generated ID.
|
||||
*/
|
||||
function generateID() {
|
||||
|
||||
// Generate id based on the current microtime
|
||||
@ -8,8 +11,9 @@ function generateID() {
|
||||
// Ensure that the id has a length of 14 chars
|
||||
while(strlen($id)<14) $id .= 0;
|
||||
|
||||
// Return the integer value of the id
|
||||
return intval($id);
|
||||
// Return id as a string. Don't convert the id to an integer
|
||||
// as 14 digits are too big for 32bit PHP versions.
|
||||
return $id;
|
||||
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ paths.view = {
|
||||
],
|
||||
scripts: [
|
||||
'node_modules/jquery/dist/jquery.min.js',
|
||||
'node_modules/basiccontext/dist/basicContext.min.js',
|
||||
'../dist/_view--javascript.js'
|
||||
],
|
||||
svg: [
|
||||
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
@ -1 +1 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"><title>Group</title><desc>Created with Sketch.</desc><g sketch:type="MSShapeGroup" fill="none"><path d="M0 0h16v16h-16v-16z" id="Shape" fill="#444"/><path id="Rectangle-path" stroke="#aaa" d="M4 4h5v5h-5z"/><path d="M6 6h8v7h-8v-7z" fill="#444"/><path stroke="#aaa" d="M7 7h5v5h-5z"/></g></svg>
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><g fill="none"><path d="M0 0h16v16h-16v-16z" fill="#444"/><path stroke="#aaa" d="M4 4h5v5h-5z"/><path d="M6 6h8v7h-8v-7z" fill="#444"/><path stroke="#aaa" d="M7 7h5v5h-5z"/></g></svg>
|
Before Width: | Height: | Size: 432 B After Width: | Height: | Size: 266 B |
@ -1 +1 @@
|
||||
<svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"><title>Group</title><desc>Created with Sketch.</desc><g sketch:type="MSLayerGroup" fill="none"><path d="M0 0h200v200h-200v-200z" id="Shape" fill="#222" sketch:type="MSShapeGroup"/><g sketch:type="MSShapeGroup"><path id="Rectangle-path" stroke="#B4B4B4" stroke-width="4" d="M68 52h50v42h-50z"/><path d="M79 63h44v36h-44v-36z" fill="#222"/><path stroke="#B4B4B4" stroke-width="4" d="M88 72h50v42h-50z"/></g></g></svg>
|
||||
<svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"><g fill="none"><path d="M0 0h200v200h-200v-200z" fill="#222"/><g><path stroke="#B4B4B4" stroke-width="4" d="M68 52h50v42h-50z"/><path d="M79 63h44v36h-44v-36z" fill="#222"/><path stroke="#B4B4B4" stroke-width="4" d="M88 72h50v42h-50z"/></g></g></svg>
|
Before Width: | Height: | Size: 557 B After Width: | Height: | Size: 337 B |
@ -1 +1 @@
|
||||
<svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"><title>Group</title><desc>Created with Sketch.</desc><g sketch:type="MSLayerGroup" fill="none"><path d="M0 0h200v200h-200v-200z" id="Shape" fill="#222" sketch:type="MSShapeGroup"/><path d="M100.5 49c-10.45 0-19 8.614-19 19.143v9.571h-9.5v38.286h57v-38.286h-9.5v-9.571c0-10.529-8.55-19.143-19-19.143zm0 9.571c5.32 0 9.5 4.211 9.5 9.571v9.571h-19v-9.571c0-5.36 4.18-9.571 9.5-9.571z" fill="#B4B4B4" sketch:type="MSShapeGroup"/></g></svg>
|
||||
<svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg"><g fill="none"><path d="M0 0h200v200h-200v-200z" id="Shape" fill="#222"/><path d="M100.5 49c-10.45 0-19 8.614-19 19.143v9.571h-9.5v38.286h57v-38.286h-9.5v-9.571c0-10.529-8.55-19.143-19-19.143zm0 9.571c5.32 0 9.5 4.211 9.5 9.571v9.571h-19v-9.571c0-5.36 4.18-9.571 9.5-9.571z" fill="#B4B4B4"/></g></svg>
|
Before Width: | Height: | Size: 577 B After Width: | Height: | Size: 388 B |
70
src/npm-shrinkwrap.json
generated
@ -32,6 +32,11 @@
|
||||
"from": "ansi-styles@>=2.1.0 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.0.tgz"
|
||||
},
|
||||
"any-promise": {
|
||||
"version": "1.1.0",
|
||||
"from": "any-promise@>=1.1.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.1.0.tgz"
|
||||
},
|
||||
"archy": {
|
||||
"version": "1.0.0",
|
||||
"from": "archy@>=1.0.0 <2.0.0",
|
||||
@ -42,6 +47,11 @@
|
||||
"from": "are-we-there-yet@>=1.1.2 <1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz"
|
||||
},
|
||||
"arr-flatten": {
|
||||
"version": "1.0.1",
|
||||
"from": "arr-flatten@>=1.0.1 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.0.1.tgz"
|
||||
},
|
||||
"array-differ": {
|
||||
"version": "1.0.0",
|
||||
"from": "array-differ@>=1.0.0 <2.0.0",
|
||||
@ -67,6 +77,11 @@
|
||||
"from": "array-uniq@>=1.0.2 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.2.tgz"
|
||||
},
|
||||
"arrify": {
|
||||
"version": "1.0.1",
|
||||
"from": "arrify@>=1.0.1 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz"
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.3",
|
||||
"from": "asn1@>=0.2.3 <0.3.0",
|
||||
@ -341,8 +356,8 @@
|
||||
"from": "basiccontext@>=3.5.1 <4.0.0"
|
||||
},
|
||||
"basicmodal": {
|
||||
"version": "3.3.3",
|
||||
"from": "basicmodal@>=3.3.3 <4.0.0"
|
||||
"version": "3.3.4",
|
||||
"from": "basicmodal@>=3.3.4 <4.0.0"
|
||||
},
|
||||
"beeper": {
|
||||
"version": "1.1.0",
|
||||
@ -751,6 +766,18 @@
|
||||
"from": "get-stdin@>=4.0.1 <5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz"
|
||||
},
|
||||
"get-value": {
|
||||
"version": "1.3.1",
|
||||
"from": "get-value@>=1.1.5 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-value/-/get-value-1.3.1.tgz",
|
||||
"dependencies": {
|
||||
"lazy-cache": {
|
||||
"version": "0.2.7",
|
||||
"from": "lazy-cache@>=0.2.4 <0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"glob": {
|
||||
"version": "5.0.15",
|
||||
"from": "glob@>=5.0.0 <5.1.0",
|
||||
@ -840,6 +867,18 @@
|
||||
"from": "graceful-readlink@>=1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz"
|
||||
},
|
||||
"group-array": {
|
||||
"version": "0.3.0",
|
||||
"from": "group-array@>=0.3.0 <0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/group-array/-/group-array-0.3.0.tgz",
|
||||
"dependencies": {
|
||||
"kind-of": {
|
||||
"version": "2.0.1",
|
||||
"from": "kind-of@>=2.0.0 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-2.0.1.tgz"
|
||||
}
|
||||
}
|
||||
},
|
||||
"gulp": {
|
||||
"version": "3.9.1",
|
||||
"from": "gulp@>=3.9.1 <4.0.0",
|
||||
@ -880,9 +919,9 @@
|
||||
}
|
||||
},
|
||||
"gulp-inject": {
|
||||
"version": "3.0.0",
|
||||
"from": "gulp-inject@>=3.0.0 <4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gulp-inject/-/gulp-inject-3.0.0.tgz"
|
||||
"version": "4.0.0",
|
||||
"from": "gulp-inject@>=4.0.0 <5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gulp-inject/-/gulp-inject-4.0.0.tgz"
|
||||
},
|
||||
"gulp-load-plugins": {
|
||||
"version": "1.2.0",
|
||||
@ -1074,6 +1113,11 @@
|
||||
"from": "is-builtin-module@>=1.0.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz"
|
||||
},
|
||||
"is-extendable": {
|
||||
"version": "0.1.1",
|
||||
"from": "is-extendable@>=0.1.1 <0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz"
|
||||
},
|
||||
"is-finite": {
|
||||
"version": "1.0.1",
|
||||
"from": "is-finite@>=1.0.0 <2.0.0",
|
||||
@ -1140,9 +1184,9 @@
|
||||
"resolved": "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz"
|
||||
},
|
||||
"jquery": {
|
||||
"version": "2.2.1",
|
||||
"from": "jquery@>=2.2.1 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-2.2.1.tgz"
|
||||
"version": "2.2.3",
|
||||
"from": "jquery@>=2.2.3 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-2.2.3.tgz"
|
||||
},
|
||||
"js-base64": {
|
||||
"version": "2.1.9",
|
||||
@ -1466,6 +1510,11 @@
|
||||
"from": "node-uuid@>=1.4.7 <1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz"
|
||||
},
|
||||
"noncharacters": {
|
||||
"version": "1.1.0",
|
||||
"from": "noncharacters@>=1.1.0 <2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/noncharacters/-/noncharacters-1.1.0.tgz"
|
||||
},
|
||||
"nopt": {
|
||||
"version": "3.0.6",
|
||||
"from": "nopt@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0",
|
||||
@ -1856,6 +1905,11 @@
|
||||
"from": "stream-consume@>=0.1.0 <0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz"
|
||||
},
|
||||
"stream-to-array": {
|
||||
"version": "2.3.0",
|
||||
"from": "stream-to-array@>=2.3.0 <3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/stream-to-array/-/stream-to-array-2.3.0.tgz"
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"from": "string_decoder@>=0.10.0 <0.11.0",
|
||||
|
@ -16,18 +16,18 @@
|
||||
"dependencies": {
|
||||
"babel-preset-es2015": "^6.6.0",
|
||||
"basiccontext": "^3.5.1",
|
||||
"basicmodal": "^3.3.3",
|
||||
"basicmodal": "^3.3.4",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-autoprefixer": "3.1.0",
|
||||
"gulp-babel": "^6.1.2",
|
||||
"gulp-concat": "^2.6.0",
|
||||
"gulp-inject": "^3.0.0",
|
||||
"gulp-inject": "^4.0.0",
|
||||
"gulp-load-plugins": "^1.2.0",
|
||||
"gulp-minify-css": "^1.2.4",
|
||||
"gulp-rimraf": "^0.2.0",
|
||||
"gulp-sass": "^2.2.0",
|
||||
"gulp-uglify": "^1.5.3",
|
||||
"jquery": "^2.2.1",
|
||||
"jquery": "^2.2.3",
|
||||
"mousetrap": "^1.5.3"
|
||||
}
|
||||
}
|
||||
|
@ -116,9 +116,6 @@ album.add = function() {
|
||||
|
||||
api.post('Album::add', params, function(data) {
|
||||
|
||||
// Avoid first album to be true
|
||||
if (data===true) data = 1
|
||||
|
||||
if (data!==false && isNumber(data)) {
|
||||
albums.refresh()
|
||||
lychee.goto(data)
|
||||
@ -512,26 +509,20 @@ album.setPublic = function(albumID, modal, e) {
|
||||
|
||||
album.share = function(service) {
|
||||
|
||||
let link = ''
|
||||
let url = location.href
|
||||
|
||||
switch (service) {
|
||||
case 'twitter':
|
||||
link = `https://twitter.com/share?url=${ encodeURI(url) }`
|
||||
window.open(`https://twitter.com/share?url=${ encodeURI(url) }`)
|
||||
break
|
||||
case 'facebook':
|
||||
link = `http://www.facebook.com/sharer.php?u=${ encodeURI(url) }&t=${ encodeURI(album.json.title) }`
|
||||
window.open(`http://www.facebook.com/sharer.php?u=${ encodeURI(url) }&t=${ encodeURI(album.json.title) }`)
|
||||
break
|
||||
case 'mail':
|
||||
link = `mailto:?subject=${ encodeURI(album.json.title) }&body=${ encodeURI(url) }`
|
||||
break
|
||||
default:
|
||||
link = ''
|
||||
location.href = `mailto:?subject=${ encodeURI(album.json.title) }&body=${ encodeURI(url) }`
|
||||
break
|
||||
}
|
||||
|
||||
if (link!=='') location.href = link
|
||||
|
||||
}
|
||||
|
||||
album.getArchive = function(albumID) {
|
||||
|
@ -26,15 +26,6 @@ api.post = function(fn, params, callback) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Convert 1 to true and an empty string to false
|
||||
if (data==='true') data = true
|
||||
else if (data==='false') data = false
|
||||
|
||||
// Convert to JSON if string start with '{' and ends with '}'
|
||||
if (typeof data==='string' && data.substring(0, 1)==='{' && data.substring(data.length - 1, data.length)==='}') {
|
||||
data = $.parseJSON(data)
|
||||
}
|
||||
|
||||
callback(data)
|
||||
|
||||
}
|
||||
@ -49,7 +40,7 @@ api.post = function(fn, params, callback) {
|
||||
type: 'POST',
|
||||
url: api.path,
|
||||
data: params,
|
||||
dataType: 'text',
|
||||
dataType: 'json',
|
||||
success,
|
||||
error
|
||||
})
|
||||
|
@ -304,10 +304,10 @@ contextMenu.sharePhoto = function(photoID, e) {
|
||||
{ title: build.iconic('twitter', iconClass) + 'Twitter', fn: () => photo.share(photoID, 'twitter') },
|
||||
{ title: build.iconic('facebook', iconClass) + 'Facebook', fn: () => photo.share(photoID, 'facebook') },
|
||||
{ title: build.iconic('envelope-closed') + 'Mail', fn: () => photo.share(photoID, 'mail') },
|
||||
{ title: build.iconic('dropbox', iconClass) + 'Dropbox', fn: () => photo.share(photoID, 'dropbox') },
|
||||
{ title: build.iconic('dropbox', iconClass) + 'Dropbox', visible: lychee.publicMode===false, fn: () => photo.share(photoID, 'dropbox') },
|
||||
{ title: build.iconic('link-intact') + 'Direct Link', fn: () => window.open(photo.getDirectLink()) },
|
||||
{ },
|
||||
{ title: build.iconic('ban') + 'Make Private', fn: () => photo.setPublic(photoID) }
|
||||
{ visible: lychee.publicMode===false },
|
||||
{ title: build.iconic('ban') + 'Make Private', visible: lychee.publicMode===false, fn: () => photo.setPublic(photoID) }
|
||||
]
|
||||
|
||||
basicContext.show(items, e.originalEvent)
|
||||
@ -325,9 +325,9 @@ contextMenu.shareAlbum = function(albumID, e) {
|
||||
{ title: build.iconic('twitter', iconClass) + 'Twitter', fn: () => album.share('twitter') },
|
||||
{ title: build.iconic('facebook', iconClass) + 'Facebook', fn: () => album.share('facebook') },
|
||||
{ title: build.iconic('envelope-closed') + 'Mail', fn: () => album.share('mail') },
|
||||
{ },
|
||||
{ title: build.iconic('pencil') + 'Edit Sharing', fn: () => album.setPublic(albumID, true, e) },
|
||||
{ title: build.iconic('ban') + 'Make Private', fn: () => album.setPublic(albumID, false) }
|
||||
{ visible: lychee.publicMode===false },
|
||||
{ title: build.iconic('pencil') + 'Edit Sharing', visible: lychee.publicMode===false, fn: () => album.setPublic(albumID, true, e) },
|
||||
{ title: build.iconic('ban') + 'Make Private', visible: lychee.publicMode===false, fn: () => album.setPublic(albumID, false) }
|
||||
]
|
||||
|
||||
basicContext.show(items, e.originalEvent)
|
||||
|
@ -236,8 +236,14 @@ lychee.setTitle = function(title, editable) {
|
||||
|
||||
lychee.setMode = function(mode) {
|
||||
|
||||
$('#button_settings, #button_trash_album, #button_share_album, .button_add, .header__divider').remove()
|
||||
$('#button_trash, #button_move, #button_share, #button_star').remove()
|
||||
$('#button_settings, #button_trash_album, .button_add, .header__divider').remove()
|
||||
$('#button_trash, #button_move, #button_star').remove()
|
||||
|
||||
$('#button_share, #button_share_album')
|
||||
.removeClass('button--eye')
|
||||
.addClass('button--share')
|
||||
.find('use')
|
||||
.attr('xlink:href', '#share')
|
||||
|
||||
$(document)
|
||||
.off('click', '.header__title--editable')
|
||||
|
@ -610,18 +610,17 @@ photo.deleteTag = function(photoID, index) {
|
||||
|
||||
photo.share = function(photoID, service) {
|
||||
|
||||
let link = ''
|
||||
let url = photo.getViewLink(photoID)
|
||||
|
||||
switch (service) {
|
||||
case 'twitter':
|
||||
link = `https://twitter.com/share?url=${ encodeURI(url) }`
|
||||
window.open(`https://twitter.com/share?url=${ encodeURI(url) }`)
|
||||
break
|
||||
case 'facebook':
|
||||
link = `http://www.facebook.com/sharer.php?u=${ encodeURI(url) }&t=${ encodeURI(photo.json.title) }`
|
||||
window.open(`http://www.facebook.com/sharer.php?u=${ encodeURI(url) }&t=${ encodeURI(photo.json.title) }`)
|
||||
break
|
||||
case 'mail':
|
||||
link = `mailto:?subject=${ encodeURI(photo.json.title) }&body=${ encodeURI(url) }`
|
||||
location.href = `mailto:?subject=${ encodeURI(photo.json.title) }&body=${ encodeURI(url) }`
|
||||
break
|
||||
case 'dropbox':
|
||||
lychee.loadDropbox(function() {
|
||||
@ -629,13 +628,8 @@ photo.share = function(photoID, service) {
|
||||
Dropbox.save(photo.getDirectLink(), filename)
|
||||
})
|
||||
break
|
||||
default:
|
||||
link = ''
|
||||
break
|
||||
}
|
||||
|
||||
if (link!=='') location.href = link
|
||||
|
||||
}
|
||||
|
||||
photo.getArchive = function(photoID) {
|
||||
|
@ -36,7 +36,7 @@ settings.createConfig = function() {
|
||||
if (data!==true) {
|
||||
|
||||
// Connection failed
|
||||
if (data.indexOf('Warning: Connection failed!')!==-1) {
|
||||
if (data==='Warning: Connection failed!') {
|
||||
|
||||
basicModal.show({
|
||||
body: '<p>Unable to connect to host database because access was denied. Double-check your host, username and password and ensure that access from your current location is permitted.</p>',
|
||||
@ -53,7 +53,7 @@ settings.createConfig = function() {
|
||||
}
|
||||
|
||||
// Creation failed
|
||||
if (data.indexOf('Warning: Creation failed!')!==-1) {
|
||||
if (data==='Warning: Creation failed!') {
|
||||
|
||||
basicModal.show({
|
||||
body: '<p>Unable to create the database. Double-check your host, username and password and ensure that the specified user has the rights to modify and add content to the database.</p>',
|
||||
@ -70,7 +70,7 @@ settings.createConfig = function() {
|
||||
}
|
||||
|
||||
// Could not create file
|
||||
if (data.indexOf('Warning: Could not create file!')!==-1) {
|
||||
if (data==='Warning: Could not create file!') {
|
||||
|
||||
basicModal.show({
|
||||
body: "<p>Unable to save this configuration. Permission denied in <b>'data/'</b>. Please set the read, write and execute rights for others in <b>'data/'</b> and <b>'uploads/'</b>. Take a look at the readme for more information.</p>",
|
||||
|
@ -93,13 +93,22 @@ upload.start = {
|
||||
|
||||
xhr.onload = function() {
|
||||
|
||||
let data = null
|
||||
let wait = false
|
||||
let errorText = ''
|
||||
|
||||
const isNumber = (n) => (!isNaN(parseFloat(n)) && isFinite(n))
|
||||
|
||||
try {
|
||||
data = JSON.parse(xhr.responseText)
|
||||
} catch(e) {
|
||||
data = ''
|
||||
}
|
||||
|
||||
file.ready = true
|
||||
|
||||
// Set status
|
||||
if (xhr.status===200 && xhr.responseText==='true') {
|
||||
if (xhr.status===200 && isNumber(data)) {
|
||||
|
||||
// Success
|
||||
$('.basicModal .rows .row:nth-child(' + (file.num + 1) + ') .status')
|
||||
@ -108,9 +117,9 @@ upload.start = {
|
||||
|
||||
} else {
|
||||
|
||||
if (xhr.responseText.substr(0, 6)==='Error:') {
|
||||
if (data.substr(0, 6)==='Error:') {
|
||||
|
||||
errorText = xhr.responseText.substr(6) + ' Please take a look at the console of your browser for further details.'
|
||||
errorText = data.substr(6) + ' Please take a look at the console of your browser for further details.'
|
||||
error = true
|
||||
|
||||
// Error Status
|
||||
@ -118,9 +127,12 @@ upload.start = {
|
||||
.html('Failed')
|
||||
.addClass('error')
|
||||
|
||||
} else if (xhr.responseText.substr(0, 8)==='Warning:') {
|
||||
// Throw error
|
||||
if (error===true) lychee.error('Upload failed. Server returned an error!', xhr, data)
|
||||
|
||||
errorText = xhr.responseText.substr(8)
|
||||
} else if (data.substr(0, 8)==='Warning:') {
|
||||
|
||||
errorText = data.substr(8)
|
||||
warning = true
|
||||
|
||||
// Warning Status
|
||||
@ -128,6 +140,9 @@ upload.start = {
|
||||
.html('Skipped')
|
||||
.addClass('warning')
|
||||
|
||||
// Throw error
|
||||
if (error===true) lychee.error('Upload failed. Server returned a warning!', xhr, data)
|
||||
|
||||
} else {
|
||||
|
||||
errorText = 'Server returned an unknown response. Please take a look at the console of your browser for further details.'
|
||||
@ -138,15 +153,15 @@ upload.start = {
|
||||
.html('Failed')
|
||||
.addClass('error')
|
||||
|
||||
// Throw error
|
||||
if (error===true) lychee.error('Upload failed. Server returned an unkown error!', xhr, data)
|
||||
|
||||
}
|
||||
|
||||
$('.basicModal .rows .row:nth-child(' + (file.num + 1) + ') p.notice')
|
||||
.html(errorText)
|
||||
.show()
|
||||
|
||||
// Throw error
|
||||
if (error===true) lychee.error('Upload failed. Server returned the status code ' + xhr.status + '!', xhr, xhr.responseText)
|
||||
|
||||
}
|
||||
|
||||
// Check if there are file which are not finished
|
||||
@ -206,8 +221,8 @@ upload.start = {
|
||||
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
|
||||
files[i].num = i
|
||||
files[i].ready = false
|
||||
files[i].num = i
|
||||
files[i].ready = false
|
||||
|
||||
if (i < files.length-1) files[i].next = files[i + 1]
|
||||
else files[i].next = null
|
||||
@ -242,7 +257,7 @@ upload.start = {
|
||||
basicModal.close()
|
||||
|
||||
files[0] = {
|
||||
name : data.link
|
||||
name: data.link
|
||||
}
|
||||
|
||||
upload.show('Importing URL', files, function() {
|
||||
@ -321,7 +336,7 @@ upload.start = {
|
||||
let files = []
|
||||
|
||||
files[0] = {
|
||||
name : data.path
|
||||
name: data.path
|
||||
}
|
||||
|
||||
upload.show('Importing from server', files, function() {
|
||||
|
@ -3,21 +3,12 @@
|
||||
* @copyright 2015 by Tobias Reich
|
||||
*/
|
||||
|
||||
// Sub-implementation of Lychee -------------------------------------------------------------- //
|
||||
// Sub-implementation of lychee -------------------------------------------------------------- //
|
||||
|
||||
let lychee = {}
|
||||
|
||||
lychee.content = $('.content')
|
||||
|
||||
lychee.getEventName = function() {
|
||||
|
||||
let touchendSupport = (/Android|iPhone|iPad|iPod/i).test(navigator.userAgent || navigator.vendor || window.opera) && ('ontouchend' in document.documentElement)
|
||||
let eventName = (touchendSupport===true ? 'touchend' : 'click')
|
||||
|
||||
return eventName
|
||||
|
||||
}
|
||||
|
||||
lychee.escapeHTML = function(html = '') {
|
||||
|
||||
// Ensure that html is a string
|
||||
@ -69,31 +60,76 @@ lychee.html = function(literalSections, ...substs) {
|
||||
|
||||
}
|
||||
|
||||
// Sub-implementation of photo -------------------------------------------------------------- //
|
||||
|
||||
let photo = {}
|
||||
|
||||
photo.share = function(photoID, service) {
|
||||
|
||||
let url = location.toString()
|
||||
|
||||
switch (service) {
|
||||
case 'twitter':
|
||||
window.open(`https://twitter.com/share?url=${ encodeURI(url) }`)
|
||||
break
|
||||
case 'facebook':
|
||||
window.open(`http://www.facebook.com/sharer.php?u=${ encodeURI(url) }`)
|
||||
break
|
||||
case 'mail':
|
||||
location.href = `mailto:?subject=&body=${ encodeURI(url) }`
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
photo.getDirectLink = function() {
|
||||
|
||||
return $('#imageview img').attr('src').replace(/"/g,'').replace(/url\(|\)$/ig, '')
|
||||
|
||||
}
|
||||
|
||||
// Sub-implementation of contextMenu -------------------------------------------------------------- //
|
||||
|
||||
let contextMenu = {}
|
||||
|
||||
contextMenu.sharePhoto = function(photoID, e) {
|
||||
|
||||
let iconClass = 'ionicons'
|
||||
|
||||
let items = [
|
||||
{ title: build.iconic('twitter', iconClass) + 'Twitter', fn: () => photo.share(photoID, 'twitter') },
|
||||
{ title: build.iconic('facebook', iconClass) + 'Facebook', fn: () => photo.share(photoID, 'facebook') },
|
||||
{ title: build.iconic('envelope-closed') + 'Mail', fn: () => photo.share(photoID, 'mail') },
|
||||
{ title: build.iconic('link-intact') + 'Direct Link', fn: () => window.open(photo.getDirectLink(), '_newtab') }
|
||||
]
|
||||
|
||||
basicContext.show(items, e.originalEvent)
|
||||
|
||||
}
|
||||
|
||||
// Main -------------------------------------------------------------- //
|
||||
|
||||
let loadingBar = { show() {}, hide() {} },
|
||||
imageview = $('#imageview')
|
||||
let loadingBar = { show() {}, hide() {} }
|
||||
let imageview = $('#imageview')
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
// Event Name
|
||||
let eventName = lychee.getEventName()
|
||||
// Save ID of photo
|
||||
let photoID = gup('p')
|
||||
|
||||
// Set API error handler
|
||||
api.onError = error
|
||||
|
||||
// Infobox
|
||||
header.dom('#button_info').on(eventName, sidebar.toggle)
|
||||
|
||||
// Direct Link
|
||||
header.dom('#button_direct').on(eventName, function() {
|
||||
|
||||
let link = $('#imageview img').attr('src').replace(/"/g,'').replace(/url\(|\)$/ig, '')
|
||||
window.open(link, '_newtab')
|
||||
|
||||
// Share
|
||||
header.dom('#button_share').on('click', function(e) {
|
||||
contextMenu.sharePhoto(photoID, e)
|
||||
})
|
||||
|
||||
loadPhotoInfo(gup('p'))
|
||||
// Infobox
|
||||
header.dom('#button_info').on('click', sidebar.toggle)
|
||||
|
||||
// Load photo
|
||||
loadPhotoInfo(photoID)
|
||||
|
||||
})
|
||||
|
||||
|
@ -12,7 +12,6 @@
|
||||
&__item {
|
||||
margin-bottom: 2px;
|
||||
font-size: 14px;
|
||||
text-shadow: $shadowLight;
|
||||
|
||||
&--separator {
|
||||
margin: 4px 0;
|
||||
|
@ -57,10 +57,10 @@
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
background: #222;
|
||||
color: #222;
|
||||
box-shadow: 0 2px 5px black(.5);
|
||||
border: 1px solid white(.5);
|
||||
transition: opacity .3s ease-out, transform .3s ease-out, border-color .3s ease-out;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
&:hover img,
|
||||
@ -146,7 +146,6 @@
|
||||
margin: 0 5px 0 0;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
filter: drop-shadow(0 1px 3px black(.4));
|
||||
}
|
||||
|
||||
.album img[data-overlay='false'] + .overlay h1,
|
||||
@ -185,7 +184,6 @@
|
||||
fill: #fff;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
filter: drop-shadow($shadowLight);
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,7 +223,6 @@
|
||||
left: 50%;
|
||||
padding-top: 20px;
|
||||
color: white(.35);
|
||||
text-shadow: 0 -1px 0 black(.4);
|
||||
text-align: center;
|
||||
transform: translateX(-50%) translateY(-50%);
|
||||
|
||||
@ -234,7 +231,6 @@
|
||||
margin: 0 0 10px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
filter: drop-shadow(0 -1px 0 black(.4));
|
||||
}
|
||||
|
||||
p {
|
||||
|
@ -95,6 +95,8 @@
|
||||
|
||||
&--eye.active .iconic { fill: #ff9737; }
|
||||
|
||||
&--share .iconic { height: 18px; }
|
||||
|
||||
&--info.active .iconic { fill: $colorBlue; }
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,6 @@
|
||||
width: auto;
|
||||
height: auto;
|
||||
transition: top .3s, right .3s, bottom .3s, left .3s, max-width .3s, max-height .3s;
|
||||
will-change: transform;
|
||||
|
||||
animation-name: zoomIn;
|
||||
animation-duration: .3s;
|
||||
@ -105,7 +104,6 @@
|
||||
|
||||
.iconic {
|
||||
fill: white(.8);
|
||||
filter: drop-shadow(0 1px 0 black(.4));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,6 @@
|
||||
color: white(.9);
|
||||
font-size: 14px;
|
||||
text-align: left;
|
||||
text-shadow: $shadow;
|
||||
line-height: 20px;
|
||||
|
||||
b {
|
||||
@ -56,7 +55,6 @@
|
||||
padding: 13px 0 15px;
|
||||
background: black(.02);
|
||||
color: white(.5);
|
||||
text-shadow: $shadow;
|
||||
border-top: 1px solid black(.2);
|
||||
box-shadow: inset 0 1px 0 white(.02);
|
||||
cursor: default;
|
||||
@ -85,7 +83,6 @@
|
||||
width: 100%;
|
||||
background-color: transparent;
|
||||
color: #fff;
|
||||
text-shadow: $shadow;
|
||||
border: none;
|
||||
// Do not use rgba() for border-bottom
|
||||
// to avoid a blurry line in Safari on non-retina screens
|
||||
@ -116,7 +113,6 @@
|
||||
color: white(1);
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
text-shadow: $shadow;
|
||||
}
|
||||
|
||||
label input {
|
||||
@ -258,7 +254,6 @@
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
text-shadow: $shadow;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
@ -92,6 +92,7 @@
|
||||
table {
|
||||
float: left;
|
||||
margin: 10px 0 15px 20px;
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
|
||||
table tr td {
|
||||
|
@ -12,8 +12,7 @@
|
||||
}
|
||||
|
||||
// Properties -------------------------------------------------------------- //
|
||||
$shadowLight : 0 -1px 0 black(.1);
|
||||
$shadow : 0 -1px 0 black(.2);
|
||||
$shadow: 0 -1px 0 black(.2);
|
||||
|
||||
// Colors ------------------------------------------------------------------ //
|
||||
$colorBlue : #2293EC;
|
||||
|
6
view.php
@ -48,12 +48,12 @@
|
||||
|
||||
<a class="header__title"></a>
|
||||
|
||||
<a class="button button--share" id="button_share" title="Share Photo">
|
||||
<svg class="iconic"><use xlink:href="#share"></use></svg>
|
||||
</a>
|
||||
<a class="button button--info" id="button_info" title="About Photo">
|
||||
<svg class="iconic"><use xlink:href="#info"></use></svg>
|
||||
</a>
|
||||
<a class="button" id="button_direct" title="Direct Link">
|
||||
<svg class="iconic"><use xlink:href="#link-intact"></use></svg>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
|