From 30cc1983021e63a575c6ddae909ce0fb1343d174 Mon Sep 17 00:00:00 2001 From: Jason Priebe Date: Sun, 27 Nov 2016 22:36:16 +0000 Subject: [PATCH 1/4] first cut at filtering --- index.html | 11 +++- php/Access/Admin.php | 12 +++- php/Modules/Albums.php | 42 ++++++++++++-- src/images/ionicons.svg | 2 +- src/scripts/albums.js | 11 +++- src/scripts/filter.js | 120 ++++++++++++++++++++++++++++++++++++++++ src/scripts/header.js | 3 +- src/scripts/view.js | 30 +++++++--- view.php | 3 +- 9 files changed, 212 insertions(+), 22 deletions(-) create mode 100644 src/scripts/filter.js diff --git a/index.html b/index.html index a816ada..0d8ef7c 100644 --- a/index.html +++ b/index.html @@ -23,7 +23,8 @@ - + + @@ -54,6 +55,9 @@ × + + + @@ -70,6 +74,9 @@ + + + @@ -141,4 +148,4 @@ - \ No newline at end of file + diff --git a/php/Access/Admin.php b/php/Access/Admin.php index c706653..a662808 100644 --- a/php/Access/Admin.php +++ b/php/Access/Admin.php @@ -73,8 +73,14 @@ final class Admin extends Access { private static function getAlbumsAction() { $albums = new Albums(); - Response::json($albums->get(false)); - + if (isset ($_POST['filterParams'])) + { + Response::json($albums->get(false, $_POST['filterParams'])); + } + else + { + Response::json($albums->get(false)); + } } // Album functions @@ -341,4 +347,4 @@ final class Admin extends Access { } -?> \ No newline at end of file +?> diff --git a/php/Modules/Albums.php b/php/Modules/Albums.php index e57ee84..efe1584 100644 --- a/php/Modules/Albums.php +++ b/php/Modules/Albums.php @@ -16,7 +16,7 @@ final class Albums { /** * @return array|false Returns an array of albums or false on failure. */ - public function get($public = true) { + public function get($public = true, $filter_params = null) { // Call plugins Plugins::get()->activate(__METHOD__, 0, func_get_args()); @@ -32,8 +32,42 @@ final class Albums { if ($public===false) $return['smartalbums'] = $this->getSmartAlbums(); // Albums query - if ($public===false) $query = Database::prepare(Database::get(), 'SELECT id, title, public, sysstamp, password FROM ? ' . Settings::get()['sortingAlbums'], array(LYCHEE_TABLE_ALBUMS)); - else $query = Database::prepare(Database::get(), 'SELECT id, title, public, sysstamp, password FROM ? WHERE public = 1 AND visible <> 0 ' . Settings::get()['sortingAlbums'], array(LYCHEE_TABLE_ALBUMS)); + if ($public===false) $sql = 'SELECT id, title, public, sysstamp, password FROM ? '; + else $sql = 'SELECT id, title, public, sysstamp, password FROM ? WHERE public = 1 AND visible <> 0 '; + + $query_params = array (); + $query_params[] = LYCHEE_TABLE_ALBUMS; + + if ($filter_params !== null) + { + $query_params[] = LYCHEE_TABLE_PHOTOS; + + $xary = array (); + if (isset ($filter_params['star']) && $filter_params['star']) + { + $xary[] = 'star = 1'; + } + if (isset ($filter_params['tags']) && $filter_params['tags']) + { + $xary[] = "tags LIKE '%?%'"; + $query_params[] = $filter_params['tags']; + } + + $where_clause = join (" AND ", $xary); + if ($public) + { + $sql .= "AND "; + } + else + { + $sql .= "WHERE "; + } + + $sql .= "id IN (SELECT DISTINCT album FROM ? WHERE $where_clause) "; + } + + $sql .= Settings::get()['sortingAlbums']; + $query = Database::prepare (Database::get (), $sql, $query_params); // Execute query $albums = Database::execute(Database::get(), $query, __METHOD__, __LINE__); @@ -188,4 +222,4 @@ final class Albums { } -?> \ No newline at end of file +?> diff --git a/src/images/ionicons.svg b/src/images/ionicons.svg index 67b9919..5780f7e 100755 --- a/src/images/ionicons.svg +++ b/src/images/ionicons.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/src/scripts/albums.js b/src/scripts/albums.js index d6913d6..d753eb9 100644 --- a/src/scripts/albums.js +++ b/src/scripts/albums.js @@ -16,7 +16,14 @@ albums.load = function() { if (albums.json===null) { - api.post('Albums::get', {}, function(data) { + params = {} + filterParams = filter.getFilterParams () + if (filterParams !== null) + { + params.filterParams = filterParams; + } + + api.post('Albums::get', params, function(data) { let waitTime = 0 @@ -153,4 +160,4 @@ albums.refresh = function() { albums.json = null -} \ No newline at end of file +} diff --git a/src/scripts/filter.js b/src/scripts/filter.js new file mode 100644 index 0000000..132e50a --- /dev/null +++ b/src/scripts/filter.js @@ -0,0 +1,120 @@ +/** + * @description Applies filters to album + */ + +var filter = {}; + +filter.currentState = { + star: 0, + tags: '' +}; + +filter.setFilter = function() { + + const action = function() { + + filter.currentState.star = 0; + if ($('#filter_star').prop('checked')) + { + filter.currentState.star = 1; + } + + filter.currentState.tags = ''; + if ($('#filter_tags').val() !== 'undefined') + { + filter.currentState.tags = $('#filter_tags').val().trim(); + } + + basicModal.close(); + + if (album.json !== null) + { + album.load(album.json.id, true); + } + else + { + albums.refresh(); + albums.load(); + } + }; + + let msg = ` +

+ Starred: + +

+

+ Tags match: + +

+ `; + + basicModal.show({ + body: msg, + buttons: { + action: { + title: 'Apply Filter', + fn: action + }, + cancel: { + title: 'Cancel', + fn: basicModal.close + } + } + }); + + + if (filter.currentState.star) + { + $('#filter_star').prop ('checked', true); + } + $('#filter_tags').val(filter.currentState.tags); + +} + +filter.checkPhoto = function(p) +{ + if (filter.currentState.star === 1) + { + if (p.star !== "1") + { + return false; + } + } + + if (filter.currentState.tags !== '') + { + if (!p.tags.includes (filter.currentState.tags)) + { + return false; + } + } + + return true; +} + +filter.isFilterActive = function () +{ + if (filter.currentState.star) + { + return true; + } + + if (filter.currentState.tags !== '') + { + return true; + } + + return false; +} + + +filter.getFilterParams = function () +{ + if (!filter.isFilterActive()) + { + return null; + } + + return filter.currentState; +} diff --git a/src/scripts/header.js b/src/scripts/header.js index ee48783..9ca9c53 100644 --- a/src/scripts/header.js +++ b/src/scripts/header.js @@ -49,6 +49,7 @@ header.bind = function() { header.dom('.header__hostedwith') .on(eventName, function() { window.open(lychee.website) }) header.dom('#button_trash_album') .on(eventName, function() { album.delete([ album.getID() ]) }) header.dom('#button_trash') .on(eventName, function() { photo.delete([ photo.getID() ]) }) + header.dom('.button_filter') .on(eventName, function() { filter.setFilter () }) header.dom('#button_archive') .on(eventName, function() { album.getArchive(album.getID()) }) header.dom('#button_star') .on(eventName, function() { photo.setStar([ photo.getID() ]) }) header.dom('#button_back_home') .on(eventName, function() { lychee.goto() }) @@ -177,4 +178,4 @@ header.setEditable = function(editable) { return true -} \ No newline at end of file +} diff --git a/src/scripts/view.js b/src/scripts/view.js index 57246ee..91fc446 100644 --- a/src/scripts/view.js +++ b/src/scripts/view.js @@ -114,25 +114,36 @@ view.album = { if ((visible.album() || !album.json.init) && !visible.photo()) { + title = ''; + editable = false; + switch (album.getID()) { case 'f': - lychee.setTitle('Starred', false) + title = 'Starred' break case 's': - lychee.setTitle('Public', false) + title = 'Public' break case 'r': - lychee.setTitle('Recent', false) + title = 'Recent' break case '0': - lychee.setTitle('Unsorted', false) + title = 'Unsorted' break default: - if (album.json.init) sidebar.changeAttr('title', album.json.title) - lychee.setTitle(album.json.title, true) + title = album.json.title + editable = true break } + if (filter.isFilterActive()) + { + title += " (filtered)" + } + + if (editable && album.json.init) sidebar.changeAttr('title', title) + lychee.setTitle(title, editable) + } }, @@ -147,7 +158,10 @@ view.album = { // Build photos $.each(album.json.content, function() { - photosData += build.photo(this) + if (filter.checkPhoto (this)) + { + photosData += build.photo(this) + } }) } @@ -452,4 +466,4 @@ view.photo = { } -} \ No newline at end of file +} diff --git a/view.php b/view.php index c66c18e..77cd7c3 100644 --- a/view.php +++ b/view.php @@ -38,7 +38,8 @@ - + + From 15b8e44a22c4c7af0a3a7a2988f03bb2540bff6b Mon Sep 17 00:00:00 2001 From: Jason Priebe Date: Mon, 28 Nov 2016 02:29:32 +0000 Subject: [PATCH 2/4] fixed issue where albums page would show thumbnails for an album that didn't match the filter (the album was correctly selected, since it *has* images that match the filter, but the selected thumbnail didn't necessarily match the filter) --- php/Modules/Albums.php | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/php/Modules/Albums.php b/php/Modules/Albums.php index efe1584..ce286b4 100644 --- a/php/Modules/Albums.php +++ b/php/Modules/Albums.php @@ -35,12 +35,15 @@ final class Albums { if ($public===false) $sql = 'SELECT id, title, public, sysstamp, password FROM ? '; else $sql = 'SELECT id, title, public, sysstamp, password FROM ? WHERE public = 1 AND visible <> 0 '; - $query_params = array (); - $query_params[] = LYCHEE_TABLE_ALBUMS; + $query_params1 = array (LYCHEE_TABLE_ALBUMS); + $query_params2 = array (); + + $filter_where1 = ''; + $filter_where2 = ''; if ($filter_params !== null) { - $query_params[] = LYCHEE_TABLE_PHOTOS; + $query_params1[] = LYCHEE_TABLE_PHOTOS; $xary = array (); if (isset ($filter_params['star']) && $filter_params['star']) @@ -50,10 +53,12 @@ final class Albums { if (isset ($filter_params['tags']) && $filter_params['tags']) { $xary[] = "tags LIKE '%?%'"; - $query_params[] = $filter_params['tags']; + $query_params1[] = $filter_params['tags']; + $query_params2[] = $filter_params['tags']; } - $where_clause = join (" AND ", $xary); + $filter_where1 = join (" AND ", $xary); + $filter_where2 = "AND " . join (" AND ", $xary); if ($public) { $sql .= "AND "; @@ -63,11 +68,11 @@ final class Albums { $sql .= "WHERE "; } - $sql .= "id IN (SELECT DISTINCT album FROM ? WHERE $where_clause) "; + $sql .= "id IN (SELECT DISTINCT album FROM ? WHERE $filter_where1) "; } $sql .= Settings::get()['sortingAlbums']; - $query = Database::prepare (Database::get (), $sql, $query_params); + $query = Database::prepare (Database::get (), $sql, $query_params1); // Execute query $albums = Database::execute(Database::get(), $query, __METHOD__, __LINE__); @@ -85,7 +90,11 @@ final class Albums { ($public===false)) { // Execute query - $query = Database::prepare(Database::get(), "SELECT thumbUrl FROM ? WHERE album = '?' ORDER BY star DESC, " . substr(Settings::get()['sortingPhotos'], 9) . " LIMIT 3", array(LYCHEE_TABLE_PHOTOS, $album['id'])); + $query = Database::prepare(Database::get(), "SELECT thumbUrl FROM ? WHERE album = '?' " + . $filter_where2 + . " ORDER BY star DESC, " + . substr(Settings::get()['sortingPhotos'], 9) + . " LIMIT 3", array_merge (array(LYCHEE_TABLE_PHOTOS, $album['id']), $query_params2)); $thumbs = Database::execute(Database::get(), $query, __METHOD__, __LINE__); if ($thumbs===false) return false; From 9321aecf17727f34736ed06048e81cea9f69dd06 Mon Sep 17 00:00:00 2001 From: Jason Priebe Date: Mon, 28 Nov 2016 02:39:58 +0000 Subject: [PATCH 3/4] if filter is changed while on album view, make the albums screen reflect that when the user hits "back" --- src/scripts/filter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scripts/filter.js b/src/scripts/filter.js index 132e50a..f8fcef2 100644 --- a/src/scripts/filter.js +++ b/src/scripts/filter.js @@ -27,13 +27,13 @@ filter.setFilter = function() { basicModal.close(); + albums.refresh(); if (album.json !== null) { album.load(album.json.id, true); } else { - albums.refresh(); albums.load(); } }; From 8ea4f68437e8f5f165e9b6453e38483c17a60cfe Mon Sep 17 00:00:00 2001 From: Jason Priebe Date: Mon, 28 Nov 2016 02:40:38 +0000 Subject: [PATCH 4/4] add "(filtered)" to the Albums title while a filter is active --- src/scripts/view.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/scripts/view.js b/src/scripts/view.js index 91fc446..14f7047 100644 --- a/src/scripts/view.js +++ b/src/scripts/view.js @@ -15,7 +15,14 @@ view.albums = { title: function() { - lychee.setTitle('Albums', false) + if (filter.isFilterActive()) + { + lychee.setTitle('Albums (filtered)', false) + } + else + { + lychee.setTitle('Albums', false) + } },