commit
d4c724b02c
BIN
dist/main.css
vendored
BIN
dist/main.css
vendored
Binary file not shown.
BIN
dist/main.js
vendored
BIN
dist/main.js
vendored
Binary file not shown.
BIN
dist/view.js
vendored
BIN
dist/view.js
vendored
Binary file not shown.
@ -1,6 +1,15 @@
|
||||
## v3.0.1
|
||||
|
||||
Released May 24, 2015
|
||||
|
||||
- `New` Album Sorting (Thanks @ophian, #98)
|
||||
- `New` Identifier to prevent login of multiple instances of lychee (#344)
|
||||
- `Improved` Albums and photos now can have a title with up to 50 chars (#332)
|
||||
- `Fixed` Removing last Tag from photo not possible in Firefox (#269)
|
||||
|
||||
## v3.0.0
|
||||
|
||||
Released April 6, 2015
|
||||
Released May 6, 2015
|
||||
|
||||
**Warning**: You need to enter a new username and password when upgrading from a previous version. Your installation is accessible for everyone till you enter a new login by visiting your Lychee. Both fields are now stored in a secure way. Legacy md5 code has been removed.
|
||||
|
||||
|
@ -279,9 +279,14 @@ class Admin extends Access {
|
||||
|
||||
private function setSorting() {
|
||||
|
||||
Module::dependencies(isset($_POST['type'], $_POST['order']));
|
||||
Module::dependencies(isset($_POST['typeAlbums'], $_POST['orderAlbums'], $_POST['typePhotos'], $_POST['orderPhotos']));
|
||||
$this->settings = new Settings($this->database);
|
||||
echo $this->settings->setSorting($_POST['type'], $_POST['order']);
|
||||
|
||||
$sA = $this->settings->setSortingAlbums($_POST['typeAlbums'], $_POST['orderAlbums']);
|
||||
$sP = $this->settings->setSortingPhotos($_POST['typePhotos'], $_POST['orderPhotos']);
|
||||
|
||||
if ($sA===true&&$sP===true) echo true;
|
||||
else echo false;
|
||||
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,8 @@ if (!empty($_POST['function'])||!empty($_GET['function'])) {
|
||||
if (isset($_POST['function'])) $fn = $_POST['function'];
|
||||
else $fn = $_GET['function'];
|
||||
|
||||
if (isset($_SESSION['login'])&&$_SESSION['login']==true) {
|
||||
if ((isset($_SESSION['login'])&&$_SESSION['login']===true)&&
|
||||
(isset($_SESSION['identifier'])&&$_SESSION['identifier']===$settings['identifier'])) {
|
||||
|
||||
###
|
||||
# Admin Access
|
||||
|
@ -4,12 +4,12 @@
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `?` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`title` varchar(50) NOT NULL,
|
||||
`title` varchar(100) NOT NULL DEFAULT '',
|
||||
`description` varchar(1000) DEFAULT '',
|
||||
`sysstamp` int(11) NOT NULL,
|
||||
`public` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`visible` tinyint(1) NOT NULL DEFAULT '1',
|
||||
`downloadable` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`password` varchar(100) DEFAULT '',
|
||||
`password` varchar(100) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
|
@ -4,7 +4,7 @@
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `?` (
|
||||
`id` bigint(14) NOT NULL,
|
||||
`title` varchar(50) NOT NULL,
|
||||
`title` varchar(100) NOT NULL,
|
||||
`description` varchar(1000) DEFAULT '',
|
||||
`url` varchar(100) NOT NULL,
|
||||
`tags` varchar(1000) NOT NULL DEFAULT '',
|
||||
|
@ -9,6 +9,10 @@ VALUES
|
||||
('password',''),
|
||||
('thumbQuality','90'),
|
||||
('checkForUpdates','1'),
|
||||
('sorting','ORDER BY id DESC'),
|
||||
('sortingPhotos','ORDER BY id DESC'),
|
||||
('sortingAlbums','ORDER BY id DESC'),
|
||||
('medium','1'),
|
||||
('imagick','1'),
|
||||
('dropboxKey',''),
|
||||
('identifier',''),
|
||||
('plugins','');
|
70
php/database/update_030001.php
Normal file
70
php/database/update_030001.php
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
###
|
||||
# @name Update to version 3.0.1
|
||||
# @copyright 2015 by Tobias Reich
|
||||
###
|
||||
|
||||
if (!defined('LYCHEE')) exit('Error: Direct access is not allowed!');
|
||||
|
||||
# Change length of photo title
|
||||
$query = Database::prepare($database, "ALTER TABLE `?` CHANGE `title` `title` VARCHAR( 100 ) NOT NULL DEFAULT ''", array(LYCHEE_TABLE_PHOTOS));
|
||||
$result = $database->query($query);
|
||||
if (!$result) {
|
||||
Log::error($database, 'update_030001', __LINE__, 'Could not update database (' . $database->error . ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
# Change length of album title
|
||||
$query = Database::prepare($database, "ALTER TABLE `?` CHANGE `title` `title` VARCHAR( 100 ) NOT NULL DEFAULT ''", array(LYCHEE_TABLE_ALBUMS));
|
||||
$result = $database->query($query);
|
||||
if (!$result) {
|
||||
Log::error($database, 'update_030001', __LINE__, 'Could not update database (' . $database->error . ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
# Add album sorting to settings
|
||||
$query = Database::prepare($database, "SELECT `key` FROM `?` WHERE `key` = 'sortingAlbums' LIMIT 1", array(LYCHEE_TABLE_SETTINGS));
|
||||
$result = $database->query($query);
|
||||
if ($result->num_rows===0) {
|
||||
$query = Database::prepare($database, "INSERT INTO `?` (`key`, `value`) VALUES ('sortingAlbums', 'ORDER BY id DESC')", array(LYCHEE_TABLE_SETTINGS));
|
||||
$result = $database->query($query);
|
||||
if (!$result) {
|
||||
Log::error($database, 'update_030001', __LINE__, 'Could not update database (' . $database->error . ')');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
# Rename sorting to sortingPhotos
|
||||
$query = Database::prepare($database, "UPDATE ? SET `key` = 'sortingPhotos' WHERE `key` = 'sorting' LIMIT 1", array(LYCHEE_TABLE_SETTINGS));
|
||||
$result = $database->query($query);
|
||||
if (!$result) {
|
||||
Log::error($database, 'update_030001', __LINE__, 'Could not update database (' . $database->error . ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
# Add identifier to settings
|
||||
$query = Database::prepare($database, "SELECT `key` FROM `?` WHERE `key` = 'identifier' LIMIT 1", array(LYCHEE_TABLE_SETTINGS));
|
||||
$result = $database->query($query);
|
||||
if ($result->num_rows===0) {
|
||||
$identifier = md5(microtime(true));
|
||||
$query = Database::prepare($database, "INSERT INTO `?` (`key`, `value`) VALUES ('identifier', '?')", array(LYCHEE_TABLE_SETTINGS, $identifier));
|
||||
$result = $database->query($query);
|
||||
if (!$result) {
|
||||
Log::error($database, 'update_030001', __LINE__, 'Could not update database (' . $database->error . ')');
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$identifier = md5(microtime(true));
|
||||
$query = Database::prepare($database, "UPDATE `?` SET `value` = '?' WHERE `key` = 'identifier' LIMIT 1", array(LYCHEE_TABLE_SETTINGS, $identifier));
|
||||
$result = $database->query($query);
|
||||
if (!$result) {
|
||||
Log::error($database, 'update_030001', __LINE__, 'Could not reset public albums (' . $database->error . ')');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
# Set version
|
||||
if (Database::setVersion($database, '030001')===false) return false;
|
||||
|
||||
?>
|
@ -94,19 +94,19 @@ class Album extends Module {
|
||||
switch ($this->albumIDs) {
|
||||
|
||||
case 'f': $return['public'] = '0';
|
||||
$query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE star = 1 " . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS));
|
||||
$query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE star = 1 " . $this->settings['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS));
|
||||
break;
|
||||
|
||||
case 's': $return['public'] = '0';
|
||||
$query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE public = 1 " . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS));
|
||||
$query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE public = 1 " . $this->settings['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS));
|
||||
break;
|
||||
|
||||
case 'r': $return['public'] = '0';
|
||||
$query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE LEFT(id, 10) >= unix_timestamp(DATE_SUB(NOW(), INTERVAL 1 DAY)) " . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS));
|
||||
$query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE LEFT(id, 10) >= unix_timestamp(DATE_SUB(NOW(), INTERVAL 1 DAY)) " . $this->settings['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS));
|
||||
break;
|
||||
|
||||
case '0': $return['public'] = '0';
|
||||
$query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE album = 0 " . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS));
|
||||
$query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE album = 0 " . $this->settings['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS));
|
||||
break;
|
||||
|
||||
default: $query = Database::prepare($this->database, "SELECT * FROM ? WHERE id = '?' LIMIT 1", array(LYCHEE_TABLE_ALBUMS, $this->albumIDs));
|
||||
@ -114,7 +114,7 @@ class Album extends Module {
|
||||
$return = $albums->fetch_assoc();
|
||||
$return['sysdate'] = date('d M. Y', $return['sysstamp']);
|
||||
$return['password'] = ($return['password']=='' ? '0' : '1');
|
||||
$query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE album = '?' " . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS, $this->albumIDs));
|
||||
$query = Database::prepare($this->database, "SELECT id, title, tags, public, star, album, thumbUrl, takestamp, url FROM ? WHERE album = '?' " . $this->settings['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS, $this->albumIDs));
|
||||
break;
|
||||
|
||||
}
|
||||
@ -189,8 +189,8 @@ class Album extends Module {
|
||||
if ($public===false) $return['smartalbums'] = $this->getSmartInfo();
|
||||
|
||||
# Albums query
|
||||
$query = Database::prepare($this->database, 'SELECT id, title, public, sysstamp, password FROM ? WHERE public = 1 AND visible <> 0', array(LYCHEE_TABLE_ALBUMS));
|
||||
if ($public===false) $query = Database::prepare($this->database, 'SELECT id, title, public, sysstamp, password FROM ?', array(LYCHEE_TABLE_ALBUMS));
|
||||
if ($public===false) $query = Database::prepare($this->database, 'SELECT id, title, public, sysstamp, password FROM ? ' . $this->settings['sortingAlbums'], array(LYCHEE_TABLE_ALBUMS));
|
||||
else $query = Database::prepare($this->database, 'SELECT id, title, public, sysstamp, password FROM ? WHERE public = 1 AND visible <> 0 ' . $this->settings['sortingAlbums'], array(LYCHEE_TABLE_ALBUMS));
|
||||
|
||||
# Execute query
|
||||
$albums = $this->database->query($query);
|
||||
@ -210,7 +210,7 @@ class Album extends Module {
|
||||
($public===false)) {
|
||||
|
||||
# Execute query
|
||||
$query = Database::prepare($this->database, "SELECT thumbUrl FROM ? WHERE album = '?' ORDER BY star DESC, " . substr($this->settings['sorting'], 9) . " LIMIT 3", array(LYCHEE_TABLE_PHOTOS, $album['id']));
|
||||
$query = Database::prepare($this->database, "SELECT thumbUrl FROM ? WHERE album = '?' ORDER BY star DESC, " . substr($this->settings['sortingPhotos'], 9) . " LIMIT 3", array(LYCHEE_TABLE_PHOTOS, $album['id']));
|
||||
$thumbs = $this->database->query($query);
|
||||
|
||||
# For each thumb
|
||||
@ -223,7 +223,7 @@ class Album extends Module {
|
||||
}
|
||||
|
||||
# Add to return
|
||||
$return['albums'][$album['id']] = $album;
|
||||
$return['albums'][] = $album;
|
||||
|
||||
}
|
||||
|
||||
@ -254,7 +254,7 @@ class Album extends Module {
|
||||
# Unsorted
|
||||
###
|
||||
|
||||
$query = Database::prepare($this->database, 'SELECT thumbUrl FROM ? WHERE album = 0 ' . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS));
|
||||
$query = Database::prepare($this->database, 'SELECT thumbUrl FROM ? WHERE album = 0 ' . $this->settings['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS));
|
||||
$unsorted = $this->database->query($query);
|
||||
$i = 0;
|
||||
|
||||
@ -274,7 +274,7 @@ class Album extends Module {
|
||||
# Starred
|
||||
###
|
||||
|
||||
$query = Database::prepare($this->database, 'SELECT thumbUrl FROM ? WHERE star = 1 ' . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS));
|
||||
$query = Database::prepare($this->database, 'SELECT thumbUrl FROM ? WHERE star = 1 ' . $this->settings['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS));
|
||||
$starred = $this->database->query($query);
|
||||
$i = 0;
|
||||
|
||||
@ -294,7 +294,7 @@ class Album extends Module {
|
||||
# Public
|
||||
###
|
||||
|
||||
$query = Database::prepare($this->database, 'SELECT thumbUrl FROM ? WHERE public = 1 ' . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS));
|
||||
$query = Database::prepare($this->database, 'SELECT thumbUrl FROM ? WHERE public = 1 ' . $this->settings['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS));
|
||||
$public = $this->database->query($query);
|
||||
$i = 0;
|
||||
|
||||
@ -314,7 +314,7 @@ class Album extends Module {
|
||||
# Recent
|
||||
###
|
||||
|
||||
$query = Database::prepare($this->database, 'SELECT thumbUrl FROM ? WHERE LEFT(id, 10) >= unix_timestamp(DATE_SUB(NOW(), INTERVAL 1 DAY)) ' . $this->settings['sorting'], array(LYCHEE_TABLE_PHOTOS));
|
||||
$query = Database::prepare($this->database, 'SELECT thumbUrl FROM ? WHERE LEFT(id, 10) >= unix_timestamp(DATE_SUB(NOW(), INTERVAL 1 DAY)) ' . $this->settings['sortingPhotos'], array(LYCHEE_TABLE_PHOTOS));
|
||||
$recent = $this->database->query($query);
|
||||
$i = 0;
|
||||
|
||||
@ -484,7 +484,7 @@ class Album extends Module {
|
||||
$this->plugins(__METHOD__, 0, func_get_args());
|
||||
|
||||
# Parse
|
||||
if (strlen($title)>50) $title = substr($title, 0, 50);
|
||||
if (strlen($title)>100) $title = substr($title, 0, 100);
|
||||
|
||||
# Execute query
|
||||
$query = Database::prepare($this->database, "UPDATE ? SET title = '?' WHERE id IN (?)", array(LYCHEE_TABLE_ALBUMS, $title, $this->albumIDs));
|
||||
|
@ -55,7 +55,8 @@ class Database extends Module {
|
||||
'020601', #2.6.1
|
||||
'020602', #2.6.2
|
||||
'020700', #2.7.0
|
||||
'030000' #3.0.0
|
||||
'030000', #3.0.0
|
||||
'030001' #3.0.1
|
||||
);
|
||||
|
||||
# For each update
|
||||
|
@ -842,7 +842,7 @@ class Photo extends Module {
|
||||
$this->plugins(__METHOD__, 0, func_get_args());
|
||||
|
||||
# Parse
|
||||
if (strlen($title)>50) $title = substr($title, 0, 50);
|
||||
if (strlen($title)>100) $title = substr($title, 0, 100);
|
||||
|
||||
# Set title
|
||||
$query = Database::prepare($this->database, "UPDATE ? SET title = '?' WHERE id IN (?)", array(LYCHEE_TABLE_PHOTOS, $title, $this->photoIDs));
|
||||
|
@ -44,6 +44,9 @@ class Session extends Module {
|
||||
unset($return['config']['username']);
|
||||
unset($return['config']['password']);
|
||||
|
||||
# Remove identifier from response
|
||||
unset($return['config']['identifier']);
|
||||
|
||||
# Path to Lychee for the server-import dialog
|
||||
$return['config']['location'] = LYCHEE;
|
||||
|
||||
@ -67,10 +70,13 @@ class Session extends Module {
|
||||
|
||||
# Unset unused vars
|
||||
unset($return['config']['thumbQuality']);
|
||||
unset($return['config']['sorting']);
|
||||
unset($return['config']['sortingAlbums']);
|
||||
unset($return['config']['sortingPhotos']);
|
||||
unset($return['config']['dropboxKey']);
|
||||
unset($return['config']['login']);
|
||||
unset($return['config']['location']);
|
||||
unset($return['config']['imagick']);
|
||||
unset($return['config']['medium']);
|
||||
unset($return['config']['plugins']);
|
||||
|
||||
}
|
||||
@ -96,15 +102,13 @@ class Session extends Module {
|
||||
# Check login with crypted hash
|
||||
if ($this->settings['username']===$username&&
|
||||
$this->settings['password']===$password) {
|
||||
$_SESSION['login'] = true;
|
||||
$_SESSION['login'] = true;
|
||||
$_SESSION['identifier'] = $this->settings['identifier'];
|
||||
return true;
|
||||
}
|
||||
|
||||
# No login
|
||||
if ($this->noLogin()===true) {
|
||||
$_SESSION['login'] = true;
|
||||
return true;
|
||||
}
|
||||
if ($this->noLogin()===true) return true;
|
||||
|
||||
# Call plugins
|
||||
$this->plugins(__METHOD__, 1, func_get_args());
|
||||
@ -121,7 +125,8 @@ class Session extends Module {
|
||||
# Check if login credentials exist and login if they don't
|
||||
if ($this->settings['username']===''&&
|
||||
$this->settings['password']==='') {
|
||||
$_SESSION['login'] = true;
|
||||
$_SESSION['login'] = true;
|
||||
$_SESSION['identifier'] = $this->settings['identifier'];
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -134,6 +139,9 @@ class Session extends Module {
|
||||
# Call plugins
|
||||
$this->plugins(__METHOD__, 0, func_get_args());
|
||||
|
||||
$_SESSION['login'] = null;
|
||||
$_SESSION['identifier'] = null;
|
||||
|
||||
session_destroy();
|
||||
|
||||
# Call plugins
|
||||
|
@ -129,7 +129,7 @@ class Settings extends Module {
|
||||
|
||||
}
|
||||
|
||||
public function setSorting($type, $order) {
|
||||
public function setSortingPhotos($type, $order) {
|
||||
|
||||
# Check dependencies
|
||||
self::dependencies(isset($this->database, $type, $order));
|
||||
@ -182,7 +182,64 @@ class Settings extends Module {
|
||||
# Execute query
|
||||
# Do not prepare $sorting because it is a true statement
|
||||
# Preparing (escaping) the sorting would destroy it
|
||||
$query = Database::prepare($this->database, "UPDATE ? SET value = '$sorting' WHERE `key` = 'sorting'", array(LYCHEE_TABLE_SETTINGS));
|
||||
# $sorting is save and can't contain user-input
|
||||
$query = Database::prepare($this->database, "UPDATE ? SET value = '$sorting' WHERE `key` = 'sortingPhotos'", array(LYCHEE_TABLE_SETTINGS));
|
||||
$result = $this->database->query($query);
|
||||
|
||||
if (!$result) {
|
||||
Log::error($this->database, __METHOD__, __LINE__, $this->database->error);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
public function setSortingAlbums($type, $order) {
|
||||
|
||||
# Check dependencies
|
||||
self::dependencies(isset($this->database, $type, $order));
|
||||
|
||||
$sorting = 'ORDER BY ';
|
||||
|
||||
# Set row
|
||||
switch ($type) {
|
||||
|
||||
case 'id': $sorting .= 'id';
|
||||
break;
|
||||
|
||||
case 'title': $sorting .= 'title';
|
||||
break;
|
||||
|
||||
case 'description': $sorting .= 'description';
|
||||
break;
|
||||
|
||||
case 'public': $sorting .= 'public';
|
||||
break;
|
||||
|
||||
default: exit('Error: Unknown type for sorting!');
|
||||
|
||||
}
|
||||
|
||||
$sorting .= ' ';
|
||||
|
||||
# Set order
|
||||
switch ($order) {
|
||||
|
||||
case 'ASC': $sorting .= 'ASC';
|
||||
break;
|
||||
|
||||
case 'DESC': $sorting .= 'DESC';
|
||||
break;
|
||||
|
||||
default: exit('Error: Unknown order for sorting!');
|
||||
|
||||
}
|
||||
|
||||
# Execute query
|
||||
# Do not prepare $sorting because it is a true statement
|
||||
# Preparing (escaping) the sorting would destroy it
|
||||
# $sorting is save and can't contain user-input
|
||||
$query = Database::prepare($this->database, "UPDATE ? SET value = '$sorting' WHERE `key` = 'sortingAlbums'", array(LYCHEE_TABLE_SETTINGS));
|
||||
$result = $this->database->query($query);
|
||||
|
||||
if (!$result) {
|
||||
|
@ -47,7 +47,7 @@ function search($database, $settings, $term) {
|
||||
$album = Album::prepareData($album);
|
||||
|
||||
# Thumbs
|
||||
$query = Database::prepare($database, "SELECT thumbUrl FROM ? WHERE album = '?' " . $settings['sorting'] . " LIMIT 0, 3", array(LYCHEE_TABLE_PHOTOS, $album['id']));
|
||||
$query = Database::prepare($database, "SELECT thumbUrl FROM ? WHERE album = '?' " . $settings['sortingPhotos'] . " LIMIT 0, 3", array(LYCHEE_TABLE_PHOTOS, $album['id']));
|
||||
$thumbs = $database->query($query);
|
||||
|
||||
# For each thumb
|
||||
|
@ -2,7 +2,7 @@
|
||||
"name": "Lychee",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"jQuery": "~2.1.3",
|
||||
"jQuery": "~2.1.4",
|
||||
"mousetrap": "~1.5.2",
|
||||
"basicContext": "~2.0.9",
|
||||
"basicModal": "~2.0.8"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Lychee",
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.1",
|
||||
"description": "Self-hosted photo-management done right.",
|
||||
"authors": "Tobias Reich <tobias@electerious.com>",
|
||||
"license": "MIT",
|
||||
@ -18,7 +18,7 @@
|
||||
"gulp-load-plugins": "^0.10.0",
|
||||
"gulp-minify-css": "^1.1.1",
|
||||
"gulp-rimraf": "^0.1.1",
|
||||
"gulp-sass": "^1.3.3",
|
||||
"gulp-sass": "^2.0.1",
|
||||
"gulp-uglify": "^1.2.0"
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ album.add = function() {
|
||||
}
|
||||
|
||||
basicModal.show({
|
||||
body: "<p>Enter a title for the new album: <input class='text' data-name='title' type='text' maxlength='30' placeholder='Title' value='Untitled'></p>",
|
||||
body: "<p>Enter a title for the new album: <input class='text' data-name='title' type='text' maxlength='50' placeholder='Title' value='Untitled'></p>",
|
||||
buttons: {
|
||||
action: {
|
||||
title: 'Create Album',
|
||||
@ -180,7 +180,7 @@ album.delete = function(albumIDs) {
|
||||
albumIDs.forEach(function(id) {
|
||||
albums.json.num--;
|
||||
view.albums.content.delete(id);
|
||||
delete albums.json.albums[id];
|
||||
albums.deleteByID(id);
|
||||
});
|
||||
|
||||
} else {
|
||||
@ -210,7 +210,7 @@ album.delete = function(albumIDs) {
|
||||
|
||||
// Get title
|
||||
if (album.json) albumTitle = album.json.title;
|
||||
else if (albums.json) albumTitle = albums.json.albums[albumIDs].title;
|
||||
else if (albums.json) albumTitle = albums.getByID(albumIDs).title;
|
||||
|
||||
msg = "<p>Are you sure you want to delete the album '" + albumTitle + "' and all of the photos it contains? This action can't be undone!</p>";
|
||||
|
||||
@ -254,7 +254,7 @@ album.setTitle = function(albumIDs) {
|
||||
|
||||
// Get old title if only one album is selected
|
||||
if (album.json) oldTitle = album.json.title;
|
||||
else if (albums.json) oldTitle = albums.json.albums[albumIDs].title;
|
||||
else if (albums.json) oldTitle = albums.getByID(albumIDs).title;
|
||||
|
||||
if (!oldTitle) oldTitle = '';
|
||||
oldTitle = oldTitle.replace(/'/g, ''');
|
||||
@ -281,13 +281,13 @@ album.setTitle = function(albumIDs) {
|
||||
|
||||
if (albums.json) {
|
||||
var id = albumIDs[0];
|
||||
albums.json.albums[id].title = newTitle;
|
||||
albums.getByID(id).title = newTitle;
|
||||
}
|
||||
|
||||
} else if (visible.albums()) {
|
||||
|
||||
albumIDs.forEach(function(id) {
|
||||
albums.json.albums[id].title = newTitle;
|
||||
albums.getByID(id).title = newTitle;
|
||||
view.albums.content.title(id);
|
||||
});
|
||||
|
||||
@ -306,7 +306,7 @@ album.setTitle = function(albumIDs) {
|
||||
|
||||
}
|
||||
|
||||
input = "<input class='text' data-name='title' type='text' maxlength='30' placeholder='Title' value='" + oldTitle + "'>";
|
||||
input = "<input class='text' data-name='title' type='text' maxlength='50' placeholder='Title' value='" + oldTitle + "'>";
|
||||
|
||||
if (albumIDs.length===1) msg = "<p>Enter a new title for this album: " + input + "</p>";
|
||||
else msg = "<p>Enter a title for all " + albumIDs.length + " selected albums: " + input +"</p>";
|
||||
@ -580,7 +580,7 @@ album.merge = function(albumIDs) {
|
||||
if (albumIDs instanceof Array===false) albumIDs = [albumIDs];
|
||||
|
||||
// Get title of first album
|
||||
if (albums.json) title = albums.json.albums[albumIDs[0]].title;
|
||||
if (albums.json) title = albums.getByID(albumIDs[0]).title;
|
||||
|
||||
if (!title) title = '';
|
||||
title = title.replace(/'/g, ''');
|
||||
@ -588,7 +588,7 @@ album.merge = function(albumIDs) {
|
||||
if (albumIDs.length===2) {
|
||||
|
||||
// Get title of second album
|
||||
if (albums.json) sTitle = albums.json.albums[albumIDs[1]].title;
|
||||
if (albums.json) sTitle = albums.getByID(albumIDs[1]).title;
|
||||
|
||||
if (!sTitle) sTitle = '';
|
||||
sTitle = sTitle.replace(/'/g, ''');
|
||||
|
@ -105,6 +105,52 @@ albums._createSmartAlbums = function(data) {
|
||||
|
||||
}
|
||||
|
||||
albums.getByID = function(albumID) {
|
||||
|
||||
// Function returns the JSON of an album
|
||||
|
||||
if (albumID===undefined||albumID===null) return undefined;
|
||||
if (!albums.json) return undefined;
|
||||
if (!albums.json.albums) return undefined;
|
||||
|
||||
var json = undefined;
|
||||
|
||||
$.each(albums.json.albums, function(i) {
|
||||
|
||||
let elem = albums.json.albums[i];
|
||||
|
||||
if (elem.id==albumID) json = elem;
|
||||
|
||||
});
|
||||
|
||||
return json;
|
||||
|
||||
}
|
||||
|
||||
albums.deleteByID = function(albumID) {
|
||||
|
||||
// Function returns the JSON of an album
|
||||
|
||||
if (albumID===undefined||albumID===null) return false;
|
||||
if (!albums.json) return false;
|
||||
if (!albums.json.albums) return false;
|
||||
|
||||
var deleted = false;
|
||||
|
||||
$.each(albums.json.albums, function(i) {
|
||||
|
||||
if (albums.json.albums[i].id==albumID) {
|
||||
albums.json.albums.splice(i, 1);
|
||||
deleted = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return deleted;
|
||||
|
||||
}
|
||||
|
||||
albums.refresh = function() {
|
||||
|
||||
albums.json = null;
|
||||
|
@ -59,16 +59,7 @@ build.album = function(data) {
|
||||
|
||||
if (data===null||data===undefined) return '';
|
||||
|
||||
var html = '',
|
||||
title = data.title,
|
||||
longTitle = '';
|
||||
|
||||
if (title!==null&&title.length>18) {
|
||||
|
||||
title = data.title.substr(0, 18) + '...';
|
||||
longTitle = data.title;
|
||||
|
||||
}
|
||||
var html = '';
|
||||
|
||||
var {path: thumbPath, hasRetina: thumbRetina} = lychee.retinize(data.thumbs[0]);
|
||||
|
||||
@ -78,7 +69,7 @@ build.album = function(data) {
|
||||
<img src='${ data.thumbs[1] }' width='200' height='200' alt='thumb' data-retina='false'>
|
||||
<img src='${ thumbPath }' width='200' height='200' alt='thumb' data-retina='${ thumbRetina }'>
|
||||
<div class='overlay'>
|
||||
<h1 title='${ longTitle }'>${ title }</h1>
|
||||
<h1 title='${ data.title }'>${ data.title }</h1>
|
||||
<a>${ data.sysdate }</a>
|
||||
</div>
|
||||
`
|
||||
@ -103,16 +94,7 @@ build.photo = function(data) {
|
||||
|
||||
if (data===null||data===undefined) return '';
|
||||
|
||||
var html = '',
|
||||
title = data.title,
|
||||
longTitle = '';
|
||||
|
||||
if (title!==null&&title.length>18) {
|
||||
|
||||
title = data.title.substr(0, 18) + '...';
|
||||
longTitle = data.title;
|
||||
|
||||
}
|
||||
var html = '';
|
||||
|
||||
var {path: thumbPath, hasRetina: thumbRetina} = lychee.retinize(data.thumbUrl);
|
||||
|
||||
@ -120,7 +102,7 @@ build.photo = function(data) {
|
||||
<div class='photo' data-album-id='${ data.album }' data-id='${ data.id }'>
|
||||
<img src='${ thumbPath }' width='200' height='200' alt='thumb'>
|
||||
<div class='overlay'>
|
||||
<h1 title='${ longTitle }'>${ title }</h1>
|
||||
<h1 title='${ data.title }'>${ data.title }</h1>
|
||||
`
|
||||
|
||||
if (data.cameraDate==='1') html += `<a><span title='Camera Date'>${ build.iconic('camera-slr') }</span>${ data.sysdate }</a>`;
|
||||
|
@ -84,7 +84,7 @@ contextMenu.albumTitle = function(albumID, e) {
|
||||
|
||||
api.post('Album::getAll', {}, function(data) {
|
||||
|
||||
if (data.num>1) {
|
||||
if (data.albums&&data.num>1) {
|
||||
|
||||
// Generate list of albums
|
||||
$.each(data.albums, function(index) {
|
||||
@ -96,7 +96,7 @@ contextMenu.albumTitle = function(albumID, e) {
|
||||
|
||||
title = "<img class='cover' width='16' height='16' src='" + that.thumbs[0] + "'><div class='title'>" + that.title + "</div>";
|
||||
|
||||
if (that.id!=albumID) items.unshift({ type: 'item', title, fn: function() { lychee.goto(that.id) } });
|
||||
if (that.id!=albumID) items.push({ type: 'item', title, fn: function() { lychee.goto(that.id) } });
|
||||
|
||||
});
|
||||
|
||||
@ -114,28 +114,30 @@ contextMenu.albumTitle = function(albumID, e) {
|
||||
|
||||
contextMenu.mergeAlbum = function(albumID, e) {
|
||||
|
||||
var items = [];
|
||||
var items = [];
|
||||
|
||||
api.post('Album::getAll', {}, function(data) {
|
||||
api.post('Album::getAll', {}, function(data) {
|
||||
|
||||
$.each(data.albums, function(){
|
||||
if (data.albums&&data.num>1) {
|
||||
|
||||
var that = this;
|
||||
$.each(data.albums, function(){
|
||||
|
||||
if (!that.thumbs[0]) that.thumbs[0] = 'src/images/no_cover.svg';
|
||||
that.contextTitle = "<img class='cover' width='16' height='16' src='" + that.thumbs[0] + "'><div class='title'>" + that.title + "</div>";
|
||||
var that = this;
|
||||
|
||||
if (that.id!=album.getID()) {
|
||||
items.unshift({ type: 'item', title: that.contextTitle, fn: function() { album.merge([albumID, that.id]) } });
|
||||
}
|
||||
if (!that.thumbs[0]) that.thumbs[0] = 'src/images/no_cover.svg';
|
||||
that.contextTitle = "<img class='cover' width='16' height='16' src='" + that.thumbs[0] + "'><div class='title'>" + that.title + "</div>";
|
||||
|
||||
});
|
||||
if (that.id!=albumID) items.push({ type: 'item', title: that.contextTitle, fn: function() { album.merge([albumID, that.id]) } });
|
||||
|
||||
if (items.length===0) return false;
|
||||
});
|
||||
|
||||
basicContext.show(items, e, contextMenu.close);
|
||||
}
|
||||
|
||||
})
|
||||
if (items.length===0) return false;
|
||||
|
||||
basicContext.show(items, e, contextMenu.close);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@ -191,7 +193,7 @@ contextMenu.photoTitle = function(albumID, photoID, e) {
|
||||
|
||||
var data = album.json;
|
||||
|
||||
if (data.num>1) {
|
||||
if (data.content!==false&&data.num>1) {
|
||||
|
||||
items.push({ type: 'separator' });
|
||||
|
||||
@ -253,7 +255,7 @@ contextMenu.move = function(photoIDs, e) {
|
||||
if (!that.thumbs[0]) that.thumbs[0] = 'src/images/no_cover.svg';
|
||||
that.title = "<img class='cover' width='16' height='16' src='" + that.thumbs[0] + "'><div class='title'>" + that.title + "</div>";
|
||||
|
||||
if (that.id!=album.getID()) items.unshift({ type: 'item', title: that.title, fn: function() { photo.setAlbum(photoIDs, that.id) } });
|
||||
if (that.id!=album.getID()) items.push({ type: 'item', title: that.title, fn: function() { photo.setAlbum(photoIDs, that.id) } });
|
||||
|
||||
});
|
||||
|
||||
|
@ -85,7 +85,7 @@ loadingBar.hide = function(force) {
|
||||
loadingBar.status = null;
|
||||
|
||||
// Move header up
|
||||
if (visible.header()) header.dom().removeClass('error loading');
|
||||
header.dom().removeClass('error loading');
|
||||
|
||||
// Set timeout
|
||||
clearTimeout(loadingBar._timeout);
|
||||
|
@ -6,8 +6,8 @@
|
||||
lychee = {
|
||||
|
||||
title: document.title,
|
||||
version: '3.0.0',
|
||||
version_code: '030000',
|
||||
version: '3.0.1',
|
||||
version_code: '030001',
|
||||
|
||||
update_path: 'http://lychee.electerious.com/version/index.php',
|
||||
updateURL: 'https://github.com/electerious/Lychee',
|
||||
@ -18,7 +18,8 @@ lychee = {
|
||||
debugMode: false,
|
||||
|
||||
checkForUpdates:'1',
|
||||
sorting: '',
|
||||
sortingPhotos: '',
|
||||
sortingAlbums: '',
|
||||
location: '',
|
||||
|
||||
dropbox: false,
|
||||
@ -48,7 +49,8 @@ lychee.init = function() {
|
||||
|
||||
// Logged in
|
||||
|
||||
lychee.sorting = data.config.sorting || '';
|
||||
lychee.sortingPhotos = data.config.sortingPhotos || '';
|
||||
lychee.sortingAlbums = data.config.sortingAlbums || '';
|
||||
lychee.dropboxKey = data.config.dropboxKey || '';
|
||||
lychee.location = data.config.location || '';
|
||||
lychee.checkForUpdates = data.config.checkForUpdates || '1';
|
||||
@ -382,10 +384,13 @@ lychee.loadDropbox = function(callback) {
|
||||
|
||||
}
|
||||
|
||||
lychee.removeHTML = function(html) {
|
||||
lychee.removeHTML = function(html = '') {
|
||||
|
||||
if (html==='') return html;
|
||||
|
||||
var tmp = document.createElement('DIV');
|
||||
tmp.innerHTML = html;
|
||||
|
||||
return tmp.textContent || tmp.innerText;
|
||||
|
||||
}
|
||||
|
@ -14,9 +14,9 @@ password.get = function(albumID, callback) {
|
||||
var passwd = $('.basicModal input.text').val(),
|
||||
params;
|
||||
|
||||
if (lychee.publicMode===false) callback();
|
||||
else if (album.json&&album.json.password==='0') callback();
|
||||
else if (albums.json&&albums.json.albums[albumID].password==='0') callback();
|
||||
if (lychee.publicMode===false) callback();
|
||||
else if (album.json&&album.json.password==='0') callback();
|
||||
else if (albums.json&&albums.getByID(albumID).password==='0') callback();
|
||||
else if (!albums.json&&!album.json) {
|
||||
|
||||
// Continue without password
|
||||
|
@ -223,7 +223,7 @@ photo.delete = function(photoIDs) {
|
||||
|
||||
}
|
||||
|
||||
album.json.content[id] = null;
|
||||
delete album.json.content[id];
|
||||
view.album.content.delete(id);
|
||||
|
||||
});
|
||||
@ -330,7 +330,7 @@ photo.setTitle = function(photoIDs) {
|
||||
|
||||
}
|
||||
|
||||
input = "<input class='text' data-name='title' type='text' maxlength='30' placeholder='Title' value='" + oldTitle + "'>";
|
||||
input = "<input class='text' data-name='title' type='text' maxlength='50' placeholder='Title' value='" + oldTitle + "'>";
|
||||
|
||||
if (photoIDs.length===1) msg = "<p>Enter a new title for this photo: " + input + "</p>";
|
||||
else msg = "<p>Enter a title for all " + photoIDs.length + " selected photos: " + input + "</p>";
|
||||
|
@ -281,7 +281,8 @@ settings.setLogin = function() {
|
||||
|
||||
settings.setSorting = function() {
|
||||
|
||||
var sorting = [],
|
||||
var sortingPhotos = [],
|
||||
sortingAlbums = [],
|
||||
action,
|
||||
msg = '';
|
||||
|
||||
@ -289,21 +290,27 @@ settings.setSorting = function() {
|
||||
|
||||
var params;
|
||||
|
||||
sorting[0] = $('.basicModal select#settings_type').val();
|
||||
sorting[1] = $('.basicModal select#settings_order').val();
|
||||
sortingAlbums[0] = $('.basicModal select#settings_albums_type').val();
|
||||
sortingAlbums[1] = $('.basicModal select#settings_albums_order').val();
|
||||
|
||||
sortingPhotos[0] = $('.basicModal select#settings_photos_type').val();
|
||||
sortingPhotos[1] = $('.basicModal select#settings_photos_order').val();
|
||||
|
||||
basicModal.close();
|
||||
albums.refresh();
|
||||
|
||||
params = {
|
||||
type: sorting[0],
|
||||
order: sorting[1]
|
||||
typeAlbums: sortingAlbums[0],
|
||||
orderAlbums: sortingAlbums[1],
|
||||
typePhotos: sortingPhotos[0],
|
||||
orderPhotos: sortingPhotos[1]
|
||||
}
|
||||
|
||||
api.post('Settings::setSorting', params, function(data) {
|
||||
|
||||
if (data===true) {
|
||||
lychee.sorting = 'ORDER BY ' + sorting[0] + ' ' + sorting[1];
|
||||
lychee.sortingAlbums = 'ORDER BY ' + sortingAlbums[0] + ' ' + sortingAlbums[1];
|
||||
lychee.sortingPhotos = 'ORDER BY ' + sortingPhotos[0] + ' ' + sortingPhotos[1];
|
||||
lychee.load();
|
||||
} else lychee.error(null, params, data);
|
||||
|
||||
@ -313,21 +320,44 @@ settings.setSorting = function() {
|
||||
|
||||
msg = `
|
||||
<p>
|
||||
Sort photos by
|
||||
<select id='settings_type'>
|
||||
<option value='id'>Upload Time</option>
|
||||
<option value='takestamp'>Take Date</option>
|
||||
<option value='title'>Title</option>
|
||||
<option value='description'>Description</option>
|
||||
<option value='public'>Public</option>
|
||||
<option value='star'>Star</option>
|
||||
<option value='type'>Photo Format</option>
|
||||
</select>
|
||||
Sort albums by
|
||||
<span class="select">
|
||||
<select id='settings_albums_type'>
|
||||
<option value='id'>Creation Time</option>
|
||||
<option value='title'>Title</option>
|
||||
<option value='description'>Description</option>
|
||||
<option value='public'>Public</option>
|
||||
</select>
|
||||
</span>
|
||||
in an
|
||||
<select id='settings_order'>
|
||||
<option value='ASC'>Ascending</option>
|
||||
<option value='DESC'>Descending</option>
|
||||
</select>
|
||||
<span class="select">
|
||||
<select id='settings_albums_order'>
|
||||
<option value='ASC'>Ascending</option>
|
||||
<option value='DESC'>Descending</option>
|
||||
</select>
|
||||
</span>
|
||||
order.
|
||||
</p>
|
||||
<p>
|
||||
Sort photos by
|
||||
<span class="select">
|
||||
<select id='settings_photos_type'>
|
||||
<option value='id'>Upload Time</option>
|
||||
<option value='takestamp'>Take Date</option>
|
||||
<option value='title'>Title</option>
|
||||
<option value='description'>Description</option>
|
||||
<option value='public'>Public</option>
|
||||
<option value='star'>Star</option>
|
||||
<option value='type'>Photo Format</option>
|
||||
</select>
|
||||
</span>
|
||||
in an
|
||||
<span class="select">
|
||||
<select id='settings_photos_order'>
|
||||
<option value='ASC'>Ascending</option>
|
||||
<option value='DESC'>Descending</option>
|
||||
</select>
|
||||
</span>
|
||||
order.
|
||||
</p>
|
||||
`
|
||||
@ -346,12 +376,21 @@ settings.setSorting = function() {
|
||||
}
|
||||
});
|
||||
|
||||
if (lychee.sorting!=='') {
|
||||
if (lychee.sortingAlbums!=='') {
|
||||
|
||||
sorting = lychee.sorting.replace('ORDER BY ', '').split(' ');
|
||||
sortingAlbums = lychee.sortingAlbums.replace('ORDER BY ', '').split(' ');
|
||||
|
||||
$('.basicModal select#settings_type').val(sorting[0]);
|
||||
$('.basicModal select#settings_order').val(sorting[1]);
|
||||
$('.basicModal select#settings_albums_type').val(sortingAlbums[0]);
|
||||
$('.basicModal select#settings_albums_order').val(sortingAlbums[1]);
|
||||
|
||||
}
|
||||
|
||||
if (lychee.sortingPhotos!=='') {
|
||||
|
||||
sortingPhotos = lychee.sortingPhotos.replace('ORDER BY ', '').split(' ');
|
||||
|
||||
$('.basicModal select#settings_photos_type').val(sortingPhotos[0]);
|
||||
$('.basicModal select#settings_photos_order').val(sortingPhotos[1]);
|
||||
|
||||
}
|
||||
|
||||
|
@ -46,9 +46,7 @@ view.albums = {
|
||||
|
||||
$.each(albums.json.albums, function() {
|
||||
albums.parse(this);
|
||||
|
||||
// Display albums in reverse order
|
||||
albumsData = build.album(this) + albumsData;
|
||||
albumsData += build.album(this);
|
||||
});
|
||||
|
||||
// Add divider
|
||||
@ -73,17 +71,11 @@ view.albums = {
|
||||
|
||||
title: function(albumID) {
|
||||
|
||||
var longTitle = '',
|
||||
title = albums.json.albums[albumID].title;
|
||||
|
||||
if (title!==null&&title.length>18) {
|
||||
longTitle = title;
|
||||
title = title.substr(0, 18) + '...';
|
||||
}
|
||||
var title = albums.getByID(albumID).title;
|
||||
|
||||
$('.album[data-id="' + albumID + '"] .overlay h1')
|
||||
.html(title)
|
||||
.attr('title', longTitle);
|
||||
.attr('title', title);
|
||||
|
||||
},
|
||||
|
||||
@ -94,7 +86,7 @@ view.albums = {
|
||||
marginLeft: 0
|
||||
}, 300, function() {
|
||||
$(this).remove();
|
||||
if (albums.json.num<=0) lychee.animate('#content .divider:last-of-type', 'fadeOut');
|
||||
if (albums.json.num<=0) lychee.content.find('.divider:last-child').remove();
|
||||
});
|
||||
|
||||
}
|
||||
@ -155,27 +147,27 @@ view.album = {
|
||||
view.albums.content.scrollPosition = $(document).scrollTop();
|
||||
$('html, body').scrollTop(0);
|
||||
|
||||
$.each(album.json.content, function() {
|
||||
photosData += build.photo(this);
|
||||
});
|
||||
if (album.json.content&&album.json.content!==false) {
|
||||
|
||||
// Build photos
|
||||
$.each(album.json.content, function() {
|
||||
photosData += build.photo(this);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// Add photos to view
|
||||
lychee.content.html(photosData);
|
||||
|
||||
},
|
||||
|
||||
title: function(photoID) {
|
||||
|
||||
var longTitle = '',
|
||||
title = album.json.content[photoID].title;
|
||||
|
||||
if (title!==null&&title.length>18) {
|
||||
longTitle = title;
|
||||
title = title.substr(0, 18) + '...';
|
||||
}
|
||||
var title = album.json.content[photoID].title;
|
||||
|
||||
$('.photo[data-id="' + photoID + '"] .overlay h1')
|
||||
.html(title)
|
||||
.attr('title', longTitle);
|
||||
.attr('title', title);
|
||||
|
||||
},
|
||||
|
||||
|
@ -125,13 +125,15 @@
|
||||
.album .overlay h1,
|
||||
.photo .overlay h1 {
|
||||
min-height: 19px;
|
||||
width: 185px;
|
||||
width: 180px;
|
||||
margin: 12px 0 5px 15px;
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 3px black(.4);
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.album .overlay a,
|
||||
@ -218,13 +220,13 @@
|
||||
.iconic {
|
||||
fill: white(.3);
|
||||
margin: 0 0 10px;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
filter: drop-shadow(0 -1px 0 black(.4));
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 18px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
@ -38,6 +38,9 @@ header {
|
||||
text-align: center;
|
||||
z-index: 1;
|
||||
cursor: default;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
.iconic {
|
||||
display: none;
|
||||
|
@ -172,6 +172,65 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Select ------------------------------------------------*/
|
||||
.select {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
margin: 1px 5px;
|
||||
padding: 0;
|
||||
width: 110px;
|
||||
background: black(.3);
|
||||
color: #fff;
|
||||
border-radius: 3px;
|
||||
border: 1px solid black(.2);
|
||||
box-shadow: 0 1px 0 white(.02);
|
||||
font-size: 11px;
|
||||
line-height: 16px;
|
||||
overflow: hidden;
|
||||
outline: 0;
|
||||
vertical-align: middle;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
content: '≡';
|
||||
right: 8px;
|
||||
top: 4px;
|
||||
color: $colorBlue;
|
||||
font-size: 16px;
|
||||
line-height: 16px;
|
||||
font-weight: bold;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
select {
|
||||
margin: 0;
|
||||
padding: 4px 8px;
|
||||
width: 120%;
|
||||
color: #fff;
|
||||
font-size: 11px;
|
||||
line-height: 16px;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
box-shadow: none;
|
||||
border-radius: 0;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
-moz-appearance: none;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
|
||||
&:focus { outline: none; }
|
||||
}
|
||||
|
||||
select option {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: #fff;
|
||||
color: #333;
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Version ------------------------------------------------*/
|
||||
.version {
|
||||
margin: -5px 0 0;
|
||||
|
Loading…
Reference in New Issue
Block a user