From a7aca6c0abfd905669004c1e4f7c8328060df27e Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sun, 19 Sep 2021 10:56:38 +0200 Subject: Improved feed action filters (#3303) * Re-order some feed options * Option to auto mark as read existing titles * Option to keep at max n unread articles per feed --- app/Controllers/configureController.php | 9 +- app/Controllers/feedController.php | 26 ++- app/Controllers/subscriptionController.php | 14 ++ app/Models/ConfigurationSetter.php | 6 - app/Models/Entry.php | 6 +- app/Models/Feed.php | 23 ++- app/Models/FeedDAO.php | 53 +++++++ app/i18n/cz/conf.php | 2 + app/i18n/de/conf.php | 2 + app/i18n/en-us/conf.php | 2 + app/i18n/en/conf.php | 2 + app/i18n/es/conf.php | 2 + app/i18n/fr/conf.php | 2 + app/i18n/he/conf.php | 2 + app/i18n/it/conf.php | 2 + app/i18n/ja/conf.php | 2 + app/i18n/kr/conf.php | 2 + app/i18n/nl/conf.php | 2 + app/i18n/oc/conf.php | 2 + app/i18n/pl/conf.php | 2 + app/i18n/pt-br/conf.php | 2 + app/i18n/ru/conf.php | 2 + app/i18n/sk/conf.php | 2 + app/i18n/tr/conf.php | 2 + app/i18n/zh-cn/conf.php | 2 + app/views/configure/reading.phtml | 20 +++ app/views/helpers/feed/update.phtml | 247 ++++++++++++++++------------- cli/i18n/ignore/en-us.php | 2 + config-user.default.php | 6 +- 29 files changed, 322 insertions(+), 126 deletions(-) diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php index 388c34624..79ddf8e17 100755 --- a/app/Controllers/configureController.php +++ b/app/Controllers/configureController.php @@ -121,9 +121,12 @@ class FreshRSS_configure_Controller extends Minz_ActionController { FreshRSS_Context::$user_conf->sort_order = Minz_Request::param('sort_order', 'DESC'); FreshRSS_Context::$user_conf->mark_when = array( 'article' => Minz_Request::param('mark_open_article', false), - 'site' => Minz_Request::param('mark_open_site', false), - 'scroll' => Minz_Request::param('mark_scroll', false), + 'max_n_unread' => Minz_Request::paramBoolean('enable_keep_max_n_unread') ? Minz_Request::param('keep_max_n_unread', false) : false, 'reception' => Minz_Request::param('mark_upon_reception', false), + 'same_title_in_feed' => Minz_Request::paramBoolean('enable_read_when_same_title_in_feed') ? + Minz_Request::param('read_when_same_title_in_feed', false) : false, + 'scroll' => Minz_Request::param('mark_scroll', false), + 'site' => Minz_Request::param('mark_open_site', false), ); FreshRSS_Context::$user_conf->save(); invalidateHttpCache(); @@ -210,7 +213,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController { } elseif (!$keepMax = Minz_Request::param('keep_max')) { $keepMax = FreshRSS_Feed::ARCHIVING_RETENTION_COUNT_LIMIT; } - if ($enableRetentionPeriod = Minz_Request::paramBoolean('enable_keep_period')) { + if (Minz_Request::paramBoolean('enable_keep_period')) { $keepPeriod = FreshRSS_Feed::ARCHIVING_RETENTION_PERIOD; if (is_numeric(Minz_Request::param('keep_period_count')) && preg_match('/^PT?1[YMWDH]$/', Minz_Request::param('keep_period_unit'))) { $keepPeriod = str_replace('1', Minz_Request::param('keep_period_count'), Minz_Request::param('keep_period_unit')); diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index d43f05d4a..afb05f17e 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -359,6 +359,19 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $needFeedCacheRefresh = false; if (count($newGuids) > 0) { + $titlesAsRead = []; + $readWhenSameTitleInFeed = $feed->attributes('read_when_same_title_in_feed'); + if ($readWhenSameTitleInFeed == false) { + $readWhenSameTitleInFeed = FreshRSS_Context::$user_conf->mark_when['same_title_in_feed']; + } + if ($readWhenSameTitleInFeed > 0) { + $titlesAsRead = array_flip($feedDAO->listTitles($feed->id(), $feed->attributes('read_when_same_title_in_feed'))); + } + + $mark_updated_article_unread = $feed->attributes('mark_updated_article_unread') !== null ? ( + $feed->attributes('mark_updated_article_unread') + ) : FreshRSS_Context::$user_conf->mark_updated_article_unread; + // For this feed, check existing GUIDs already in database. $existingHashForGuids = $entryDAO->listHashForFeedGuids($feed->id(), $newGuids); $newGuids = array(); @@ -379,11 +392,11 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } else { //This entry already exists but has been updated //Minz_Log::debug('Entry with GUID `' . $entry->guid() . '` updated in feed ' . $feed->url(false) . //', old hash ' . $existingHash . ', new hash ' . $entry->hash()); - $mark_updated_article_unread = $feed->attributes('mark_updated_article_unread') !== null ? - $feed->attributes('mark_updated_article_unread') : - FreshRSS_Context::$user_conf->mark_updated_article_unread; $needFeedCacheRefresh = $mark_updated_article_unread; $entry->_isRead($mark_updated_article_unread ? false : null); //Change is_read according to policy. + if ($mark_updated_article_unread) { + $feed->incPendingUnread(); //Maybe + } $entry = Minz_ExtensionManager::callHook('entry_before_insert', $entry); if ($entry === null) { @@ -403,7 +416,10 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $id = uTimeString(); $entry->_id($id); - $entry->applyFilterActions(); + $entry->applyFilterActions($titlesAsRead); + if ($readWhenSameTitleInFeed > 0) { + $titlesAsRead[$entry->title()] = true; + } $entry = Minz_ExtensionManager::callHook('entry_before_insert', $entry); if ($entry === null) { @@ -424,6 +440,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $entryDAO->beginTransaction(); } $entryDAO->addEntry($entry->toArray()); + $feed->incPendingUnread(); $nb_new_articles++; } } @@ -445,6 +462,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { if ($needFeedCacheRefresh) { $feedDAO->updateCachedValues($feed->id()); } + $feed->keepMaxUnread(); if ($entryDAO->inTransaction()) { $entryDAO->commit(); } diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php index f47988926..4bb08f495 100644 --- a/app/Controllers/subscriptionController.php +++ b/app/Controllers/subscriptionController.php @@ -112,6 +112,20 @@ class FreshRSS_subscription_Controller extends Minz_ActionController { $feed->_attributes('read_upon_reception', Minz_Request::paramTernary('read_upon_reception')); $feed->_attributes('clear_cache', Minz_Request::paramTernary('clear_cache')); + $keep_max_n_unread = intval(Minz_Request::param('keep_max_n_unread', 0)); + $feed->_attributes('keep_max_n_unread', $keep_max_n_unread > 0 ? $keep_max_n_unread : null); + + $read_when_same_title_in_feed = Minz_Request::param('read_when_same_title_in_feed', ''); + if ($read_when_same_title_in_feed === '') { + $read_when_same_title_in_feed = null; + } else { + $read_when_same_title_in_feed = intval($read_when_same_title_in_feed); + if ($read_when_same_title_in_feed <= 0) { + $read_when_same_title_in_feed = false; + } + } + $feed->_attributes('read_when_same_title_in_feed', $read_when_same_title_in_feed); + $cookie = Minz_Request::param('curl_params_cookie', ''); $useragent = Minz_Request::param('curl_params_useragent', ''); $proxy_address = Minz_Request::param('curl_params', ''); diff --git a/app/Models/ConfigurationSetter.php b/app/Models/ConfigurationSetter.php index ee58ebe5b..535f17e2e 100644 --- a/app/Models/ConfigurationSetter.php +++ b/app/Models/ConfigurationSetter.php @@ -205,12 +205,6 @@ class FreshRSS_ConfigurationSetter { $data['lazyload'] = $this->handleBool($value); } - private function _mark_when(&$data, $values) { - foreach ($values as $key => $value) { - $data['mark_when'][$key] = $this->handleBool($value); - } - } - private function _onread_jump_next(&$data, $value) { $data['onread_jump_next'] = $this->handleBool($value); } diff --git a/app/Models/Entry.php b/app/Models/Entry.php index 66e554e22..f75c0d704 100644 --- a/app/Models/Entry.php +++ b/app/Models/Entry.php @@ -341,12 +341,16 @@ class FreshRSS_Entry extends Minz_Model { return false; } - public function applyFilterActions() { + public function applyFilterActions($titlesAsRead = []) { if ($this->feed != null) { if ($this->feed->attributes('read_upon_reception') || ($this->feed->attributes('read_upon_reception') === null && FreshRSS_Context::$user_conf->mark_when['reception'])) { $this->_isRead(true); } + if (isset($titlesAsRead[$this->title()])) { + Minz_Log::debug('Mark title as read: ' . $this->title()); + $this->_isRead(true); + } foreach ($this->feed->filterActions() as $filterAction) { if ($this->matches($filterAction->booleanSearch())) { foreach ($filterAction->actions() as $action) { diff --git a/app/Models/Feed.php b/app/Models/Feed.php index 012bdced8..423b913b0 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -15,6 +15,7 @@ class FreshRSS_Feed extends Minz_Model { private $category = 1; private $nbEntries = -1; private $nbNotRead = -1; + private $nbPendingNotRead = 0; private $name = ''; private $website = ''; private $description = ''; @@ -141,13 +142,13 @@ class FreshRSS_Feed extends Minz_Model { return $this->nbEntries; } - public function nbNotRead() { + public function nbNotRead($includePending = false) { if ($this->nbNotRead < 0) { $feedDAO = FreshRSS_Factory::createFeedDao(); $this->nbNotRead = $feedDAO->countNotRead($this->id()); } - return $this->nbNotRead; + return $this->nbNotRead + ($includePending ? $this->nbPendingNotRead : 0); } public function faviconPrepare() { require_once(LIB_PATH . '/favicons.php'); @@ -475,6 +476,24 @@ class FreshRSS_Feed extends Minz_Model { } } + /** + * To keep track of some new potentially unread articles since last commit+fetch from database + */ + public function incPendingUnread($n = 1) { + $this->nbPendingNotRead += $n; + } + + public function keepMaxUnread() { + $keepMaxUnread = $this->attributes('keep_max_n_unread'); + if ($keepMaxUnread == false) { + $keepMaxUnread = FreshRSS_Context::$user_conf->mark_when['max_n_unread']; + } + if ($keepMaxUnread > 0 && $this->nbNotRead(false) + $this->nbPendingNotRead > $keepMaxUnread) { + $feedDAO = FreshRSS_Factory::createFeedDao(); + $feedDAO->keepMaxUnread($this->id(), max(0, $keepMaxUnread - $this->nbPendingNotRead)); + } + } + public function cleanOldEntries() { //Remember to call updateCachedValue($id_feed) or updateCachedValues() just after $archiving = $this->attributes('archiving'); if ($archiving == null) { diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php index af599c2a6..0d65e171d 100644 --- a/app/Models/FeedDAO.php +++ b/app/Models/FeedDAO.php @@ -363,6 +363,19 @@ SQL; } } + public function listTitles($id, $limit = null) { + $sql = 'SELECT title FROM `_entry` WHERE id_feed=:id_feed ORDER BY id DESC' + . ($limit < 1 ? '' : ' LIMIT ' . intval($limit)); + + $stm = $this->pdo->prepare($sql); + $stm->bindParam(':id_feed', $id, PDO::PARAM_INT); + + if ($stm && $stm->execute()) { + return $stm->fetchAll(PDO::FETCH_COLUMN, 0); + } + return false; + } + public function listByCategory($cat) { $sql = 'SELECT * FROM `_feed` WHERE category=?'; $stm = $this->pdo->prepare($sql); @@ -418,6 +431,46 @@ SQL; } } + public function keepMaxUnread($id, $n) { + //Double SELECT for MySQL workaround ERROR 1093 (HY000) + $sql = <<<'SQL' +UPDATE `_entry` SET is_read=1 +WHERE id_feed=:id_feed1 AND is_read=0 AND id <= (SELECT e3.id FROM ( + SELECT e2.id FROM `_entry` e2 + WHERE e2.id_feed=:id_feed2 AND e2.is_read=0 + ORDER BY e2.id DESC + LIMIT 1 + OFFSET :limit) e3) +SQL; + + $stm = $this->pdo->prepare($sql); + $stm->bindParam(':id_feed1', $id, PDO::PARAM_INT); + $stm->bindParam(':id_feed2', $id, PDO::PARAM_INT); + $stm->bindParam(':limit', $n, PDO::PARAM_INT); + + if (!$stm || !$stm->execute()) { + $info = $stm == null ? $this->pdo->errorInfo() : $stm->errorInfo(); + Minz_Log::error('SQL error keepMaxUnread: ' . json_encode($info)); + return false; + } + $affected = $stm->rowCount(); + + if ($affected > 0) { + $sql = 'UPDATE `_feed` ' + . 'SET `cache_nbUnreads`=`cache_nbUnreads`-' . $affected + . ' WHERE id=:id'; + $stm = $this->pdo->prepare($sql); + $stm->bindParam(':id', $id_feed, PDO::PARAM_INT); + if (!($stm && $stm->execute())) { + $info = $stm == null ? $this->pdo->errorInfo() : $stm->errorInfo(); + Minz_Log::error('SQL error keepMaxUnread cache: ' . json_encode($info)); + return false; + } + } + + return $affected; + } + public function truncate($id) { $sql = 'DELETE FROM `_entry` WHERE id_feed=:id'; $stm = $this->pdo->prepare($sql); diff --git a/app/i18n/cz/conf.php b/app/i18n/cz/conf.php index 01175cfef..bc52106e0 100644 --- a/app/i18n/cz/conf.php +++ b/app/i18n/cz/conf.php @@ -127,9 +127,11 @@ return array( 'read' => array( 'article_open_on_website' => 'když je otevřen původní web s článkem', 'article_viewed' => 'během čtení článku', + 'keep_max_n_unread' => 'Max number of articles to keep unread', // TODO - Translation 'scroll' => 'během skrolování', 'upon_reception' => 'po načtení článku', 'when' => 'Označit článek jako přečtený…', + 'when_same_title' => 'if an identical title already exists in the top n newest articles', // TODO - Translation ), 'show' => array( '_' => 'Počet zobrazených článků', diff --git a/app/i18n/de/conf.php b/app/i18n/de/conf.php index 5ccb3e738..09194ea8c 100644 --- a/app/i18n/de/conf.php +++ b/app/i18n/de/conf.php @@ -127,9 +127,11 @@ return array( 'read' => array( 'article_open_on_website' => 'wenn der Artikel auf der Original-Webseite geöffnet wird', 'article_viewed' => 'wenn der Artikel angesehen wird', + 'keep_max_n_unread' => 'Max number of articles to keep unread', // TODO - Translation 'scroll' => 'beim Scrollen bzw. Überspringen', 'upon_reception' => 'beim Empfang des Artikels', 'when' => 'Artikel als gelesen markieren…', + 'when_same_title' => 'if an identical title already exists in the top n newest articles', // TODO - Translation ), 'show' => array( '_' => 'Artikel zum Anzeigen', diff --git a/app/i18n/en-us/conf.php b/app/i18n/en-us/conf.php index c826d1098..e7f1a2b72 100644 --- a/app/i18n/en-us/conf.php +++ b/app/i18n/en-us/conf.php @@ -127,9 +127,11 @@ return array( 'read' => array( 'article_open_on_website' => 'when the article is opened on its original website', 'article_viewed' => 'when the article is viewed', + 'keep_max_n_unread' => 'Max number of articles to keep unread', 'scroll' => 'while scrolling', 'upon_reception' => 'upon receiving the article', 'when' => 'Mark an article as read…', + 'when_same_title' => 'if an identical title already exists in the top n newest articles', ), 'show' => array( '_' => 'Articles to display', diff --git a/app/i18n/en/conf.php b/app/i18n/en/conf.php index e6beeb6c1..03905d671 100644 --- a/app/i18n/en/conf.php +++ b/app/i18n/en/conf.php @@ -127,9 +127,11 @@ return array( 'read' => array( 'article_open_on_website' => 'when the article is opened on its original website', 'article_viewed' => 'when the article is viewed', + 'keep_max_n_unread' => 'Max number of articles to keep unread', 'scroll' => 'while scrolling', 'upon_reception' => 'upon receiving the article', 'when' => 'Mark an article as read…', + 'when_same_title' => 'if an identical title already exists in the top n newest articles', ), 'show' => array( '_' => 'Articles to display', diff --git a/app/i18n/es/conf.php b/app/i18n/es/conf.php index b05844592..e3fa6e9fe 100755 --- a/app/i18n/es/conf.php +++ b/app/i18n/es/conf.php @@ -127,9 +127,11 @@ return array( 'read' => array( 'article_open_on_website' => 'cuando el artículo se abra en su web original', 'article_viewed' => 'cuando se muestre el artículo', + 'keep_max_n_unread' => 'Max number of articles to keep unread', // TODO - Translation 'scroll' => 'durante el desplazamiento', 'upon_reception' => 'al recibir el artículo', 'when' => 'Marcar el artículo como leído…', + 'when_same_title' => 'if an identical title already exists in the top n newest articles', // TODO - Translation ), 'show' => array( '_' => 'Artículos a mostrar', diff --git a/app/i18n/fr/conf.php b/app/i18n/fr/conf.php index 78d8bff1a..ea6a54862 100644 --- a/app/i18n/fr/conf.php +++ b/app/i18n/fr/conf.php @@ -127,9 +127,11 @@ return array( 'read' => array( 'article_open_on_website' => 'lorsque l’article est ouvert sur le site d’origine', 'article_viewed' => 'lorsque l’article est affiché', + 'keep_max_n_unread' => 'Nombre maximum d’articles conservés non lus', 'scroll' => 'au défilement de la page', 'upon_reception' => 'dès la réception du nouvel article', 'when' => 'Marquer un article comme lu…', + 'when_same_title' => 'si un même titre existe déjà dans les n articles plus récents', ), 'show' => array( '_' => 'Articles à afficher', diff --git a/app/i18n/he/conf.php b/app/i18n/he/conf.php index 4d3dfb5c1..3dbf8127a 100644 --- a/app/i18n/he/conf.php +++ b/app/i18n/he/conf.php @@ -127,9 +127,11 @@ return array( 'read' => array( 'article_open_on_website' => 'כאשר מאמר נפתח באתר המקורי', 'article_viewed' => 'כאשר מאמר נצפה', + 'keep_max_n_unread' => 'Max number of articles to keep unread', // TODO - Translation 'scroll' => 'כאשר גוללים', 'upon_reception' => 'כאשר המאמר מתקבל', 'when' => 'סימון מאמרים כנקראו…', + 'when_same_title' => 'if an identical title already exists in the top n newest articles', // TODO - Translation ), 'show' => array( '_' => 'מאמרים להצגה', diff --git a/app/i18n/it/conf.php b/app/i18n/it/conf.php index d24dda3a1..f10132fdc 100644 --- a/app/i18n/it/conf.php +++ b/app/i18n/it/conf.php @@ -127,9 +127,11 @@ return array( 'read' => array( 'article_open_on_website' => 'Quando un articolo è aperto nel suo sito di origine', 'article_viewed' => 'Quando un articolo viene letto', + 'keep_max_n_unread' => 'Max number of articles to keep unread', // TODO - Translation 'scroll' => 'Scorrendo la pagina', 'upon_reception' => 'Alla ricezione del contenuto', 'when' => 'Segna articoli come letti…', + 'when_same_title' => 'if an identical title already exists in the top n newest articles', // TODO - Translation ), 'show' => array( '_' => 'Articoli da visualizzare', diff --git a/app/i18n/ja/conf.php b/app/i18n/ja/conf.php index 81c85d2a7..244f9b87a 100644 --- a/app/i18n/ja/conf.php +++ b/app/i18n/ja/conf.php @@ -127,9 +127,11 @@ return array( 'read' => array( 'article_open_on_website' => '記事を元のwebサイトで開いたとき', 'article_viewed' => '記事を読んだとき', + 'keep_max_n_unread' => 'Max number of articles to keep unread', // TODO - Translation 'scroll' => 'スクロールしているとき', 'upon_reception' => '記事を受け取ったとき', 'when' => '記事を既読にする…', + 'when_same_title' => 'if an identical title already exists in the top n newest articles', // TODO - Translation ), 'show' => array( '_' => '記事を表示する', diff --git a/app/i18n/kr/conf.php b/app/i18n/kr/conf.php index 4e6623034..fb88275b5 100644 --- a/app/i18n/kr/conf.php +++ b/app/i18n/kr/conf.php @@ -127,9 +127,11 @@ return array( 'read' => array( 'article_open_on_website' => '글이 게재된 웹사이트를 방문했을 때', 'article_viewed' => '글을 읽었을 때', + 'keep_max_n_unread' => 'Max number of articles to keep unread', // TODO - Translation 'scroll' => '스크롤을 하며 지나갈 때', 'upon_reception' => '글을 가져오자마자', 'when' => '읽음으로 표시…', + 'when_same_title' => 'if an identical title already exists in the top n newest articles', // TODO - Translation ), 'show' => array( '_' => '글 표시 방식', diff --git a/app/i18n/nl/conf.php b/app/i18n/nl/conf.php index 9472a0d73..31c47608b 100644 --- a/app/i18n/nl/conf.php +++ b/app/i18n/nl/conf.php @@ -127,9 +127,11 @@ return array( 'read' => array( 'article_open_on_website' => 'als het artikel wordt geopend op de originele website', 'article_viewed' => 'als het artikel wordt bekeken', + 'keep_max_n_unread' => 'Max number of articles to keep unread', // TODO - Translation 'scroll' => 'tijdens het scrollen', 'upon_reception' => 'bij ontvangst van het artikel', 'when' => 'Markeer artikel als gelezen…', + 'when_same_title' => 'if an identical title already exists in the top n newest articles', // TODO - Translation ), 'show' => array( '_' => 'Artikelen om te tonen', diff --git a/app/i18n/oc/conf.php b/app/i18n/oc/conf.php index 07a62cddb..549614ae9 100644 --- a/app/i18n/oc/conf.php +++ b/app/i18n/oc/conf.php @@ -127,9 +127,11 @@ return array( 'read' => array( 'article_open_on_website' => 'quand l’article es dobèrt sul site d’origina', 'article_viewed' => 'quand l’article es mostrat', + 'keep_max_n_unread' => 'Max number of articles to keep unread', // TODO - Translation 'scroll' => 'en davalar la pagina', 'upon_reception' => 'en recebre un article novèl', 'when' => 'Marcar un article coma legit…', + 'when_same_title' => 'if an identical title already exists in the top n newest articles', // TODO - Translation ), 'show' => array( '_' => 'Articles de mostrar', diff --git a/app/i18n/pl/conf.php b/app/i18n/pl/conf.php index c50132a17..7908b44ee 100644 --- a/app/i18n/pl/conf.php +++ b/app/i18n/pl/conf.php @@ -127,9 +127,11 @@ return array( 'read' => array( 'article_open_on_website' => 'gdy wiadomość jest otworzona na pierwotnej stronie', 'article_viewed' => 'gdy wiadomość jest otworzona', + 'keep_max_n_unread' => 'Max number of articles to keep unread', // TODO - Translation 'scroll' => 'podczas przewijania', 'upon_reception' => 'po otrzymaniu wiadomości', 'when' => 'Oznacz wiadomość jako przeczytaną…', + 'when_same_title' => 'if an identical title already exists in the top n newest articles', // TODO - Translation ), 'show' => array( '_' => 'Wiadomości do wyświetlenia', diff --git a/app/i18n/pt-br/conf.php b/app/i18n/pt-br/conf.php index e5008eb03..34eaaa745 100644 --- a/app/i18n/pt-br/conf.php +++ b/app/i18n/pt-br/conf.php @@ -127,9 +127,11 @@ return array( 'read' => array( 'article_open_on_website' => 'quando o artigo é aberto no site original', 'article_viewed' => 'Quando o artigo é visualizado', + 'keep_max_n_unread' => 'Max number of articles to keep unread', // TODO - Translation 'scroll' => 'enquanto scrolling', 'upon_reception' => 'ao receber um artigo', 'when' => 'Marcar artigo como lido…', + 'when_same_title' => 'if an identical title already exists in the top n newest articles', // TODO - Translation ), 'show' => array( '_' => 'Artigos para exibir', diff --git a/app/i18n/ru/conf.php b/app/i18n/ru/conf.php index 9772c39ed..242bf063e 100644 --- a/app/i18n/ru/conf.php +++ b/app/i18n/ru/conf.php @@ -127,9 +127,11 @@ return array( 'read' => array( 'article_open_on_website' => 'когда статья открывается на её сайте', 'article_viewed' => 'когда статья просматривается', + 'keep_max_n_unread' => 'Max number of articles to keep unread', // TODO - Translation 'scroll' => 'во время прокрутки', 'upon_reception' => 'по получении статьи', 'when' => 'Отмечать статью прочитанной…', + 'when_same_title' => 'if an identical title already exists in the top n newest articles', // TODO - Translation ), 'show' => array( '_' => 'Какие статьи отображать', diff --git a/app/i18n/sk/conf.php b/app/i18n/sk/conf.php index e6b7d5b06..bddd51b26 100644 --- a/app/i18n/sk/conf.php +++ b/app/i18n/sk/conf.php @@ -127,9 +127,11 @@ return array( 'read' => array( 'article_open_on_website' => 'keď je článok otvorený na svojej webovej stránke', 'article_viewed' => 'keď je článok zobrazený', + 'keep_max_n_unread' => 'Max number of articles to keep unread', // TODO - Translation 'scroll' => 'počas skrolovania', 'upon_reception' => 'po načítaní článku', 'when' => 'Označiť článok ako prečítaný…', + 'when_same_title' => 'if an identical title already exists in the top n newest articles', // TODO - Translation ), 'show' => array( '_' => 'Článkov na zobrazenie', diff --git a/app/i18n/tr/conf.php b/app/i18n/tr/conf.php index 3c7ca101a..3379a19e3 100644 --- a/app/i18n/tr/conf.php +++ b/app/i18n/tr/conf.php @@ -127,9 +127,11 @@ return array( 'read' => array( 'article_open_on_website' => 'orijinal makale sitesi açıldığında', 'article_viewed' => 'makale görüntülendiğinde', + 'keep_max_n_unread' => 'Max number of articles to keep unread', // TODO - Translation 'scroll' => 'kaydırma yapılırken', 'upon_reception' => 'makale üzerinde gelince', 'when' => 'Makaleyi okundu olarak işaretle…', + 'when_same_title' => 'if an identical title already exists in the top n newest articles', // TODO - Translation ), 'show' => array( '_' => 'Gösterilecek makaleler', diff --git a/app/i18n/zh-cn/conf.php b/app/i18n/zh-cn/conf.php index 6c95b1576..45d287b8d 100644 --- a/app/i18n/zh-cn/conf.php +++ b/app/i18n/zh-cn/conf.php @@ -127,9 +127,11 @@ return array( 'read' => array( 'article_open_on_website' => '在打开原文章后', 'article_viewed' => '在文章被浏览后', + 'keep_max_n_unread' => 'Max number of articles to keep unread', // TODO - Translation 'scroll' => '在滚动浏览后', 'upon_reception' => '在接收文章后', 'when' => '何时将文章标记为已读', + 'when_same_title' => 'if an identical title already exists in the top n newest articles', // TODO - Translation ), 'show' => array( '_' => '文章显示', diff --git a/app/views/configure/reading.phtml b/app/views/configure/reading.phtml index 68d878eb0..e19a14067 100644 --- a/app/views/configure/reading.phtml +++ b/app/views/configure/reading.phtml @@ -207,12 +207,32 @@ data-leave-validation="mark_when['scroll'] ?>"/> + + + + + diff --git a/app/views/helpers/feed/update.phtml b/app/views/helpers/feed/update.phtml index 4bc9913c1..44e3c6c92 100644 --- a/app/views/helpers/feed/update.phtml +++ b/app/views/helpers/feed/update.phtml @@ -79,6 +79,43 @@ +
+ +
+ + +
+
+ + feed->pubSubHubbubEnabled()) { ?> +
+
+ +
+
+ +
@@ -90,6 +127,101 @@
+ + feed->httpAuth(false); ?> +
+ +
+ +

+
+ + +
+ +
+
+ +
+
+ + +
+
+ + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +

+
+
+ +
+
+ + +
+
+
@@ -220,43 +352,6 @@
-
- -
- - -
-
- - feed->pubSubHubbubEnabled()) { ?> -
-
- -
-
- -
@@ -265,30 +360,6 @@
- - feed->httpAuth(false); ?> -
- -
- -

-
- - -
- -
-
- -
-
- - -
-
-
@@ -328,43 +399,7 @@
- -
- -
-
- -
- -
- -
-
- -
-
- -
-
- -
- +
- +
-

+
- +
diff --git a/cli/i18n/ignore/en-us.php b/cli/i18n/ignore/en-us.php index 590a33f30..c7e978585 100644 --- a/cli/i18n/ignore/en-us.php +++ b/cli/i18n/ignore/en-us.php @@ -224,9 +224,11 @@ return array( 'conf.reading.number_divided_when_reader', 'conf.reading.read.article_open_on_website', 'conf.reading.read.article_viewed', + 'conf.reading.read.keep_max_n_unread', 'conf.reading.read.scroll', 'conf.reading.read.upon_reception', 'conf.reading.read.when', + 'conf.reading.read.when_same_title', 'conf.reading.show._', 'conf.reading.show.active_category', 'conf.reading.show.adaptive', diff --git a/config-user.default.php b/config-user.default.php index d7831cee9..ef2218bab 100644 --- a/config-user.default.php +++ b/config-user.default.php @@ -49,9 +49,11 @@ return array ( 'anon_access' => false, 'mark_when' => array ( 'article' => true, - 'site' => true, - 'scroll' => true, + 'max_n_unread' => false, 'reception' => false, + 'same_title_in_feed' => false, + 'scroll' => true, + 'site' => true, ), 'theme' => 'Origine', 'content_width' => 'thin', -- cgit v1.2.3