From 6f23999c7b3de1a69fea4dea056aed2548c4a32d Mon Sep 17 00:00:00 2001 From: Prashant Tholia <65695939+prashanttholia@users.noreply.github.com> Date: Mon, 2 Nov 2020 16:33:16 +0530 Subject: Remember open categories (#3185) * feature(normal) - Remember opened categories in the left menu Session storage based implementation to remember opened categories in left menu Issue Ref: #2248 * lib_phpQuery updates * Updates covering feedback points and functionality fixes * Feedback updates * Revert "lib_phpQuery updates" This reverts commit dcd23b9418405a2d14ee03c1fcadf90c04b267e1. * First review Change variable name to "remember" instead of "open". Start using localStorage instead of sessionStorage. Simplify code. * Simplify remember categories init function Replace 'session' with 'local' in function names and comment Set open categories CSS as same as when category is opened in 'active' unfold mode * Remove URLSearchParams check in remember categories init function * Delete open categories on login and logout * JSHint check fix * Second review * Make new mode the default for new users * Always open active category * Reduce / simplify code * i18n French * Revert default value Wait a bit more for this decision / change Co-authored-by: Alexandre Alapetite --- app/Models/ConfigurationSetter.php | 2 +- app/Models/Context.php | 2 +- app/i18n/cz/conf.php | 1 + app/i18n/de/conf.php | 1 + app/i18n/en-us/conf.php | 1 + app/i18n/en/conf.php | 1 + app/i18n/es/conf.php | 1 + app/i18n/fr/conf.php | 1 + app/i18n/he/conf.php | 1 + app/i18n/it/conf.php | 1 + app/i18n/kr/conf.php | 1 + app/i18n/nl/conf.php | 1 + app/i18n/oc/conf.php | 1 + app/i18n/pl/conf.php | 1 + app/i18n/pt-br/conf.php | 1 + app/i18n/ru/conf.php | 1 + app/i18n/sk/conf.php | 1 + app/i18n/tr/conf.php | 1 + app/i18n/zh-cn/conf.php | 1 + app/layout/aside_feed.phtml | 8 ++++---- app/views/configure/reading.phtml | 1 + app/views/helpers/javascript_vars.phtml | 1 + cli/i18n/ignore/en-us.php | 1 + config-user.default.php | 2 +- p/scripts/extra.js | 6 ++++++ p/scripts/main.js | 31 +++++++++++++++++++++++++++++++ 26 files changed, 64 insertions(+), 7 deletions(-) diff --git a/app/Models/ConfigurationSetter.php b/app/Models/ConfigurationSetter.php index 1d4b7f667..2a5f59226 100644 --- a/app/Models/ConfigurationSetter.php +++ b/app/Models/ConfigurationSetter.php @@ -183,7 +183,7 @@ class FreshRSS_ConfigurationSetter { } private function _display_categories(&$data, $value) { - if (!in_array($value, [ 'active', 'all', 'none' ], true)) { + if (!in_array($value, [ 'active', 'remember', 'all', 'none' ], true)) { $value = $value === true ? 'all' : 'active'; } $data['display_categories'] = $value; diff --git a/app/Models/Context.php b/app/Models/Context.php index c5dcbdcdb..8be73f407 100644 --- a/app/Models/Context.php +++ b/app/Models/Context.php @@ -71,7 +71,7 @@ class FreshRSS_Context { } //Legacy < 1.16.1 - if (!in_array(FreshRSS_Context::$user_conf->display_categories, [ 'active', 'all', 'none' ], true)) { + if (!in_array(FreshRSS_Context::$user_conf->display_categories, [ 'active', 'remember', 'all', 'none' ], true)) { FreshRSS_Context::$user_conf->display_categories = FreshRSS_Context::$user_conf->display_categories === true ? 'all' : 'active'; } } diff --git a/app/i18n/cz/conf.php b/app/i18n/cz/conf.php index 5bdc115a5..61a2a111a 100644 --- a/app/i18n/cz/conf.php +++ b/app/i18n/cz/conf.php @@ -124,6 +124,7 @@ return array( 'all_articles' => 'Zobrazit všechny články', 'all_categories' => 'All categories', // TODO - Translation 'no_category' => 'No category', // TODO - Translation + 'remember_categories' => 'Remember open categories', // TODO - Translation 'unread' => 'Zobrazit jen nepřečtené', ), 'sides_close_article' => 'Clicking outside of article text area closes the article', // TODO - Translation diff --git a/app/i18n/de/conf.php b/app/i18n/de/conf.php index 60d0a2ac6..82479b899 100644 --- a/app/i18n/de/conf.php +++ b/app/i18n/de/conf.php @@ -124,6 +124,7 @@ return array( 'all_articles' => 'Alle Artikel zeigen', 'all_categories' => 'Alle Kategorien', 'no_category' => 'Keine Kategorie', + 'remember_categories' => 'Remember open categories', // TODO - Translation 'unread' => 'Nur ungelesene zeigen', ), 'sides_close_article' => 'Klick außerhalb des Artikel-Textes schließt den Artikel', diff --git a/app/i18n/en-us/conf.php b/app/i18n/en-us/conf.php index a5a5cb2f9..5053b7afb 100644 --- a/app/i18n/en-us/conf.php +++ b/app/i18n/en-us/conf.php @@ -124,6 +124,7 @@ return array( 'all_articles' => 'Show all articles', 'all_categories' => 'All categories', 'no_category' => 'No category', + 'remember_categories' => 'Remember open categories', 'unread' => 'Show only unread', ), 'sides_close_article' => 'Clicking outside of article text area closes the article', diff --git a/app/i18n/en/conf.php b/app/i18n/en/conf.php index b3e8750db..2bcbd6a80 100644 --- a/app/i18n/en/conf.php +++ b/app/i18n/en/conf.php @@ -124,6 +124,7 @@ return array( 'all_articles' => 'Show all articles', 'all_categories' => 'All categories', 'no_category' => 'No category', + 'remember_categories' => 'Remember open categories', 'unread' => 'Show only unread', ), 'sides_close_article' => 'Clicking outside of article text area closes the article', diff --git a/app/i18n/es/conf.php b/app/i18n/es/conf.php index 28076f9a7..ab4355d3a 100755 --- a/app/i18n/es/conf.php +++ b/app/i18n/es/conf.php @@ -124,6 +124,7 @@ return array( 'all_articles' => 'Mostrar todos los artículos', 'all_categories' => 'All categories', // TODO - Translation 'no_category' => 'No category', // TODO - Translation + 'remember_categories' => 'Remember open categories', // TODO - Translation 'unread' => 'Mostrar solo pendientes', ), 'sides_close_article' => 'Pinchar fuera del área de texto del artículo lo cerrará', diff --git a/app/i18n/fr/conf.php b/app/i18n/fr/conf.php index 9f1d68fb1..2048361ac 100644 --- a/app/i18n/fr/conf.php +++ b/app/i18n/fr/conf.php @@ -124,6 +124,7 @@ return array( 'all_articles' => 'Afficher tous les articles', 'all_categories' => 'Toutes les catégories', 'no_category' => 'Aucune catégorie', + 'remember_categories' => 'Se souvenir des catégories dépliées', 'unread' => 'Afficher les non lus', ), 'sides_close_article' => 'Cliquer hors de la zone de texte ferme l’article', diff --git a/app/i18n/he/conf.php b/app/i18n/he/conf.php index 3d2e87788..4db111d26 100644 --- a/app/i18n/he/conf.php +++ b/app/i18n/he/conf.php @@ -124,6 +124,7 @@ return array( 'all_articles' => 'הצגת כל המאמרים', 'all_categories' => 'All categories', // TODO - Translation 'no_category' => 'No category', // TODO - Translation + 'remember_categories' => 'Remember open categories', // TODO - Translation 'unread' => 'הצגת מאמרים שלא נקראו בלבד', ), 'sides_close_article' => 'Clicking outside of article text area closes the article', // TODO - Translation diff --git a/app/i18n/it/conf.php b/app/i18n/it/conf.php index d3e303b1f..c805511cc 100644 --- a/app/i18n/it/conf.php +++ b/app/i18n/it/conf.php @@ -124,6 +124,7 @@ return array( 'all_articles' => 'Mostra tutti gli articoli', 'all_categories' => 'All categories', // TODO - Translation 'no_category' => 'No category', // TODO - Translation + 'remember_categories' => 'Remember open categories', // TODO - Translation 'unread' => 'Mostra solo non letti', ), 'sides_close_article' => 'Clicking outside of article text area closes the article', // TODO - Translation diff --git a/app/i18n/kr/conf.php b/app/i18n/kr/conf.php index d2786b677..691355809 100644 --- a/app/i18n/kr/conf.php +++ b/app/i18n/kr/conf.php @@ -124,6 +124,7 @@ return array( 'all_articles' => '모든 글 표시', 'all_categories' => 'All categories', // TODO - Translation 'no_category' => 'No category', // TODO - Translation + 'remember_categories' => 'Remember open categories', // TODO - Translation 'unread' => '읽지 않은 글만 표시', ), 'sides_close_article' => '글 영역 바깥을 클릭하면 글 접기', diff --git a/app/i18n/nl/conf.php b/app/i18n/nl/conf.php index 2996dd5a8..939cb76a9 100644 --- a/app/i18n/nl/conf.php +++ b/app/i18n/nl/conf.php @@ -124,6 +124,7 @@ return array( 'all_articles' => 'Bekijk alle artikelen', 'all_categories' => 'Alle categorieën', 'no_category' => 'Geen categorie', + 'remember_categories' => 'Remember open categories', // TODO - Translation 'unread' => 'Bekijk alleen ongelezen', ), 'sides_close_article' => 'Sluit het artikel door buiten de artikeltekst te klikken', diff --git a/app/i18n/oc/conf.php b/app/i18n/oc/conf.php index 27e8976c7..b6d968c9b 100644 --- a/app/i18n/oc/conf.php +++ b/app/i18n/oc/conf.php @@ -124,6 +124,7 @@ return array( 'all_articles' => 'Mostrar totes los articles', 'all_categories' => 'Totas las categorias', 'no_category' => 'Cap de categoria', + 'remember_categories' => 'Remember open categories', // TODO - Translation 'unread' => 'Mostrar pas que los pas legits', ), 'sides_close_article' => 'Clicar fòra de la zòna de tèxte tampa l’article', diff --git a/app/i18n/pl/conf.php b/app/i18n/pl/conf.php index a47ba0df2..9536b1b64 100644 --- a/app/i18n/pl/conf.php +++ b/app/i18n/pl/conf.php @@ -124,6 +124,7 @@ return array( 'all_articles' => 'Wszystkie wiadomości', 'all_categories' => 'Wszystkie', 'no_category' => 'Żadna', + 'remember_categories' => 'Remember open categories', // TODO - Translation 'unread' => 'Tylko nieprzeczytane', ), 'sides_close_article' => 'Kliknięcie poza zawartością wiadomości zamyka widok wiadomości', diff --git a/app/i18n/pt-br/conf.php b/app/i18n/pt-br/conf.php index 077333e88..4b882ca27 100644 --- a/app/i18n/pt-br/conf.php +++ b/app/i18n/pt-br/conf.php @@ -124,6 +124,7 @@ return array( 'all_articles' => 'Exibir todos os artigos', 'all_categories' => 'All categories', // TODO - Translation 'no_category' => 'No category', // TODO - Translation + 'remember_categories' => 'Remember open categories', // TODO - Translation 'unread' => 'Exibir apenas não lido', ), 'sides_close_article' => 'Clicando fora da área do texto do artigo fecha o mesmo', diff --git a/app/i18n/ru/conf.php b/app/i18n/ru/conf.php index 88764c3d4..49be0af7e 100644 --- a/app/i18n/ru/conf.php +++ b/app/i18n/ru/conf.php @@ -124,6 +124,7 @@ return array( 'all_articles' => 'Show all articles', // TODO - Translation 'all_categories' => 'All categories', // TODO - Translation 'no_category' => 'No category', // TODO - Translation + 'remember_categories' => 'Remember open categories', // TODO - Translation 'unread' => 'Show only unread', // TODO - Translation ), 'sides_close_article' => 'Clicking outside of article text area closes the article', // TODO - Translation diff --git a/app/i18n/sk/conf.php b/app/i18n/sk/conf.php index 9d4540cda..a0c68697f 100644 --- a/app/i18n/sk/conf.php +++ b/app/i18n/sk/conf.php @@ -124,6 +124,7 @@ return array( 'all_articles' => 'Zobraziť všetky články', 'all_categories' => 'All categories', // TODO - Translation 'no_category' => 'No category', // TODO - Translation + 'remember_categories' => 'Remember open categories', // TODO - Translation 'unread' => 'Zobraziť iba neprečítané', ), 'sides_close_article' => 'Po kliknutí mimo textu článku sa článok zatvorí', diff --git a/app/i18n/tr/conf.php b/app/i18n/tr/conf.php index 460801890..5141b343d 100644 --- a/app/i18n/tr/conf.php +++ b/app/i18n/tr/conf.php @@ -124,6 +124,7 @@ return array( 'all_articles' => 'Tüm makaleleri göster', 'all_categories' => 'All categories', // TODO - Translation 'no_category' => 'No category', // TODO - Translation + 'remember_categories' => 'Remember open categories', // TODO - Translation 'unread' => 'Sadece okunmamış makaleleri göster', ), 'sides_close_article' => 'Clicking outside of article text area closes the article', // TODO - Translation diff --git a/app/i18n/zh-cn/conf.php b/app/i18n/zh-cn/conf.php index 8a1b91bb1..299f6be84 100644 --- a/app/i18n/zh-cn/conf.php +++ b/app/i18n/zh-cn/conf.php @@ -124,6 +124,7 @@ return array( 'all_articles' => '显示所有', 'all_categories' => 'All categories', // TODO - Translation 'no_category' => 'No category', // TODO - Translation + 'remember_categories' => 'Remember open categories', // TODO - Translation 'unread' => '只显示未读', ), 'sides_close_article' => '点击文章区域外以关闭', diff --git a/app/layout/aside_feed.phtml b/app/layout/aside_feed.phtml index fcc93c6a8..1b413ac86 100644 --- a/app/layout/aside_feed.phtml +++ b/app/layout/aside_feed.phtml @@ -46,9 +46,9 @@ display_categories === 'active') || FreshRSS_Context::$user_conf->display_categories === 'all'; + $t_show = ($t_active && in_array(FreshRSS_Context::$user_conf->display_categories, [ 'active', 'remember' ])) || FreshRSS_Context::$user_conf->display_categories === 'all'; ?> -
  • +
  • @@ -75,9 +75,9 @@ $position = $cat->attributes('position'); if (!empty($feeds)) { $c_active = FreshRSS_Context::isCurrentGet('c_' . $cat->id()); - $c_show = ($c_active && FreshRSS_Context::$user_conf->display_categories === 'active') || FreshRSS_Context::$user_conf->display_categories === 'all'; + $c_show = ($c_active && in_array(FreshRSS_Context::$user_conf->display_categories, [ 'active', 'remember' ])) || FreshRSS_Context::$user_conf->display_categories === 'all'; ?> -
  • data-unread="nbNotRead() ?>"> +
  • data-unread="nbNotRead() ?>">
    name() ?> diff --git a/app/views/configure/reading.phtml b/app/views/configure/reading.phtml index 3cd0a718e..f828556b2 100644 --- a/app/views/configure/reading.phtml +++ b/app/views/configure/reading.phtml @@ -52,6 +52,7 @@
    diff --git a/app/views/helpers/javascript_vars.phtml b/app/views/helpers/javascript_vars.phtml index 24fa140a5..11373b76f 100644 --- a/app/views/helpers/javascript_vars.phtml +++ b/app/views/helpers/javascript_vars.phtml @@ -7,6 +7,7 @@ echo htmlspecialchars(json_encode(array( 'auto_remove_article' => !!FreshRSS_Context::isAutoRemoveAvailable(), 'hide_posts' => !(FreshRSS_Context::$user_conf->display_posts || Minz_Request::actionName() === 'reader'), 'display_order' => Minz_Request::param('order', FreshRSS_Context::$user_conf->sort_order), + 'display_categories' => FreshRSS_Context::$user_conf->display_categories, 'auto_mark_article' => !!$mark['article'], 'auto_mark_site' => !!$mark['site'], 'auto_mark_scroll' => !!$mark['scroll'], diff --git a/cli/i18n/ignore/en-us.php b/cli/i18n/ignore/en-us.php index 474bd959b..93e695bde 100644 --- a/cli/i18n/ignore/en-us.php +++ b/cli/i18n/ignore/en-us.php @@ -235,6 +235,7 @@ return array( 'conf.reading.show.all_articles', 'conf.reading.show.all_categories', 'conf.reading.show.no_category', + 'conf.reading.show.remember_categories', 'conf.reading.show.unread', 'conf.reading.sides_close_article', 'conf.reading.sort._', diff --git a/config-user.default.php b/config-user.default.php index 4bbad05f6..71ec4236b 100644 --- a/config-user.default.php +++ b/config-user.default.php @@ -32,7 +32,7 @@ return array ( 'show_fav_unread' => false, 'auto_load_more' => true, 'display_posts' => false, - 'display_categories' => 'active', //{ active, all, none } + 'display_categories' => 'active', //{ active, remember, all, none } 'hide_read_feeds' => true, 'onread_jump_next' => true, 'lazyload' => true, diff --git a/p/scripts/extra.js b/p/scripts/extra.js index fe4e54739..d34042e05 100644 --- a/p/scripts/extra.js +++ b/p/scripts/extra.js @@ -30,6 +30,10 @@ function poormanSalt() { //If crypto.getRandomValues is not available return text; } +function forgetOpenCategories() { + localStorage.removeItem('FreshRSS_open_categories'); +} + function init_crypto_form() { /* globals dcodeIO */ const crypto_form = document.getElementById('crypto-form'); @@ -45,6 +49,8 @@ function init_crypto_form() { return; } + forgetOpenCategories(); + crypto_form.onsubmit = function (e) { const submit_button = this.querySelector('button[type="submit"]'); submit_button.disabled = true; diff --git a/p/scripts/main.js b/p/scripts/main.js index 6823f3119..21141f210 100644 --- a/p/scripts/main.js +++ b/p/scripts/main.js @@ -692,6 +692,26 @@ function init_posts() { } } +function rememberOpenCategory(category_id, isOpen) { + if (context.display_categories === 'remember') { + const open_categories = JSON.parse(localStorage.getItem('FreshRSS_open_categories') || '{}'); + if (isOpen) { + open_categories[category_id] = true; + } else { + delete open_categories[category_id]; + } + localStorage.setItem('FreshRSS_open_categories', JSON.stringify(open_categories)); + } +} + +function openCategory(category_id) { + const category_element = document.getElementById(category_id); + category_element.querySelector('.tree-folder-items').classList.add('active'); + const img = category_element.querySelector('a.dropdown-toggle img'); + img.src = img.src.replace('/icons/down.', '/icons/up.'); + img.alt = '△'; +} + function init_column_categories() { if (context.current_view !== 'normal' && context.current_view !== 'reader') { return; @@ -700,16 +720,27 @@ function init_column_categories() { //Restore sidebar scroll position document.getElementById('sidebar').scrollTop = +sessionStorage.getItem('FreshRSS_sidebar_scrollTop'); + //Restore open categories + if (context.display_categories === 'remember') { + const open_categories = JSON.parse(localStorage.getItem('FreshRSS_open_categories') || '{}'); + Object.keys(open_categories).forEach(function (category_id) { + openCategory(category_id); + }); + } + document.getElementById('aside_feed').onclick = function (ev) { let a = ev.target.closest('.tree-folder > .tree-folder-title > a.dropdown-toggle'); if (a) { const img = a.querySelector('img'); + const category_id = a.closest('.category').id; if (img.alt === '▽') { img.src = img.src.replace('/icons/down.', '/icons/up.'); img.alt = '△'; + rememberOpenCategory(category_id, true); } else { img.src = img.src.replace('/icons/up.', '/icons/down.'); img.alt = '▽'; + rememberOpenCategory(category_id, false); } const ul = a.closest('li').querySelector('.tree-folder-items'); -- cgit v1.2.3