summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Marien Fressinaud <dev@marienfressinaud.fr> 2014-10-24 15:17:07 +0200
committerGravatar Marien Fressinaud <dev@marienfressinaud.fr> 2014-10-24 15:17:07 +0200
commit3e2d34c8671acae33568fdeb1398afad8296d9bf (patch)
tree6a8fa1430115d12e78855362e093dae9667008f8
parent5d7d01be296a23058026e0dc610b2e2077b3262c (diff)
parent83d95ca4b894a84de467a97c7f413c1d04c43631 (diff)
Merge branch '634-refactor-with-context' into dev
-rwxr-xr-xapp/Controllers/configureController.php5
-rwxr-xr-xapp/Controllers/entryController.php14
-rw-r--r--app/Controllers/errorController.php2
-rwxr-xr-xapp/Controllers/indexController.php351
-rw-r--r--app/Exceptions/ContextException.php10
-rw-r--r--app/FreshRSS.php14
-rw-r--r--app/Models/Configuration.php21
-rw-r--r--app/Models/Context.php250
-rw-r--r--app/Models/Entry.php3
-rw-r--r--app/Models/EntryDAO.php2
-rw-r--r--app/layout/aside_feed.phtml95
-rw-r--r--app/layout/aside_flux.phtml103
-rw-r--r--app/layout/aside_subscription.phtml2
-rw-r--r--app/layout/layout.phtml19
-rw-r--r--app/layout/nav_menu.phtml205
-rw-r--r--app/views/configure/reading.phtml6
-rwxr-xr-xapp/views/helpers/pagination.phtml30
-rw-r--r--app/views/helpers/view/global_view.phtml53
-rw-r--r--app/views/index/global.phtml53
-rw-r--r--app/views/index/index.phtml2
-rw-r--r--app/views/index/normal.phtml (renamed from app/views/helpers/view/normal_view.phtml)20
-rw-r--r--app/views/index/reader.phtml (renamed from app/views/helpers/view/reader_view.phtml)2
-rwxr-xr-xapp/views/index/rss.phtml (renamed from app/views/helpers/view/rss_view.phtml)0
-rw-r--r--lib/Minz/Request.php7
-rw-r--r--lib/lib_rss.php4
-rw-r--r--p/scripts/global_view.js5
-rw-r--r--p/scripts/main.js71
-rw-r--r--p/themes/Dark/dark.css194
-rw-r--r--p/themes/Flat/flat.css184
-rw-r--r--p/themes/Origine/origine.css188
-rw-r--r--p/themes/Pafat/pafat.css247
-rw-r--r--p/themes/Screwdriver/screwdriver.css226
-rw-r--r--p/themes/base-theme/base.css157
-rw-r--r--p/themes/base-theme/template.css150
34 files changed, 1415 insertions, 1280 deletions
diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php
index 8a9dcdc62..cafd0e8a8 100755
--- a/app/Controllers/configureController.php
+++ b/app/Controllers/configureController.php
@@ -104,7 +104,7 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
if (Minz_Request::isPost()) {
FreshRSS_Context::$conf->_posts_per_page(Minz_Request::param('posts_per_page', 10));
FreshRSS_Context::$conf->_view_mode(Minz_Request::param('view_mode', 'normal'));
- FreshRSS_Context::$conf->_default_view((int)Minz_Request::param('default_view', FreshRSS_Entry::STATE_ALL));
+ FreshRSS_Context::$conf->_default_view(Minz_Request::param('default_view', 'adaptive'));
FreshRSS_Context::$conf->_auto_load_more(Minz_Request::param('auto_load_more', false));
FreshRSS_Context::$conf->_display_posts(Minz_Request::param('display_posts', false));
FreshRSS_Context::$conf->_display_categories(Minz_Request::param('display_categories', false));
@@ -338,9 +338,6 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
unset($query[$key]);
}
}
- if (!empty($query['state']) && $query['state'] & FreshRSS_Entry::STATE_STRICT) {
- $query['state'] -= FreshRSS_Entry::STATE_STRICT;
- }
$queries[] = $query;
FreshRSS_Context::$conf->_queries($queries);
FreshRSS_Context::$conf->save();
diff --git a/app/Controllers/entryController.php b/app/Controllers/entryController.php
index 449029648..d11f3a520 100755
--- a/app/Controllers/entryController.php
+++ b/app/Controllers/entryController.php
@@ -17,14 +17,6 @@ class FreshRSS_entry_Controller extends Minz_ActionController {
);
}
- // Keep parameter information (output) to do a correct redirection at
- // the end.
- $this->params = array();
- $output = Minz_Request::param('output', '');
- if ($output != '' && FreshRSS_Context::$conf->view_mode !== $output) {
- $this->params['output'] = $output;
- }
-
// If ajax request, we do not print layout
$this->ajax = Minz_Request::param('ajax');
if ($this->ajax) {
@@ -53,6 +45,7 @@ class FreshRSS_entry_Controller extends Minz_ActionController {
$get = Minz_Request::param('get');
$next_get = Minz_Request::param('nextGet', $get);
$id_max = Minz_Request::param('idMax', 0);
+ $params = array();
$entryDAO = FreshRSS_Factory::createEntryDao();
if ($id === false) {
@@ -86,7 +79,7 @@ class FreshRSS_entry_Controller extends Minz_ActionController {
// Redirect to the correct page (category, feed or starred)
// Not "a" because it is the default value if nothing is
// given.
- $this->params['get'] = $next_get;
+ $params['get'] = $next_get;
}
}
} else {
@@ -98,7 +91,7 @@ class FreshRSS_entry_Controller extends Minz_ActionController {
Minz_Request::good(_t('feeds_marked_read'), array(
'c' => 'index',
'a' => 'index',
- 'params' => $this->params,
+ 'params' => $params,
), true);
}
}
@@ -123,7 +116,6 @@ class FreshRSS_entry_Controller extends Minz_ActionController {
Minz_Request::forward(array(
'c' => 'index',
'a' => 'index',
- 'params' => $this->params,
), true);
}
}
diff --git a/app/Controllers/errorController.php b/app/Controllers/errorController.php
index 76ab930e0..6c080bea8 100644
--- a/app/Controllers/errorController.php
+++ b/app/Controllers/errorController.php
@@ -37,7 +37,7 @@ class FreshRSS_error_Controller extends Minz_ActionController {
if ($this->view->errorMessage == '') {
switch($code_int) {
case 403:
- $this->view->errorMessage = _t('forbidden_access');
+ $this->view->errorMessage = _t('access_denied');
break;
case 404:
default:
diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php
index f994e257c..1cf618f7f 100755
--- a/app/Controllers/indexController.php
+++ b/app/Controllers/indexController.php
@@ -1,217 +1,220 @@
<?php
+/**
+ * This class handles main actions of FreshRSS.
+ */
class FreshRSS_index_Controller extends Minz_ActionController {
- private $nb_not_read_cat = 0;
+ /**
+ * This action only redirect on the default view mode (normal or global)
+ */
public function indexAction() {
- $output = Minz_Request::param('output');
- $token = FreshRSS_Context::$conf->token;
+ $prefered_output = FreshRSS_Context::$conf->view_mode;
+ Minz_Request::forward(array(
+ 'c' => 'index',
+ 'a' => $prefered_output
+ ));
+ }
- // check if user is logged in
+ /**
+ * This action displays the normal view of FreshRSS.
+ */
+ public function normalAction() {
if (!FreshRSS_Auth::hasAccess() && !Minz_Configuration::allowAnonymous()) {
- $token_param = Minz_Request::param('token', '');
- $token_is_ok = ($token != '' && $token === $token_param);
- if ($output === 'rss' && !$token_is_ok) {
- Minz_Error::error(
- 403,
- array('error' => array(_t('access_denied')))
- );
- return;
- } elseif ($output !== 'rss') {
- // "hard" redirection is not required, just ask dispatcher to
- // forward to the login form without 302 redirection
- Minz_Request::forward(array('c' => 'auth', 'a' => 'login'));
- return;
- }
+ Minz_Request::forward(array('c' => 'auth', 'a' => 'login'));
+ return;
}
- $params = Minz_Request::params();
- if (isset($params['search'])) {
- $params['search'] = urlencode($params['search']);
+ try {
+ $this->updateContext();
+ } catch (FreshRSS_Context_Exception $e) {
+ Minz_Error::error(404);
}
- $this->view->url = array(
- 'c' => 'index',
- 'a' => 'index',
- 'params' => $params
- );
+ try {
+ $entries = $this->listEntriesByContext();
+
+ $nb_entries = count($entries);
+ if ($nb_entries > FreshRSS_Context::$number) {
+ // We have more elements for pagination
+ $last_entry = array_pop($entries);
+ FreshRSS_Context::$next_id = $last_entry->id();
+ }
+
+ $first_entry = $nb_entries > 0 ? $entries[0] : null;
+ FreshRSS_Context::$id_max = $first_entry === null ?
+ (time() - 1) . '000000' :
+ $first_entry->id();
+ if (FreshRSS_Context::$order === 'ASC') {
+ // In this case we do not know but we guess id_max
+ $id_max = (time() - 1) . '000000';
+ if (strcmp($id_max, FreshRSS_Context::$id_max) > 0) {
+ FreshRSS_Context::$id_max = $id_max;
+ }
+ }
+
+ $this->view->entries = $entries;
+ } catch (FreshRSS_EntriesGetter_Exception $e) {
+ Minz_Log::notice($e->getMessage());
+ Minz_Error::error(404);
+ }
+
+ $this->view->categories = FreshRSS_Context::$categories;
- if ($output === 'rss') {
- // no layout for RSS output
- $this->view->_useLayout(false);
- header('Content-Type: application/rss+xml; charset=utf-8');
- } elseif ($output === 'global') {
- Minz_View::appendScript(Minz_Url::display('/scripts/global_view.js?' . @filemtime(PUBLIC_PATH . '/scripts/global_view.js')));
+ $this->view->rss_title = FreshRSS_Context::$name . ' | ' . Minz_View::title();
+ $title = FreshRSS_Context::$name;
+ if (FreshRSS_Context::$get_unread > 0) {
+ $title = '(' . FreshRSS_Context::$get_unread . ') ' . $title;
}
+ Minz_View::prependTitle($title . ' · ');
+ }
- $catDAO = new FreshRSS_CategoryDAO();
- $entryDAO = FreshRSS_Factory::createEntryDao();
+ /**
+ * This action displays the reader view of FreshRSS.
+ *
+ * @todo: change this view into specific CSS rules?
+ */
+ public function readerAction() {
+ $this->normalAction();
+ }
- $this->view->cat_aside = $catDAO->listCategories();
- $this->view->nb_favorites = $entryDAO->countUnreadReadFavorites();
- $this->view->nb_not_read = FreshRSS_CategoryDAO::CountUnreads($this->view->cat_aside, 1);
- $this->view->currentName = '';
-
- $this->view->get_c = '';
- $this->view->get_f = '';
-
- $get = Minz_Request::param('get', 'a');
- $getType = $get[0];
- $getId = substr($get, 2);
- if (!$this->checkAndProcessType($getType, $getId)) {
- Minz_Log::debug('Not found [' . $getType . '][' . $getId . ']');
- Minz_Error::error(
- 404,
- array('error' => array(_t('page_not_found')))
- );
+ /**
+ * This action displays the global view of FreshRSS.
+ */
+ public function globalAction() {
+ if (!FreshRSS_Auth::hasAccess() && !Minz_Configuration::allowAnonymous()) {
+ Minz_Request::forward(array('c' => 'auth', 'a' => 'login'));
return;
}
- // mise à jour des titres
- $this->view->rss_title = $this->view->currentName . ' | ' . Minz_View::title();
- Minz_View::prependTitle(
- ($this->nb_not_read_cat > 0 ? '(' . formatNumber($this->nb_not_read_cat) . ') ' : '') .
- $this->view->currentName .
- ' · '
- );
+ Minz_View::appendScript(Minz_Url::display('/scripts/global_view.js?' . @filemtime(PUBLIC_PATH . '/scripts/global_view.js')));
- // On récupère les différents éléments de filtrage
- $this->view->state = Minz_Request::param('state', FreshRSS_Context::$conf->default_view);
- $state_param = Minz_Request::param('state', null);
- $filter = Minz_Request::param('search', '');
- $this->view->order = $order = Minz_Request::param('order', FreshRSS_Context::$conf->sort_order);
- $nb = Minz_Request::param('nb', FreshRSS_Context::$conf->posts_per_page);
- $first = Minz_Request::param('next', '');
-
- $ajax_request = Minz_Request::param('ajax', false);
- if ($output === 'reader') {
- $nb = max(1, round($nb / 2));
+ try {
+ $this->updateContext();
+ } catch (FreshRSS_Context_Exception $e) {
+ Minz_Error::error(404);
}
- if ($this->view->state === FreshRSS_Entry::STATE_NOT_READ) { //Any unread article in this category at all?
- switch ($getType) {
- case 'a':
- $hasUnread = $this->view->nb_not_read > 0;
- break;
- case 's':
- // This is deprecated. The favorite button does not exist anymore
- $hasUnread = $this->view->nb_favorites['unread'] > 0;
- break;
- case 'c':
- $hasUnread = (!isset($this->view->cat_aside[$getId]) ||
- $this->view->cat_aside[$getId]->nbNotRead() > 0);
- break;
- case 'f':
- $myFeed = FreshRSS_CategoryDAO::findFeed($this->view->cat_aside, $getId);
- $hasUnread = ($myFeed === null) || ($myFeed->nbNotRead() > 0);
- break;
- default:
- $hasUnread = true;
- break;
- }
- if (!$hasUnread && ($state_param === null)) {
- $this->view->state = FreshRSS_Entry::STATE_ALL;
- }
+ $this->view->categories = FreshRSS_Context::$categories;
+
+ $this->view->rss_title = FreshRSS_Context::$name . ' | ' . Minz_View::title();
+ $title = _t('gen.title.global_view');
+ if (FreshRSS_Context::$get_unread > 0) {
+ $title = '(' . FreshRSS_Context::$get_unread . ') ' . $title;
}
+ Minz_View::prependTitle($title . ' · ');
+ }
- $this->view->today = @strtotime('today');
+ /**
+ * This action displays the RSS feed of FreshRSS.
+ */
+ public function rssAction() {
+ $token = FreshRSS_Context::$conf->token;
+ $token_param = Minz_Request::param('token', '');
+ $token_is_ok = ($token != '' && $token === $token_param);
+
+ // Check if user has access.
+ if (!FreshRSS_Auth::hasAccess() &&
+ !Minz_Configuration::allowAnonymous() &&
+ !$token_is_ok) {
+ Minz_Error::error(403);
+ }
try {
- $entries = $entryDAO->listWhere($getType, $getId, $this->view->state, $order, $nb + 1, $first, $filter);
-
- // Si on a récupéré aucun article "non lus"
- // on essaye de récupérer tous les articles
- if ($this->view->state === FreshRSS_Entry::STATE_NOT_READ && empty($entries) && ($state_param === null) && ($filter == '')) {
- Minz_Log::debug('Conflicting information about nbNotRead!');
- $feedDAO = FreshRSS_Factory::createFeedDao();
- try {
- $feedDAO->updateCachedValues();
- } catch (Exception $ex) {
- Minz_Log::notice('Failed to automatically correct nbNotRead! ' + $ex->getMessage());
- }
- $this->view->state = FreshRSS_Entry::STATE_ALL;
- $entries = $entryDAO->listWhere($getType, $getId, $this->view->state, $order, $nb, $first, $filter);
- }
- Minz_Request::_param('state', $this->view->state);
-
- if (count($entries) <= $nb) {
- $this->view->nextId = '';
- } else { //We have more elements for pagination
- $lastEntry = array_pop($entries);
- $this->view->nextId = $lastEntry->id();
- }
+ $this->updateContext();
+ } catch (FreshRSS_Context_Exception $e) {
+ Minz_Error::error(404);
+ }
- $this->view->entries = $entries;
+ try {
+ $this->view->entries = $this->listEntriesByContext();
} catch (FreshRSS_EntriesGetter_Exception $e) {
Minz_Log::notice($e->getMessage());
- Minz_Error::error(
- 404,
- array('error' => array(_t('page_not_found')))
- );
+ Minz_Error::error(404);
}
+
+ // No layout for RSS output.
+ $this->view->rss_title = FreshRSS_Context::$name . ' | ' . Minz_View::title();
+ $this->view->_useLayout(false);
+ header('Content-Type: application/rss+xml; charset=utf-8');
}
- /*
- * Vérifie que la catégorie / flux sélectionné existe
- * + Initialise correctement les variables de vue get_c et get_f
- * + Met à jour la variable $this->nb_not_read_cat
+ /**
+ * This action updates the Context object by using request parameters.
+ *
+ * Parameters are:
+ * - state (default: conf->default_view)
+ * - search (default: empty string)
+ * - order (default: conf->sort_order)
+ * - nb (default: conf->posts_per_page)
+ * - next (default: empty string)
*/
- private function checkAndProcessType($getType, $getId) {
- switch($getType) {
- case 'a':
- $this->view->currentName = _t('your_rss_feeds');
- $this->nb_not_read_cat = $this->view->nb_not_read;
- $this->view->get_c = $getType;
- return true;
- case 's':
- $this->view->currentName = _t('your_favorites');
- $this->nb_not_read_cat = $this->view->nb_favorites['unread'];
- $this->view->get_c = $getType;
- return true;
- case 'c':
- $cat = isset($this->view->cat_aside[$getId]) ? $this->view->cat_aside[$getId] : null;
- if ($cat === null) {
- $catDAO = new FreshRSS_CategoryDAO();
- $cat = $catDAO->searchById($getId);
- }
- if ($cat) {
- $this->view->currentName = $cat->name();
- $this->nb_not_read_cat = $cat->nbNotRead();
- $this->view->get_c = $getId;
- return true;
- } else {
- return false;
- }
- case 'f':
- $feed = FreshRSS_CategoryDAO::findFeed($this->view->cat_aside, $getId);
- if (empty($feed)) {
- $feedDAO = FreshRSS_Factory::createFeedDao();
- $feed = $feedDAO->searchById($getId);
- }
- if ($feed) {
- $this->view->currentName = $feed->name();
- $this->nb_not_read_cat = $feed->nbNotRead();
- $this->view->get_f = $getId;
- $this->view->get_c = $feed->category();
- return true;
- } else {
- return false;
- }
- default:
- return false;
+ private function updateContext() {
+ // Update number of read / unread variables.
+ $entryDAO = FreshRSS_Factory::createEntryDao();
+ FreshRSS_Context::$total_starred = $entryDAO->countUnreadReadFavorites();
+ FreshRSS_Context::$total_unread = FreshRSS_CategoryDAO::CountUnreads(
+ FreshRSS_Context::$categories, 1
+ );
+
+ FreshRSS_Context::_get(Minz_Request::param('get', 'a'));
+
+ FreshRSS_Context::$state = Minz_Request::param(
+ 'state', FreshRSS_Context::$conf->default_state
+ );
+ $state_forced_by_user = Minz_Request::param('state', false) !== false;
+ if (FreshRSS_Context::$conf->default_view === 'adaptive' &&
+ FreshRSS_Context::$get_unread <= 0 &&
+ !FreshRSS_Context::isStateEnabled(FreshRSS_Entry::STATE_READ) &&
+ !$state_forced_by_user) {
+ FreshRSS_Context::$state |= FreshRSS_Entry::STATE_READ;
}
+
+ FreshRSS_Context::$search = Minz_Request::param('search', '');
+ FreshRSS_Context::$order = Minz_Request::param(
+ 'order', FreshRSS_Context::$conf->sort_order
+ );
+ FreshRSS_Context::$number = Minz_Request::param(
+ 'nb', FreshRSS_Context::$conf->posts_per_page
+ );
+ FreshRSS_Context::$first_id = Minz_Request::param('next', '');
}
-
+
+ /**
+ * This method returns a list of entries based on the Context object.
+ */
+ private function listEntriesByContext() {
+ $entryDAO = FreshRSS_Factory::createEntryDao();
+
+ $get = FreshRSS_Context::currentGet(true);
+ if (count($get) > 1) {
+ $type = $get[0];
+ $id = $get[1];
+ } else {
+ $type = $get;
+ $id = '';
+ }
+
+ return $entryDAO->listWhere(
+ $type, $id, FreshRSS_Context::$state, FreshRSS_Context::$order,
+ FreshRSS_Context::$number + 1, FreshRSS_Context::$first_id,
+ FreshRSS_Context::$search
+ );
+ }
+
+ /**
+ * This action displays the about page of FreshRSS.
+ */
public function aboutAction() {
Minz_View::prependTitle(_t('about') . ' · ');
}
+ /**
+ * This action displays logs of FreshRSS for the current user.
+ */
public function logsAction() {
if (!FreshRSS_Auth::hasAccess()) {
- Minz_Error::error(
- 403,
- array('error' => array(_t('access_denied')))
- );
+ Minz_Error::error(403);
}
Minz_View::prependTitle(_t('logs') . ' · ');
diff --git a/app/Exceptions/ContextException.php b/app/Exceptions/ContextException.php
new file mode 100644
index 000000000..357751b7c
--- /dev/null
+++ b/app/Exceptions/ContextException.php
@@ -0,0 +1,10 @@
+<?php
+
+/**
+ * An exception raised when a context is invalid
+ */
+class FreshRSS_Context_Exception extends Exception {
+ public function __construct($message) {
+ parent::__construct($message);
+ }
+}
diff --git a/app/FreshRSS.php b/app/FreshRSS.php
index 752b14e31..6114a5d1a 100644
--- a/app/FreshRSS.php
+++ b/app/FreshRSS.php
@@ -26,21 +26,15 @@ class FreshRSS extends Minz_FrontController {
// Load context and configuration.
FreshRSS_Context::init();
- $this->loadParamsView();
+ // Init i18n.
+ Minz_Session::_param('language', FreshRSS_Context::$conf->language);
+ Minz_Translate::init();
+
$this->loadStylesAndScripts();
$this->loadNotifications();
$this->loadExtensions();
}
- private function loadParamsView() {
- // TODO: outputs should be different actions.
- $output = Minz_Request::param('output', '');
- if (($output === '') || ($output !== 'normal' && $output !== 'rss' && $output !== 'reader' && $output !== 'global')) {
- $output = FreshRSS_Context::$conf->view_mode;
- Minz_Request::_param('output', $output);
- }
- }
-
private function loadStylesAndScripts() {
$theme = FreshRSS_Themes::load(FreshRSS_Context::$conf->theme);
if ($theme) {
diff --git a/app/Models/Configuration.php b/app/Models/Configuration.php
index 2f208e509..53f136513 100644
--- a/app/Models/Configuration.php
+++ b/app/Models/Configuration.php
@@ -14,7 +14,8 @@ class FreshRSS_Configuration {
'apiPasswordHash' => '', //CRYPT_BLOWFISH
'posts_per_page' => 20,
'view_mode' => 'normal',
- 'default_view' => FreshRSS_Entry::STATE_NOT_READ,
+ 'default_view' => 'adaptive',
+ 'default_state' => FreshRSS_Entry::STATE_NOT_READ,
'auto_load_more' => true,
'display_posts' => false,
'display_categories' => false,
@@ -153,18 +154,22 @@ class FreshRSS_Configuration {
}
public function _default_view($value) {
switch ($value) {
- case FreshRSS_Entry::STATE_ALL:
- // left blank on purpose
- case FreshRSS_Entry::STATE_NOT_READ:
- // left blank on purpose
- case FreshRSS_Entry::STATE_STRICT + FreshRSS_Entry::STATE_NOT_READ:
+ case 'all':
$this->data['default_view'] = $value;
+ $this->data['default_state'] = (FreshRSS_Entry::STATE_READ +
+ FreshRSS_Entry::STATE_NOT_READ);
break;
+ case 'adaptive':
+ case 'unread':
default:
- $this->data['default_view'] = FreshRSS_Entry::STATE_ALL;
- break;
+ $this->data['default_view'] = $value;
+ $this->data['default_state'] = FreshRSS_Entry::STATE_NOT_READ;
}
}
+ public function _default_state($value) {
+ $this->data['default_state'] = (int)$value;
+ }
+
public function _display_posts($value) {
$this->data['display_posts'] = ((bool)$value) && $value !== 'no';
}
diff --git a/app/Models/Context.php b/app/Models/Context.php
index d984fece7..36c4087eb 100644
--- a/app/Models/Context.php
+++ b/app/Models/Context.php
@@ -6,8 +6,39 @@
*/
class FreshRSS_Context {
public static $conf = null;
+ public static $categories = array();
+
+ public static $name = '';
+
+ public static $total_unread = 0;
+ public static $total_starred = array(
+ 'all' => 0,
+ 'read' => 0,
+ 'unread' => 0,
+ );
+
+ public static $get_unread = 0;
+ public static $current_get = array(
+ 'all' => false,
+ 'starred' => false,
+ 'feed' => false,
+ 'category' => false,
+ );
+ public static $next_get = 'a';
+
public static $state = 0;
+ public static $order = 'DESC';
+ public static $number = 0;
+ public static $search = '';
+ public static $first_id = '';
+ public static $next_id = '';
+ public static $id_max = '';
+ /**
+ * Initialize the context.
+ *
+ * Set the correct $conf and $categories variables.
+ */
public static function init() {
// Init configuration.
$current_user = Minz_Session::param('currentUser');
@@ -18,15 +49,220 @@ class FreshRSS_Context {
die($e->getMessage());
}
- // Init i18n.
- Minz_Session::_param('language', self::$conf->language);
- Minz_Translate::init();
-
- // Get the current state.
- self::$state = self::$conf->default_view;
+ $catDAO = new FreshRSS_CategoryDAO();
+ self::$categories = $catDAO->listCategories();
}
- public static function stateEnabled($state) {
+ /**
+ * Returns if the current state includes $state parameter.
+ */
+ public static function isStateEnabled($state) {
return self::$state & $state;
}
+
+ /**
+ * Returns the current state with or without $state parameter.
+ */
+ public static function getRevertState($state) {
+ if (self::$state & $state) {
+ return self::$state & ~$state;
+ } else {
+ return self::$state | $state;
+ }
+ }
+
+ /**
+ * Return the current get as a string or an array.
+ *
+ * If $array is true, the first item of the returned value is 'f' or 'c' and
+ * the second is the id.
+ */
+ public static function currentGet($array = false) {
+ if (self::$current_get['all']) {
+ return 'a';
+ } elseif (self::$current_get['starred']) {
+ return 's';
+ } elseif (self::$current_get['feed']) {
+ if ($array) {
+ return array('f', self::$current_get['feed']);
+ } else {
+ return 'f_' . self::$current_get['feed'];
+ }
+ } elseif (self::$current_get['category']) {
+ if ($array) {
+ return array('c', self::$current_get['category']);
+ } else {
+ return 'c_' . self::$current_get['category'];
+ }
+ }
+ }
+
+ /**
+ * Return true if $get parameter correspond to the $current_get attribute.
+ */
+ public static function isCurrentGet($get) {
+ $type = $get[0];
+ $id = substr($get, 2);
+
+ switch($type) {
+ case 'a':
+ return self::$current_get['all'];
+ case 's':
+ return self::$current_get['starred'];
+ case 'f':
+ return self::$current_get['feed'] == $id;
+ case 'c':
+ return self::$current_get['category'] == $id;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Set the current $get attribute.
+ *
+ * Valid $get parameter are:
+ * - a
+ * - s
+ * - f_<feed id>
+ * - c_<category id>
+ *
+ * $name and $get_unread attributes are also updated as $next_get
+ * Raise an exception if id or $get is invalid.
+ */
+ public static function _get($get) {
+ $type = $get[0];
+ $id = substr($get, 2);
+ $nb_unread = 0;
+
+ switch($type) {
+ case 'a':
+ self::$current_get['all'] = true;
+ self::$name = _t('your_rss_feeds');
+ self::$get_unread = self::$total_unread;
+ break;
+ case 's':
+ self::$current_get['starred'] = true;
+ self::$name = _t('your_favorites');
+ self::$get_unread = self::$total_starred['unread'];
+
+ // Update state if favorite is not yet enabled.
+ self::$state = self::$state | FreshRSS_Entry::STATE_FAVORITE;
+ break;
+ case 'f':
+ // We try to find the corresponding feed.
+ $feed = FreshRSS_CategoryDAO::findFeed(self::$categories, $id);
+ if ($feed === null) {
+ $feedDAO = FreshRSS_Factory::createFeedDao();
+ $feed = $feedDAO->searchById($id);
+
+ if (!$feed) {
+ throw new FreshRSS_Context_Exception('Invalid feed: ' . $id);
+ }
+ }
+
+ self::$current_get['feed'] = $id;
+ self::$current_get['category'] = $feed->category();
+ self::$name = $feed->name();
+ self::$get_unread = $feed->nbNotRead();
+ break;
+ case 'c':
+ // We try to find the corresponding category.
+ self::$current_get['category'] = $id;
+ if (!isset(self::$categories[$id])) {
+ $catDAO = new FreshRSS_CategoryDAO();
+ $cat = $catDAO->searchById($id);
+
+ if (!$cat) {
+ throw new FreshRSS_Context_Exception('Invalid category: ' . $id);
+ }
+ } else {
+ $cat = self::$categories[$id];
+ }
+
+ self::$name = $cat->name();
+ self::$get_unread = $cat->nbNotRead();
+ break;
+ default:
+ throw new FreshRSS_Context_Exception('Invalid getter: ' . $get);
+ }
+
+ self::_nextGet();
+ }
+
+ /**
+ * Set the value of $next_get attribute.
+ */
+ public static function _nextGet() {
+ $get = self::currentGet();
+ // By default, $next_get == $get
+ self::$next_get = $get;
+
+ if (self::$conf->onread_jump_next && strlen($get) > 2) {
+ $another_unread_id = '';
+ $found_current_get = false;
+ switch ($get[0]) {
+ case 'f':
+ // We search the next feed with at least one unread article in
+ // same category as the currend feed.
+ foreach (self::$categories as $cat) {
+ if ($cat->id() != self::$current_get['category']) {
+ // We look into the category of the current feed!
+ continue;
+ }
+
+ foreach ($cat->feeds() as $feed) {
+ if ($feed->id() == self::$current_get['feed']) {
+ // Here is our current feed! Fine, the next one will
+ // be a potential candidate.
+ $found_current_get = true;
+ continue;
+ }
+
+ if ($feed->nbNotRead() > 0) {
+ $another_unread_id = $feed->id();
+ if ($found_current_get) {
+ // We have found our current feed and now we
+ // have an feed with unread articles. Leave the
+ // loop!
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ // If no feed have been found, next_get is the current category.
+ self::$next_get = empty($another_unread_id) ?
+ 'c_' . self::$current_get['category'] :
+ 'f_' . $another_unread_id;
+ break;
+ case 'c':
+ // We search the next category with at least one unread article.
+ foreach (self::$categories as $cat) {
+ if ($cat->id() == self::$current_get['category']) {
+ // Here is our current category! Next one could be our
+ // champion if it has unread articles.
+ $found_current_get = true;
+ continue;
+ }
+
+ if ($cat->nbNotRead() > 0) {
+ $another_unread_id = $cat->id();
+ if ($found_current_get) {
+ // Unread articles and the current category has
+ // already been found? Leave the loop!
+ break;
+ }
+ }
+ }
+
+ // No unread category? The main stream will be our destination!
+ self::$next_get = empty($another_unread_id) ?
+ 'a' :
+ 'c_' . $another_unread_id;
+ break;
+ }
+ }
+ }
}
diff --git a/app/Models/Entry.php b/app/Models/Entry.php
index ee94d1110..346c98a92 100644
--- a/app/Models/Entry.php
+++ b/app/Models/Entry.php
@@ -1,12 +1,11 @@
<?php
class FreshRSS_Entry extends Minz_Model {
- const STATE_ALL = 0;
const STATE_READ = 1;
const STATE_NOT_READ = 2;
+ const STATE_ALL = 3;
const STATE_FAVORITE = 4;
const STATE_NOT_FAVORITE = 8;
- const STATE_STRICT = 16;
private $id = 0;
private $guid;
diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php
index 5a136499a..5d2909c62 100644
--- a/app/Models/EntryDAO.php
+++ b/app/Models/EntryDAO.php
@@ -333,8 +333,6 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
if ($state & FreshRSS_Entry::STATE_NOT_READ) {
if (!($state & FreshRSS_Entry::STATE_READ)) {
$where .= 'AND e1.is_read=0 ';
- } elseif ($state & FreshRSS_Entry::STATE_STRICT) {
- $where .= 'AND e1.is_read=0 ';
}
}
elseif ($state & FreshRSS_Entry::STATE_READ) {
diff --git a/app/layout/aside_feed.phtml b/app/layout/aside_feed.phtml
new file mode 100644
index 000000000..3c23e0178
--- /dev/null
+++ b/app/layout/aside_feed.phtml
@@ -0,0 +1,95 @@
+<?php
+ $class = '';
+ if (FreshRSS_Context::$conf->hide_read_feeds &&
+ FreshRSS_Context::isStateEnabled(FreshRSS_Entry::STATE_NOT_READ) &&
+ !FreshRSS_Context::isStateEnabled(FreshRSS_Entry::STATE_READ)) {
+ $class = ' state_unread';
+ }
+?>
+
+<div class="aside aside_feed<?php echo $class; ?>" id="aside_feed">
+ <a class="toggle_aside" href="#close"><?php echo _i('close'); ?></a>
+
+ <?php if (FreshRSS_Auth::hasAccess()) { ?>
+ <div class="stick configure-feeds no-mobile">
+ <a class="btn btn-important" href="<?php echo _url('subscription', 'index'); ?>"><?php echo _t('subscription_management'); ?></a>
+ <a class="btn btn-important" href="<?php echo _url('importExport', 'index'); ?>"><?php echo _i('import'); ?></a>
+ </div>
+ <?php } elseif (Minz_Configuration::needsLogin()) { ?>
+ <a href="<?php echo _url('index', 'about'); ?>"><?php echo _t('about_freshrss'); ?></a>
+ <?php } ?>
+
+ <form id="mark-read-aside" method="post" style="display: none"></form>
+
+ <ul class="tree">
+ <li class="tree-folder category all<?php echo FreshRSS_Context::isCurrentGet('a') ? ' active' : ''; ?>">
+ <div class="tree-folder-title">
+ <?php echo _i('all'); ?> <a class="title" data-unread="<?php echo format_number(FreshRSS_Context::$total_unread); ?>" href="<?php echo _url('index', 'index'); ?>"><?php echo _t('main_stream'); ?></a>
+ </div>
+ </li>
+
+ <li class="tree-folder category favorites<?php echo FreshRSS_Context::isCurrentGet('s') ? ' active' : ''; ?>">
+ <div class="tree-folder-title">
+ <?php echo _i('bookmark'); ?> <a class="title" data-unread="<?php echo format_number(FreshRSS_Context::$total_starred['unread']); ?>" href="<?php echo _url('index', 'index', 'get', 's'); ?>"><?php echo _t('favorite_feeds', format_number(FreshRSS_Context::$total_starred['all'])); ?></a>
+ </div>
+ </li>
+
+ <?php
+ foreach ($this->categories as $cat) {
+ $feeds = $cat->feeds();
+ if (!empty($feeds)) {
+ $c_active = FreshRSS_Context::isCurrentGet('c_' . $cat->id());
+ $c_show = $c_active && (!FreshRSS_Context::$conf->display_categories ||
+ FreshRSS_Context::$current_get['feed']);
+ ?>
+ <li class="tree-folder category<?php echo $c_active ? ' active' : ''; ?>" data-unread="<?php echo $cat->nbNotRead(); ?>">
+ <div class="tree-folder-title">
+ <a class="dropdown-toggle" href="#"><?php echo _i($c_show ? 'up' : 'down'); ?></a>
+ <a class="title" data-unread="<?php echo format_number($cat->nbNotRead()); ?>" href="<?php echo _url('index', 'index', 'get', 'c_' . $cat->id()); ?>"><?php echo $cat->name(); ?></a>
+ </div>
+
+ <ul class="tree-folder-items<?php echo $c_show ? ' active' : ''; ?>">
+ <?php
+ foreach ($feeds as $feed) {
+ $f_active = FreshRSS_Context::isCurrentGet('f_' . $feed->id());
+ ?>
+ <li id="f_<?php echo $feed->id(); ?>" class="item feed<?php echo $f_active ? ' active' : ''; ?><?php echo $feed->inError() ? ' error' : ''; ?><?php echo $feed->nbEntries() <= 0 ? ' empty' : ''; ?>" data-unread="<?php echo $feed->nbNotRead(); ?>" data-priority="<?php echo $feed->priority(); ?>">
+ <div class="dropdown no-mobile">
+ <div class="dropdown-target"></div>
+ <a class="dropdown-toggle" data-fweb="<?php echo $feed->website(); ?>"><?php echo _i('configure'); ?></a>
+ <?php /* feed_config_template */ ?>
+ </div>
+ <img class="favicon" src="<?php echo $feed->favicon(); ?>" alt="✇" /> <a class="item-title" data-unread="<?php echo format_number($feed->nbNotRead()); ?>" href="<?php echo _url('index', 'index', 'get', 'f_' . $feed->id()); ?>"><?php echo $feed->name(); ?></a>
+ </li>
+ <?php } ?>
+ </ul>
+ </li>
+ <?php
+ }
+ }
+ ?>
+ </ul>
+</div>
+
+<script id="feed_config_template" type="text/html">
+ <ul class="dropdown-menu">
+ <li class="dropdown-close"><a href="#close">❌</a></li>
+ <li class="item"><a href="<?php echo _url('index', 'index', 'get', 'f_!!!!!!'); ?>"><?php echo _t('filter'); ?></a></li>
+ <?php if (FreshRSS_Auth::hasAccess()) { ?>
+ <li class="item"><a href="<?php echo _url('stats', 'repartition', 'id', '!!!!!!'); ?>"><?php echo _t('stats'); ?></a></li>
+ <?php } ?>
+ <li class="item"><a target="_blank" href="http://example.net/"><?php echo _t('see_website'); ?></a></li>
+ <?php if (FreshRSS_Auth::hasAccess()) { ?>
+ <li class="separator"></li>
+ <li class="item"><a href="<?php echo _url('subscription', 'index', 'id', '!!!!!!'); ?>"><?php echo _t('administration'); ?></a></li>
+ <li class="item"><a href="<?php echo _url('feed', 'actualize', 'id', '!!!!!!'); ?>"><?php echo _t('actualize'); ?></a></li>
+ <li class="item">
+ <?php $confirm = FreshRSS_Context::$conf->reading_confirm ? 'confirm' : ''; ?>
+ <button class="read_all as-link <?php echo $confirm; ?>"
+ form="mark-read-aside"
+ formaction="<?php echo _url('entry', 'read', 'get', 'f_!!!!!!'); ?>"
+ type="submit"><?php echo _t('mark_read'); ?></button>
+ </li>
+ <?php } ?>
+ </ul>
+</script>
diff --git a/app/layout/aside_flux.phtml b/app/layout/aside_flux.phtml
deleted file mode 100644
index 114ccbf56..000000000
--- a/app/layout/aside_flux.phtml
+++ /dev/null
@@ -1,103 +0,0 @@
-<div class="aside aside_flux<?php if (FreshRSS_Context::$conf->hide_read_feeds && ($this->state & FreshRSS_Entry::STATE_NOT_READ) && !($this->state & FreshRSS_Entry::STATE_READ)) echo ' state_unread'; ?>" id="aside_flux">
- <a class="toggle_aside" href="#close"><?php echo _i('close'); ?></a>
-
- <ul class="categories">
- <?php if (FreshRSS_Auth::hasAccess()) { ?>
- <form id="mark-read-aside" method="post" style="display: none"></form>
-
- <li>
- <div class="stick configure-feeds">
- <a class="btn btn-important" href="<?php echo _url('subscription', 'index'); ?>"><?php echo _t('subscription_management'); ?></a>
- <a class="btn btn-important" href="<?php echo _url('importExport', 'index'); ?>"><?php echo _i('import'); ?></a>
- </div>
- </li>
- <?php } elseif (Minz_Configuration::needsLogin()) { ?>
- <li><a href="<?php echo _url('index', 'about'); ?>"><?php echo _t('about_freshrss'); ?></a></li>
- <?php } ?>
-
- <?php
- $arUrl = array('c' => 'index', 'a' => 'index', 'params' => array());
- if (FreshRSS_Context::$conf->view_mode !== Minz_Request::param('output', 'normal')) {
- $arUrl['params']['output'] = 'normal';
- }
- ?>
- <li>
- <div class="category all<?php echo $this->get_c == 'a' ? ' active' : ''; ?>">
- <a data-unread="<?php echo formatNumber($this->nb_not_read); ?>" class="btn<?php echo $this->get_c == 'a' ? ' active' : ''; ?>" href="<?php echo Minz_Url::display($arUrl); ?>">
- <?php echo _i('all'); ?>
- <?php echo _t('main_stream'); ?>
- </a>
- </div>
- </li>
-
- <li>
- <div class="category favorites<?php echo $this->get_c == 's' ? ' active' : ''; ?>">
- <a data-unread="<?php echo formatNumber($this->nb_favorites['unread']); ?>" class="btn<?php echo $this->get_c == 's' ? ' active' : ''; ?>" href="<?php $arUrl['params']['get'] = 's'; echo Minz_Url::display($arUrl); ?>">
- <?php echo _i('bookmark'); ?>
- <?php echo _t('favorite_feeds', formatNumber($this->nb_favorites['all'])); ?>
- </a>
- </div>
- </li>
-
- <?php
- foreach ($this->cat_aside as $cat) {
- $feeds = $cat->feeds();
- if (!empty($feeds)) {
- $c_active = false;
- $c_show = false;
- if ($this->get_c == $cat->id()) {
- $c_active = true;
- if (!FreshRSS_Context::$conf->display_categories || $this->get_f) {
- $c_show = true;
- }
- }
- ?><li data-unread="<?php echo $cat->nbNotRead(); ?>"<?php if ($c_active) echo ' class="active"'; ?>><?php
- ?><div class="category stick<?php echo $c_active ? ' active' : ''; ?>"><?php
- ?><a data-unread="<?php echo formatNumber($cat->nbNotRead()); ?>" class="btn<?php echo $c_active ? ' active' : ''; ?>" href="<?php $arUrl['params']['get'] = 'c_' . $cat->id(); echo Minz_Url::display($arUrl); ?>"><?php echo $cat->name(); ?></a><?php
- ?><a class="btn dropdown-toggle" href="#"><?php echo _i($c_show ? 'up' : 'down'); ?></a><?php
- ?></div><?php
- ?><ul class="feeds<?php echo $c_show ? ' active' : ''; ?>"><?php
- foreach ($feeds as $feed) {
- $feed_id = $feed->id();
- $nbEntries = $feed->nbEntries();
- $f_active = ($this->get_f == $feed_id);
- ?><li id="f_<?php echo $feed_id; ?>" class="item<?php echo $f_active ? ' active' : ''; ?><?php echo $feed->inError() ? ' error' : ''; ?><?php echo $nbEntries == 0 ? ' empty' : ''; ?>" data-unread="<?php echo $feed->nbNotRead(); ?>"><?php
- ?><div class="dropdown"><?php
- ?><div class="dropdown-target"></div><?php
- ?><a class="dropdown-toggle" data-fweb="<?php echo $feed->website(); ?>"><?php echo _i('configure'); ?></a><?php
- /* feed_config_template */
- ?></div><?php
- ?> <img class="favicon" src="<?php echo $feed->favicon(); ?>" alt="✇" /> <?php
- ?><a class="feed" data-unread="<?php echo formatNumber($feed->nbNotRead()); ?>" data-priority="<?php echo $feed->priority(); ?>" href="<?php $arUrl['params']['get'] = 'f_' . $feed_id; echo Minz_Url::display($arUrl); ?>"><?php echo $feed->name(); ?></a><?php
- ?></li><?php
- }
- ?></ul><?php
- ?></li><?php
- }
- } ?>
- </ul>
- <span class="aside_flux_ender"><!-- For fixed menu --></span>
-</div>
-
-<script id="feed_config_template" type="text/html">
- <ul class="dropdown-menu">
- <li class="dropdown-close"><a href="#close">❌</a></li>
- <li class="item"><a href="<?php echo _url('index', 'index', 'get', 'f_!!!!!!'); ?>"><?php echo _t('filter'); ?></a></li>
- <?php if (FreshRSS_Auth::hasAccess()) { ?>
- <li class="item"><a href="<?php echo _url('stats', 'repartition', 'id', '!!!!!!'); ?>"><?php echo _t('stats'); ?></a></li>
- <?php } ?>
- <li class="item"><a target="_blank" href="http://example.net/"><?php echo _t('see_website'); ?></a></li>
- <?php if (FreshRSS_Auth::hasAccess()) { ?>
- <li class="separator"></li>
- <li class="item"><a href="<?php echo _url('subscription', 'index', 'id', '!!!!!!'); ?>"><?php echo _t('administration'); ?></a></li>
- <li class="item"><a href="<?php echo _url('feed', 'actualize', 'id', '!!!!!!'); ?>"><?php echo _t('actualize'); ?></a></li>
- <li class="item">
- <?php $confirm = FreshRSS_Context::$conf->reading_confirm ? 'confirm' : ''; ?>
- <button class="read_all as-link <?php echo $confirm; ?>"
- form="mark-read-aside"
- formaction="<?php echo _url('entry', 'read', 'get', 'f_!!!!!!'); ?>"
- type="submit"><?php echo _t('mark_read'); ?></button>
- </li>
- <?php } ?>
- </ul>
-</script>
diff --git a/app/layout/aside_subscription.phtml b/app/layout/aside_subscription.phtml
index 9a95763c3..cbf5df67d 100644
--- a/app/layout/aside_subscription.phtml
+++ b/app/layout/aside_subscription.phtml
@@ -1,4 +1,4 @@
-<ul class="nav nav-list aside aside_feed">
+<ul class="nav nav-list aside">
<li class="nav-header"><?php echo _t('subscription_management'); ?></li>
<li class="item<?php echo Minz_Request::controllerName() == 'subscription' ? ' active' : ''; ?>">
diff --git a/app/layout/layout.phtml b/app/layout/layout.phtml
index a8c70ec64..1827d6c26 100644
--- a/app/layout/layout.phtml
+++ b/app/layout/layout.phtml
@@ -10,21 +10,22 @@
<?php $this->renderHelper('javascript_vars'); ?>
//]]></script>
<?php
- if (!empty($this->nextId)) {
- $params = Minz_Request::params();
- $params['next'] = $this->nextId;
- $params['ajax'] = 1;
+ $url_base = Minz_Request::currentRequest();
+ if (FreshRSS_Context::$next_id !== '') {
+ $url_next = $url_base;
+ $url_next['params']['next'] = FreshRSS_Context::$next_id;
+ $url_next['params']['ajax'] = 1;
?>
- <link id="prefetch" rel="next prefetch" href="<?php echo Minz_Url::display(array('c' => Minz_Request::controllerName(), 'a' => Minz_Request::actionName(), 'params' => $params)); ?>" />
+ <link id="prefetch" rel="next prefetch" href="<?php echo Minz_Url::display($url_next); ?>" />
<?php } ?>
<link rel="shortcut icon" id="favicon" type="image/x-icon" sizes="16x16 64x64" href="<?php echo Minz_Url::display('/favicon.ico'); ?>" />
<link rel="icon msapplication-TileImage apple-touch-icon" type="image/png" sizes="256x256" href="<?php echo Minz_Url::display('/themes/icons/favicon-256.png'); ?>" />
<?php
- if (isset($this->url)) {
- $rss_url = $this->url;
- $rss_url['params']['output'] = 'rss';
+ if (isset($this->rss_title)) {
+ $url_rss = $url_base;
+ $url_rss['a'] = 'rss';
?>
- <link rel="alternate" type="application/rss+xml" title="<?php echo $this->rss_title; ?>" href="<?php echo Minz_Url::display($rss_url); ?>" />
+ <link rel="alternate" type="application/rss+xml" title="<?php echo $this->rss_title; ?>" href="<?php echo Minz_Url::display($url_rss); ?>" />
<?php } ?>
<link rel="prefetch" href="<?php echo FreshRSS_Themes::icon('starred', true); ?>">
<link rel="prefetch" href="<?php echo FreshRSS_Themes::icon('non-starred', true); ?>">
diff --git a/app/layout/nav_menu.phtml b/app/layout/nav_menu.phtml
index bb9468ab1..775daf088 100644
--- a/app/layout/nav_menu.phtml
+++ b/app/layout/nav_menu.phtml
@@ -1,90 +1,31 @@
-<?php
- $actual_view = Minz_Request::param('output', 'normal');
-?>
+<?php $actual_view = Minz_Request::actionName(); ?>
+
<div class="nav_menu">
<?php if ($actual_view === 'normal') { ?>
- <a class="btn toggle_aside" href="#aside_flux"><?php echo _i('category'); ?></a>
+ <a class="btn toggle_aside" href="#aside_feed"><?php echo _i('category'); ?></a>
<?php } ?>
<?php if (FreshRSS_Auth::hasAccess()) { ?>
<div id="nav_menu_actions" class="stick">
<?php
- $url_state = $this->url;
-
- if ($this->state & FreshRSS_Entry::STATE_READ) {
- $url_state['params']['state'] = $this->state & ~FreshRSS_Entry::STATE_READ;
- $checked = 'true';
- $class = 'active';
- } else {
- $url_state['params']['state'] = $this->state | FreshRSS_Entry::STATE_READ;
- $checked = 'false';
- $class = '';
- }
- ?>
- <a id="toggle-read"
- class="btn <?php echo $class; ?>"
- aria-checked="<?php echo $checked; ?>"
- href="<?php echo Minz_Url::display($url_state); ?>"
- title="<?php echo _t('show_read'); ?>">
- <?php echo _i('read'); ?>
- </a>
-
- <?php
- if ($this->state & FreshRSS_Entry::STATE_NOT_READ) {
- $url_state['params']['state'] = $this->state & ~FreshRSS_Entry::STATE_NOT_READ;
- $checked = 'true';
- $class = 'active';
- } else {
- $url_state['params']['state'] = $this->state | FreshRSS_Entry::STATE_NOT_READ;
- $checked = 'false';
- $class = '';
- }
- ?>
- <a id="toggle-unread"
- class="btn <?php echo $class; ?>"
- aria-checked="<?php echo $checked; ?>"
- href="<?php echo Minz_Url::display($url_state); ?>"
- title="<?php echo _t('show_not_reads'); ?>">
- <?php echo _i('unread'); ?>
- </a>
-
- <?php
- if ($this->state & FreshRSS_Entry::STATE_FAVORITE || $this->get_c == 's') {
- $url_state['params']['state'] = $this->state & ~FreshRSS_Entry::STATE_FAVORITE;
- $checked = 'true';
- $class = 'active';
- } else {
- $url_state['params']['state'] = $this->state | FreshRSS_Entry::STATE_FAVORITE;
- $checked = 'false';
- $class = '';
- }
- ?>
- <a id="toggle-favorite"
- class="btn <?php echo $class; ?>"
- aria-checked="<?php echo $checked; ?>"
- href="<?php echo Minz_Url::display($url_state); ?>"
- title="<?php echo _t('show_favorite'); ?>">
- <?php echo _i('starred'); ?>
- </a>
-
- <?php
- if ($this->state & FreshRSS_Entry::STATE_NOT_FAVORITE) {
- $url_state['params']['state'] = $this->state & ~FreshRSS_Entry::STATE_NOT_FAVORITE;
- $checked = 'true';
- $class = 'active';
- } else {
- $url_state['params']['state'] = $this->state | FreshRSS_Entry::STATE_NOT_FAVORITE;
- $checked = 'false';
- $class = '';
- }
+ $states = array(
+ 'read' => FreshRSS_Entry::STATE_READ,
+ 'unread' => FreshRSS_Entry::STATE_NOT_READ,
+ 'starred' => FreshRSS_Entry::STATE_FAVORITE,
+ 'non-starred' => FreshRSS_Entry::STATE_NOT_FAVORITE,
+ );
+
+ foreach ($states as $state_str => $state) {
+ $state_enabled = FreshRSS_Context::isStateEnabled($state);
+ $url_state = Minz_Request::currentRequest();
+ $url_state['params']['state'] = FreshRSS_Context::getRevertState($state);
?>
- <a id="toggle-not-favorite"
- class="btn <?php echo $class; ?>"
- aria-checked="<?php echo $checked; ?>"
- href="<?php echo Minz_Url::display($url_state); ?>"
- title="<?php echo _t('show_not_favorite'); ?>">
- <?php echo _i('non-starred'); ?>
- </a>
+ <a id="toggle-<?php echo $state_str; ?>"
+ class="btn <?php echo $state_enabled ? 'active' : ''; ?>"
+ aria-checked="<?php echo $state_enabled ? 'true' : 'false'; ?>"
+ title="<?php echo _t($state_str); ?>"
+ href="<?php echo Minz_Url::display($url_state); ?>"><?php echo _i($state_str); ?></a>
+ <?php } ?>
<div class="dropdown">
<div id="dropdown-query" class="dropdown-target"></div>
@@ -109,7 +50,7 @@
<?php } ?>
<?php
- $url_query = $this->url;
+ $url_query = Minz_Request::currentRequest();;
$url_query['c'] = 'configure';
$url_query['a'] = 'addQuery';
?>
@@ -117,74 +58,25 @@
</ul>
</div>
</div>
+
<?php
- $get = false;
+ $get = FreshRSS_Context::currentGet();
$string_mark = _t('mark_all_read');
- if ($this->get_f) {
- $get = 'f_' . $this->get_f;
+ if ($get[0] == 'f') {
$string_mark = _t('mark_feed_read');
- } elseif ($this->get_c && $this->get_c != 'a') {
- if ($this->get_c === 's') {
- $get = 's';
- } else {
- $get = 'c_' . $this->get_c;
- }
+ } elseif ($get[0] == 'c') {
$string_mark = _t('mark_cat_read');
}
- $nextGet = $get;
- if (FreshRSS_Context::$conf->onread_jump_next && strlen($get) > 2) {
- $anotherUnreadId = '';
- $foundCurrent = false;
- switch ($get[0]) {
- case 'c':
- foreach ($this->cat_aside as $cat) {
- if ($cat->id() == $this->get_c) {
- $foundCurrent = true;
- continue;
- }
- if ($cat->nbNotRead() <= 0) continue;
- $anotherUnreadId = $cat->id();
- if ($foundCurrent) break;
- }
- $nextGet = empty($anotherUnreadId) ? 'a' : 'c_' . $anotherUnreadId;
- break;
- case 'f':
- foreach ($this->cat_aside as $cat) {
- if ($cat->id() == $this->get_c) {
- foreach ($cat->feeds() as $feed) {
- if ($feed->id() == $this->get_f) {
- $foundCurrent = true;
- continue;
- }
- if ($feed->nbNotRead() <= 0) continue;
- $anotherUnreadId = $feed->id();
- if ($foundCurrent) break;
- }
- break;
- }
- }
- $nextGet = empty($anotherUnreadId) ? 'c_' . $this->get_c : 'f_' . $anotherUnreadId;
- break;
- }
- }
- $p = isset($this->entries[0]) ? $this->entries[0] : null;
- $idMax = $p === null ? (time() - 1) . '000000' : $p->id();
-
- if ($this->order === 'ASC') { //In this case we do not know but we guess idMax
- $idMax2 = (time() - 1) . '000000';
- if (strcmp($idMax2, $idMax) > 0) {
- $idMax = $idMax2;
- }
- }
-
- $arUrl = array('c' => 'entry', 'a' => 'read', 'params' => array('get' => $get, 'nextGet' => $nextGet, 'idMax' => $idMax));
- $output = Minz_Request::param('output', '');
- if ($output != '' && FreshRSS_Context::$conf->view_mode !== $output) {
- $arUrl['params']['output'] = $output;
- }
- $markReadUrl = Minz_Url::display($arUrl);
- Minz_Session::_param('markReadUrl', $markReadUrl);
+ $mark_read_url = array(
+ 'c' => 'entry',
+ 'a' => 'read',
+ 'params' => array(
+ 'get' => $get,
+ 'nextGet' => FreshRSS_Context::$next_get,
+ 'idMax' => FreshRSS_Context::$id_max,
+ )
+ );
?>
<form id="mark-read-menu" method="post" style="display: none"></form>
@@ -193,7 +85,7 @@
<?php $confirm = FreshRSS_Context::$conf->reading_confirm ? 'confirm' : ''; ?>
<button class="read_all btn <?php echo $confirm; ?>"
form="mark-read-menu"
- formaction="<?php echo $markReadUrl; ?>"
+ formaction="<?php echo Minz_Url::display($mark_read_url); ?>"
type="submit"><?php echo _t('mark_read'); ?></button>
<div class="dropdown">
@@ -206,15 +98,16 @@
<li class="item">
<button class="as-link <?php echo $confirm; ?>"
form="mark-read-menu"
- formaction="<?php echo $markReadUrl; ?>"
+ formaction="<?php echo Minz_Url::display($mark_read_url); ?>"
type="submit"><?php echo $string_mark; ?></button>
</li>
<li class="separator"></li>
<?php
- $mark_before_today = $arUrl;
- $mark_before_today['params']['idMax'] = $this->today . '000000';
- $mark_before_one_week = $arUrl;
- $mark_before_one_week['params']['idMax'] = ($this->today - 604800) . '000000';
+ $today = @strtotime('today');
+ $mark_before_today = $mark_read_url;
+ $mark_before_today['params']['idMax'] = $today . '000000';
+ $mark_before_one_week = $mark_read_url;
+ $mark_before_one_week['params']['idMax'] = ($today - 604800) . '000000';
?>
<li class="item">
<button class="as-link <?php echo $confirm; ?>"
@@ -233,25 +126,25 @@
</div>
<?php } ?>
- <?php $url_output = $this->url; ?>
+ <?php $url_output = Minz_Request::currentRequest(); ?>
<div class="stick" id="nav_menu_views">
- <?php $url_output['params']['output'] = 'normal'; ?>
+ <?php $url_output['a'] = 'normal'; ?>
<a class="view_normal btn <?php echo $actual_view == 'normal'? 'active' : ''; ?>" title="<?php echo _t('normal_view'); ?>" href="<?php echo Minz_Url::display($url_output); ?>">
<?php echo _i("view-normal"); ?>
</a>
- <?php $url_output['params']['output'] = 'global'; ?>
+ <?php $url_output['a'] = 'global'; ?>
<a class="view_global btn <?php echo $actual_view == 'global'? 'active' : ''; ?>" title="<?php echo _t('global_view'); ?>" href="<?php echo Minz_Url::display($url_output); ?>">
<?php echo _i("view-global"); ?>
</a>
- <?php $url_output['params']['output'] = 'reader'; ?>
- <a class="view_reader btn <?php echo $actual_view == 'reader'? 'active' : ''; ?>" title="<?php echo _t('reader_view'); ?>" href="<?php echo Minz_Url::display($url_output); ?>">
+ <?php $url_output['a'] = 'reader'; ?>
+ <a class="view_reader btn <?php echo $actual_view == 'reader'? 'active' : ''; ?>" title="<?php echo _t('global_view'); ?>" href="<?php echo Minz_Url::display($url_output); ?>">
<?php echo _i("view-reader"); ?>
</a>
<?php
- $url_output['params']['output'] = 'rss';
+ $url_output['a'] = 'rss';
if (FreshRSS_Context::$conf->token) {
$url_output['params']['token'] = FreshRSS_Context::$conf->token;
}
@@ -284,7 +177,7 @@
</div>
<?php
- if ($this->order === 'DESC') {
+ if (FreshRSS_Context::$order === 'DESC') {
$order = 'ASC';
$icon = 'up';
$title = 'older_first';
@@ -293,7 +186,7 @@
$icon = 'down';
$title = 'newer_first';
}
- $url_order = $this->url;
+ $url_order = Minz_Request::currentRequest();
$url_order['params']['order'] = $order;
?>
<a id="toggle-order" class="btn" href="<?php echo Minz_Url::display($url_order); ?>" title="<?php echo _t($title); ?>">
diff --git a/app/views/configure/reading.phtml b/app/views/configure/reading.phtml
index ef775b4b1..b8f673466 100644
--- a/app/views/configure/reading.phtml
+++ b/app/views/configure/reading.phtml
@@ -39,9 +39,9 @@
<label class="group-name" for="view_mode"><?php echo _t('articles_to_display'); ?></label>
<div class="group-controls">
<select name="default_view" id="default_view">
- <option value="<?php echo FreshRSS_Entry::STATE_NOT_READ; ?>"<?php echo FreshRSS_Context::$conf->default_view === FreshRSS_Entry::STATE_NOT_READ ? ' selected="selected"' : ''; ?>><?php echo _t('show_adaptive'); ?></option>
- <option value="<?php echo FreshRSS_Entry::STATE_ALL; ?>"<?php echo FreshRSS_Context::$conf->default_view === FreshRSS_Entry::STATE_ALL ? ' selected="selected"' : ''; ?>><?php echo _t('show_all_articles'); ?></option>
- <option value="<?php echo FreshRSS_Entry::STATE_STRICT + FreshRSS_Entry::STATE_NOT_READ; ?>"<?php echo FreshRSS_Context::$conf->default_view === FreshRSS_Entry::STATE_STRICT + FreshRSS_Entry::STATE_NOT_READ ? ' selected="selected"' : ''; ?>><?php echo _t('show_not_reads'); ?></option>
+ <option value="adaptive"<?php echo FreshRSS_Context::$conf->default_view === 'adaptive' ? ' selected="selected"' : ''; ?>><?php echo _t('show_adaptive'); ?></option>
+ <option value="all"<?php echo FreshRSS_Context::$conf->default_view === 'all' ? ' selected="selected"' : ''; ?>><?php echo _t('show_all_articles'); ?></option>
+ <option value="unread"<?php echo FreshRSS_Context::$conf->default_view === 'unread' ? ' selected="selected"' : ''; ?>><?php echo _t('show_not_reads'); ?></option>
</select>
</div>
</div>
diff --git a/app/views/helpers/pagination.phtml b/app/views/helpers/pagination.phtml
index d642443a8..3ea6c3582 100755
--- a/app/views/helpers/pagination.phtml
+++ b/app/views/helpers/pagination.phtml
@@ -1,28 +1,32 @@
<?php
- $c = Minz_Request::controllerName();
- $a = Minz_Request::actionName();
- $params = Minz_Request::params();
- $markReadUrl = Minz_Session::param('markReadUrl');
- Minz_Session::_param('markReadUrl', false);
+ $url_next = Minz_Request::currentRequest();
+ $url_next['params']['next'] = FreshRSS_Context::$next_id;
+ $url_next['params']['ajax'] = 1;
+
+ $url_mark_read = array(
+ 'c' => 'entry',
+ 'a' => 'read',
+ 'params' => array(
+ 'get' => FreshRSS_Context::currentGet(),
+ 'nextGet' => FreshRSS_Context::$next_get,
+ 'idMax' => FreshRSS_Context::$id_max,
+ )
+ );
?>
<form id="mark-read-pagination" method="post" style="display: none"></form>
<ul class="pagination">
<li class="item pager-next">
- <?php if (!empty($this->nextId)) { ?>
- <?php
- $params['next'] = $this->nextId;
- $params['ajax'] = 1;
- ?>
- <a id="load_more" href="<?php echo Minz_Url::display(array('c' => $c, 'a' => $a, 'params' => $params)); ?>">
+ <?php if (FreshRSS_Context::$next_id) { ?>
+ <a id="load_more" href="<?php echo Minz_Url::display($url_next); ?>">
<?php echo _t('load_more'); ?>
</a>
- <?php } elseif ($markReadUrl) { ?>
+ <?php } elseif ($url_mark_read) { ?>
<button id="bigMarkAsRead"
class="as-link <?php echo FreshRSS_Context::$conf->reading_confirm ? 'confirm' : ''; ?>"
form="mark-read-pagination"
- formaction="<?php echo $markReadUrl; ?>"
+ formaction="<?php echo Minz_Url::display($url_mark_read); ?>"
type="submit">
<?php echo _t('nothing_to_load'); ?><br />
<span class="bigTick">✓</span><br />
diff --git a/app/views/helpers/view/global_view.phtml b/app/views/helpers/view/global_view.phtml
deleted file mode 100644
index ae8af820d..000000000
--- a/app/views/helpers/view/global_view.phtml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php $this->partial('nav_menu'); ?>
-
-<?php if (!empty($this->entries)) { ?>
-<div id="stream" class="global categories">
-<?php
- $arUrl = array('c' => 'index', 'a' => 'index', 'params' => array());
- if (FreshRSS_Context::$conf->view_mode !== 'normal') {
- $arUrl['params']['output'] = 'normal';
- }
- $p = Minz_Request::param('state', '');
- if (($p != '') && (FreshRSS_Context::$conf->default_view !== $p)) {
- $arUrl['params']['state'] = $p;
- }
-
- foreach ($this->cat_aside as $cat) {
- $feeds = $cat->feeds();
- if (!empty($feeds)) {
-?>
- <div class="box-category">
- <div class="category">
- <a data-unread="<?php echo formatNumber($cat->nbNotRead()); ?>" class="btn" href="<?php $arUrl['params']['get'] = 'c_' . $cat->id(); echo Minz_Url::display($arUrl); ?>">
- <?php echo $cat->name(); ?>
- </a>
- </div>
- <ul class="feeds">
- <?php foreach ($feeds as $feed) { ?>
- <?php $not_read = $feed->nbNotRead(); ?>
- <li id="f_<?php echo $feed->id(); ?>" class="item<?php echo $feed->inError() ? ' error' : ''; ?><?php echo $feed->nbEntries() == 0 ? ' empty' : ''; ?>">
- <img class="favicon" src="<?php echo $feed->favicon(); ?>" alt="✇" />
- <a class="feed" data-unread="<?php echo formatNumber($feed->nbNotRead()); ?>" data-priority="<?php echo $feed->priority(); ?>" href="<?php $arUrl['params']['get'] = 'f_' . $feed->id(); echo Minz_Url::display($arUrl); ?>">
- <?php echo $feed->name(); ?>
- </a>
- </li>
- <?php } ?>
- </ul>
- </div>
-<?php
- }
- }
-?>
-</div>
-
-<div id="overlay"></div>
-<div id="panel"<?php echo FreshRSS_Context::$conf->display_posts ? '' : ' class="hide_posts"'; ?>>
- <a class="close" href="#"><?php echo _i('close'); ?></a>
-</div>
-
-<?php } else { ?>
-<div id="stream" class="prompt alert alert-warn global">
- <h2><?php echo _t('no_feed_to_display'); ?></h2>
- <a href="<?php echo _url('subscription', 'index'); ?>"><?php echo _t('think_to_add'); ?></a><br /><br />
-</div>
-<?php } ?>
diff --git a/app/views/index/global.phtml b/app/views/index/global.phtml
new file mode 100644
index 000000000..0975a5a00
--- /dev/null
+++ b/app/views/index/global.phtml
@@ -0,0 +1,53 @@
+<?php
+ $this->partial('nav_menu');
+
+ $class = '';
+ if (FreshRSS_Context::$conf->hide_read_feeds &&
+ FreshRSS_Context::isStateEnabled(FreshRSS_Entry::STATE_NOT_READ) &&
+ !FreshRSS_Context::isStateEnabled(FreshRSS_Entry::STATE_READ)) {
+ $class = ' state_unread';
+ }
+?>
+
+<div id="stream" class="global<?php echo $class; ?>">
+<?php
+ $url_base = array(
+ 'c' => 'index',
+ 'a' => 'index',
+ 'params' => Minz_Request::params()
+ );
+
+ foreach ($this->categories as $cat) {
+ $feeds = $cat->feeds();
+ $url_base['params']['get'] = 'c_' . $cat->id();
+
+ if (!empty($feeds)) {
+?>
+ <div class="box category" data-unread="<?php echo $cat->nbNotRead(); ?>">
+ <div class="box-title"><a class="title" data-unread="<?php echo format_number($cat->nbNotRead()); ?>" href="<?php echo Minz_Url::display($url_base); ?>"><?php echo $cat->name(); ?></a></div>
+
+ <ul class="box-content">
+ <?php
+ foreach ($feeds as $feed) {
+ $nb_not_read = $feed->nbNotRead();
+ $error = $feed->inError() ? ' error' : '';
+ $empty = $feed->nbEntries() === 0 ? ' empty' : '';
+ $url_base['params']['get'] = 'f_' . $feed->id();
+ ?>
+ <li id="f_<?php echo $feed->id(); ?>" class="item feed<?php echo $error, $empty; ?>" data-unread="<?php echo $feed->nbNotRead(); ?>" data-priority="<?php echo $feed->priority(); ?>">
+ <img class="favicon" src="<?php echo $feed->favicon(); ?>" alt="✇" />
+ <a class="item-title" data-unread="<?php echo format_number($feed->nbNotRead()); ?>" href="<?php echo Minz_Url::display($url_base); ?>"><?php echo $feed->name(); ?></a>
+ </li>
+ <?php } ?>
+ </ul>
+ </div>
+<?php
+ }
+ }
+?>
+</div>
+
+<div id="overlay"></div>
+<div id="panel"<?php echo FreshRSS_Context::$conf->display_posts ? '' : ' class="hide_posts"'; ?>>
+ <a class="close" href="#"><?php echo _i('close'); ?></a>
+</div>
diff --git a/app/views/index/index.phtml b/app/views/index/index.phtml
index a59063557..8b93461dd 100644
--- a/app/views/index/index.phtml
+++ b/app/views/index/index.phtml
@@ -7,8 +7,6 @@ if (FreshRSS_Auth::hasAccess() || Minz_Configuration::allowAnonymous()) {
$this->renderHelper('view/normal_view');
} elseif ($output === 'reader') {
$this->renderHelper('view/reader_view');
- } elseif ($output === 'global') {
- $this->renderHelper('view/global_view');
} elseif ($output === 'rss') {
$this->renderHelper('view/rss_view');
} else {
diff --git a/app/views/helpers/view/normal_view.phtml b/app/views/index/normal.phtml
index afe8ed872..02d621bd0 100644
--- a/app/views/helpers/view/normal_view.phtml
+++ b/app/views/index/normal.phtml
@@ -1,6 +1,6 @@
<?php
-$this->partial('aside_flux');
+$this->partial('aside_feed');
$this->partial('nav_menu');
if (!empty($this->entries)) {
@@ -26,33 +26,35 @@ if (!empty($this->entries)) {
$bottomline_link = FreshRSS_Context::$conf->bottomline_link;
$content_width = FreshRSS_Context::$conf->content_width;
+
+ $today = @strtotime('today');
?>
<div id="stream" class="normal<?php echo $hidePosts ? ' hide_posts' : ''; ?>"><?php
?><div id="new-article">
- <a href="<?php echo Minz_Url::display($this->url); ?>"><?php echo _t('new_article'); ?></a>
+ <a href="<?php echo Minz_Url::display(Minz_Request::currentRequest()); ?>"><?php echo _t('new_article'); ?></a>
</div><?php
foreach ($this->entries as $item) {
- if ($display_today && $item->isDay(FreshRSS_Days::TODAY, $this->today)) {
+ if ($display_today && $item->isDay(FreshRSS_Days::TODAY, $today)) {
?><div class="day" id="day_today"><?php
echo _t('today');
?><span class="date"> — <?php echo timestamptodate(time(), false); ?></span><?php
- ?><span class="name"><?php echo $this->currentName; ?></span><?php
+ ?><span class="name"><?php echo FreshRSS_Context::$name; ?></span><?php
?></div><?php
$display_today = false;
}
- if ($display_yesterday && $item->isDay(FreshRSS_Days::YESTERDAY, $this->today)) {
+ if ($display_yesterday && $item->isDay(FreshRSS_Days::YESTERDAY, $today)) {
?><div class="day" id="day_yesterday"><?php
echo _t('yesterday');
?><span class="date"> — <?php echo timestamptodate(time() - 86400, false); ?></span><?php
- ?><span class="name"><?php echo $this->currentName; ?></span><?php
+ ?><span class="name"><?php echo FreshRSS_Context::$name; ?></span><?php
?></div><?php
$display_yesterday = false;
}
- if ($display_others && $item->isDay(FreshRSS_Days::BEFORE_YESTERDAY, $this->today)) {
+ if ($display_others && $item->isDay(FreshRSS_Days::BEFORE_YESTERDAY, $today)) {
?><div class="day" id="day_before_yesterday"><?php
echo _t('before_yesterday');
- ?><span class="name"><?php echo $this->currentName; ?></span><?php
+ ?><span class="name"><?php echo FreshRSS_Context::$name; ?></span><?php
?></div><?php
$display_others = false;
}
@@ -80,7 +82,7 @@ if (!empty($this->entries)) {
?></li><?php
}
}
- $feed = FreshRSS_CategoryDAO::findFeed($this->cat_aside, $item->feed()); //We most likely already have the feed object in cache
+ $feed = FreshRSS_CategoryDAO::findFeed($this->categories, $item->feed()); //We most likely already have the feed object in cache
if ($feed == null) {
$feed = $item->feed(true);
if ($feed == null) {
diff --git a/app/views/helpers/view/reader_view.phtml b/app/views/index/reader.phtml
index 821a50f7f..f07868488 100644
--- a/app/views/helpers/view/reader_view.phtml
+++ b/app/views/index/reader.phtml
@@ -13,7 +13,7 @@ if (!empty($this->entries)) {
<div class="flux_content">
<div class="content <?php echo $content_width; ?>">
<?php
- $feed = FreshRSS_CategoryDAO::findFeed($this->cat_aside, $item->feed()); //We most likely already have the feed object in cache
+ $feed = FreshRSS_CategoryDAO::findFeed($this->categories, $item->feed()); //We most likely already have the feed object in cache
if (empty($feed)) $feed = $item->feed(true);
?>
<a href="<?php echo $item->link(); ?>">
diff --git a/app/views/helpers/view/rss_view.phtml b/app/views/index/rss.phtml
index e34b15ab1..e34b15ab1 100755
--- a/app/views/helpers/view/rss_view.phtml
+++ b/app/views/index/rss.phtml
diff --git a/lib/Minz/Request.php b/lib/Minz/Request.php
index f7a24c026..4b97a3caf 100644
--- a/lib/Minz/Request.php
+++ b/lib/Minz/Request.php
@@ -45,6 +45,13 @@ class Minz_Request {
public static function defaultActionName() {
return self::$default_action_name;
}
+ public static function currentRequest() {
+ return array(
+ 'c' => self::$controller_name,
+ 'a' => self::$action_name,
+ 'params' => self::$params,
+ );
+ }
/**
* Setteurs
diff --git a/lib/lib_rss.php b/lib/lib_rss.php
index 9abdf18ce..80eb206d2 100644
--- a/lib/lib_rss.php
+++ b/lib/lib_rss.php
@@ -60,6 +60,10 @@ function formatNumber($n, $precision = 0) {
return str_replace(' ', ' ', //Espace insécable //TODO: remplacer par une espace _fine_ insécable
number_format($n, $precision, '.', ' ')); //number_format does not seem to be Unicode-compatible
}
+function format_number($n, $precision = 0) {
+ // TODO: coding style, prefer THIS function. Remove formatNumber.
+ return formatNumber($n, $precision);
+}
function formatBytes($bytes, $precision = 2, $system = 'IEC') {
if ($system === 'IEC') {
diff --git a/p/scripts/global_view.js b/p/scripts/global_view.js
index 6e1f61066..14909f44e 100644
--- a/p/scripts/global_view.js
+++ b/p/scripts/global_view.js
@@ -9,7 +9,7 @@ function load_panel(link) {
panel_loading = true;
$.get(link, function (data) {
- $("#panel").append($(".nav_menu, #stream .day, #stream .flux, #stream .pagination", data));
+ $("#panel").append($(".nav_menu, #stream .day, #stream .flux, #stream .pagination, #stream.prompt", data));
$("#panel .nav_menu").children().not("#nav_menu_read_all").remove();
@@ -50,7 +50,8 @@ function init_close_panel() {
}
function init_global_view() {
- $("#stream .box-category a").click(function () {
+ // TODO: should be based on generic classes.
+ $(".box a").click(function () {
var link = $(this).attr("href");
load_panel(link);
diff --git a/p/scripts/main.js b/p/scripts/main.js
index 1e13ff16a..b6370866f 100644
--- a/p/scripts/main.js
+++ b/p/scripts/main.js
@@ -56,31 +56,31 @@ function incLabel(p, inc, spaceAfter) {
function incUnreadsFeed(article, feed_id, nb) {
//Update unread: feed
- var elem = $('#' + feed_id + '>.feed').get(0),
+ var elem = $('#' + feed_id).get(0),
feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0,
feed_priority = elem ? str2int(elem.getAttribute('data-priority')) : 0;
if (elem) {
- elem.setAttribute('data-unread', numberFormat(feed_unreads + nb));
- elem = $(elem).closest('li').get(0);
+ elem.setAttribute('data-unread', feed_unreads + nb);
+ elem = $(elem).children('.item-title').get(0);
if (elem) {
- elem.setAttribute('data-unread', feed_unreads + nb);
+ elem.setAttribute('data-unread', numberFormat(feed_unreads + nb));
}
}
//Update unread: category
- elem = $('#' + feed_id).parent().prevAll('.category').children(':first').get(0);
+ elem = $('#' + feed_id).parents('.category').get(0);
feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0;
if (elem) {
- elem.setAttribute('data-unread', numberFormat(feed_unreads + nb));
- elem = $(elem).closest('li').get(0);
+ elem.setAttribute('data-unread', feed_unreads + nb);
+ elem = $(elem).find('.title').get(0);
if (elem) {
- elem.setAttribute('data-unread', feed_unreads + nb);
+ elem.setAttribute('data-unread', numberFormat(feed_unreads + nb));
}
}
//Update unread: all
if (feed_priority > 0) {
- elem = $('#aside_flux .all').children(':first').get(0);
+ elem = $('#aside_feed .all .title').get(0);
if (elem) {
feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0;
elem.setAttribute('data-unread', numberFormat(feed_unreads + nb));
@@ -89,7 +89,7 @@ function incUnreadsFeed(article, feed_id, nb) {
//Update unread: favourites
if (article && article.closest('div').hasClass('favorite')) {
- elem = $('#aside_flux .favorites').children(':first').get(0);
+ elem = $('#aside_feed .favorites .title').get(0);
if (elem) {
feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0;
elem.setAttribute('data-unread', numberFormat(feed_unreads + nb));
@@ -97,7 +97,7 @@ function incUnreadsFeed(article, feed_id, nb) {
}
var isCurrentView = false;
- //Update unread: title
+ // Update unread: title
document.title = document.title.replace(/^((?:\([ 0-9]+\) )?)/, function (m, p1) {
var $feed = $('#' + feed_id);
if (article || ($feed.closest('.active').length > 0 && $feed.siblings('.active').length === 0)) {
@@ -194,7 +194,7 @@ function mark_favorite(active) {
}
$b.find('.icon').replaceWith(data.icon);
- var favourites = $('.favorites>a').contents().last().get(0);
+ var favourites = $('#aside_feed .favorites .title').contents().last().get(0);
if (favourites && favourites.textContent) {
favourites.textContent = favourites.textContent.replace(/((?: \([ 0-9]+\))?\s*)$/, function (m, p1) {
return incLabel(p1, inc, false);
@@ -202,7 +202,7 @@ function mark_favorite(active) {
}
if (active.closest('div').hasClass('not_read')) {
- var elem = $('#aside_flux .favorites').children(':first').get(0),
+ var elem = $('#aside_feed .favorites .title').get(0),
feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0;
if (elem) {
elem.setAttribute('data-unread', numberFormat(feed_unreads + inc));
@@ -292,42 +292,42 @@ function next_entry() {
}
function prev_feed() {
- var active_feed = $("#aside_flux .feeds li.active");
+ var active_feed = $("#aside_feed .tree-folder-items .item.active");
if (active_feed.length > 0) {
- active_feed.prevAll(':visible:first').find('a.feed').each(function(){this.click();});
+ active_feed.prevAll(':visible:first').find('a').each(function(){this.click();});
} else {
last_feed();
}
}
function next_feed() {
- var active_feed = $("#aside_flux .feeds li.active");
+ var active_feed = $("#aside_feed .tree-folder-items .item.active");
if (active_feed.length > 0) {
- active_feed.nextAll(':visible:first').find('a.feed').each(function(){this.click();});
+ active_feed.nextAll(':visible:first').find('a').each(function(){this.click();});
} else {
first_feed();
}
}
function first_feed() {
- var feed = $("#aside_flux .feeds.active li:visible:first");
+ var feed = $("#aside_feed .tree-folder-items.active .item:visible:first");
if (feed.length > 0) {
feed.find('a')[1].click();
}
}
function last_feed() {
- var feed = $("#aside_flux .feeds.active li:visible:last");
+ var feed = $("#aside_feed .tree-folder-items.active .item:visible:last");
if (feed.length > 0) {
feed.find('a')[1].click();
}
}
function prev_category() {
- var active_cat = $("#aside_flux .category.stick.active");
+ var active_cat = $("#aside_feed .tree-folder.active");
if (active_cat.length > 0) {
- var prev_cat = active_cat.parent('li').prevAll(':visible:first').find('.category.stick a.btn');
+ var prev_cat = active_cat.prevAll(':visible:first').find('.tree-folder-title .title');
if (prev_cat.length > 0) {
prev_cat[0].click();
}
@@ -338,10 +338,10 @@ function prev_category() {
}
function next_category() {
- var active_cat = $("#aside_flux .category.stick.active");
+ var active_cat = $("#aside_feed .tree-folder.active");
if (active_cat.length > 0) {
- var next_cat = active_cat.parent('li').nextAll(':visible:first').find('.category.stick a.btn');
+ var next_cat = active_cat.nextAll(':visible:first').find('.tree-folder-title .title');
if (next_cat.length > 0) {
next_cat[0].click();
}
@@ -352,16 +352,16 @@ function next_category() {
}
function first_category() {
- var cat = $("#aside_flux .category.stick:visible:first");
+ var cat = $("#aside_feed .tree-folder:visible:first");
if (cat.length > 0) {
- cat.find('a.btn')[0].click();
+ cat.find('.tree-folder-title .title')[0].click();
}
}
function last_category() {
- var cat = $("#aside_flux .category.stick:visible:last");
+ var cat = $("#aside_feed .tree-folder:visible:last");
if (cat.length > 0) {
- cat.find('a.btn')[0].click();
+ cat.find('.tree-folder-title .title')[0].click();
}
}
@@ -487,7 +487,8 @@ function init_column_categories() {
if (context['current_view'] !== 'normal') {
return;
}
- $('#aside_flux').on('click', '.category>a.dropdown-toggle', function () {
+
+ $('#aside_feed').on('click', '.tree-folder>.tree-folder-title>a.dropdown-toggle', function () {
$(this).children().each(function() {
if (this.alt === '▽') {
this.src = this.src.replace('/icons/down.', '/icons/up.');
@@ -497,12 +498,12 @@ function init_column_categories() {
this.alt = '▽';
}
});
- $(this).parent().next(".feeds").slideToggle();
+ $(this).parent().next(".tree-folder-items").slideToggle();
return false;
});
- $('#aside_flux').on('click', '.feeds .dropdown-toggle', function () {
+ $('#aside_feed').on('click', '.tree-folder-items .item .dropdown-toggle', function () {
if ($(this).nextAll('.dropdown-menu').length === 0) {
- var feed_id = $(this).closest('li').attr('id').substr(2),
+ var feed_id = $(this).closest('.item').attr('id').substr(2),
feed_web = $(this).data('fweb'),
template = $('#feed_config_template').html().replace(/!!!!!!/g, feed_id).replace('http://example.net/', feed_web);
$(this).attr('href', '#dropdown-' + feed_id).prev('.dropdown-target').attr('id', 'dropdown-' + feed_id).parent().append(template);
@@ -875,12 +876,12 @@ function init_notifs_html5() {
function refreshUnreads() {
$.getJSON('./?c=javascript&a=nbUnreadsPerFeed').done(function (data) {
- var isAll = $('.category.all > .active').length > 0,
+ var isAll = $('.category.all.active').length > 0,
new_articles = false;
$.each(data, function(feed_id, nbUnreads) {
feed_id = 'f_' + feed_id;
- var elem = $('#' + feed_id + '>.feed').get(0),
+ var elem = $('#' + feed_id).get(0),
feed_unreads = elem ? str2int(elem.getAttribute('data-unread')) : 0;
if ((incUnreadsFeed(null, feed_id, nbUnreads - feed_unreads) || isAll) && //Update of current view?
@@ -890,7 +891,7 @@ function refreshUnreads() {
};
});
- var nb_unreads = str2int($('.category.all>a').attr('data-unread'));
+ var nb_unreads = str2int($('.category.all .title').attr('data-unread'));
if (nb_unreads > 0 && new_articles) {
faviconNbUnread(nb_unreads);
@@ -1135,7 +1136,7 @@ function init_password_observers() {
function faviconNbUnread(n) {
if (typeof n === 'undefined') {
- n = str2int($('.category.all>a').attr('data-unread'));
+ n = str2int($('.category.all .title').attr('data-unread'));
}
//http://remysharp.com/2010/08/24/dynamic-favicons/
var canvas = document.createElement('canvas'),
diff --git a/p/themes/Dark/dark.css b/p/themes/Dark/dark.css
index f3790614e..e551aa9c0 100644
--- a/p/themes/Dark/dark.css
+++ b/p/themes/Dark/dark.css
@@ -464,6 +464,48 @@ a.btn {
visibility: visible;
}
+/*=== Tree */
+.tree {
+ margin: 10px 0;
+}
+.tree-folder-title {
+ position: relative;
+ padding: 0 10px;
+ line-height: 2.5rem;
+ font-size: 1rem;
+ background: #1c1c1c;
+ font-weight: bold;
+}
+.tree-folder-title .title {
+ background: inherit;
+ color: #888;
+}
+.tree-folder-title .title:hover {
+ text-decoration: none;
+}
+.tree-folder.active .tree-folder-title {
+ background: #2c2c2c;
+}
+.tree-folder-items {
+ border-top: 1px solid #222;
+ border-bottom: 1px solid #222;
+ background: #161616;
+}
+.tree-folder-items > .item {
+ padding: 0 10px;
+ line-height: 2.5rem;
+ font-size: 0.8rem;
+}
+.tree-folder-items > .item.active {
+ background: #1c1c1c;
+}
+.tree-folder-items > .item > a {
+ text-decoration: none;
+}
+.tree-folder-items > .item.active > a {
+ color: #888;
+}
+
/*=== STRUCTURE */
/*===============*/
/*=== Header */
@@ -500,81 +542,60 @@ a.btn {
border-right: 1px solid #333;
background: #1c1c1c;
}
-.aside.aside_flux {
- padding: 10px 0 50px;
- border-right: 1px solid #333;
- background: #1c1c1c;
-}
-
-/*=== Aside main page (categories) */
-.categories {
+.aside.aside_feed {
+ padding: 10px 0;
text-align: center;
}
-.category {
- width: 235px;
- margin: 10px auto;
- text-align: left;
-}
-.category .btn:first-child {
- position: relative;
- width: 213px;
-}
-.category.stick .btn:first-child {
- width: 176px;
+.aside.aside_feed .tree {
+ position: sticky;
+ top: 0;
+ margin: 10px 0 50px;
}
-.category .btn:first-child:not([data-unread="0"]):after {
+
+/*=== Aside main page (categories) */
+.aside_feed .tree-folder-title > .title:not([data-unread="0"]):after {
position: absolute;
- top: 3px; right: 3px;
- padding: 1px 5px;
- background: #111;
- color: #888;
- border: 1px solid #000;
- border-radius: 5px;
+ right: 0;
+ margin: 10px 0;
+ padding: 0 10px;
+ font-size: 0.9rem;
+ line-height: 1.5rem;
+ background: inherit;
+ border-left: 1px solid #666;
}
/*=== Aside main page (feeds) */
-.categories .feeds .item.active {
- background: #333;
+.feed.item.empty.active {
+ background: #c95;
}
-.categories .feeds .item.active .feed {
- color: #888;
+.feed.item.error.active {
+ background: #a44;
}
-.categories .feeds .item.empty .feed {
+.feed.item.empty,
+.feed.item.empty > a {
color: #c95;
}
-.categories .feeds .item.empty.active {
- background: #c95;
-}
-.categories .feeds .item.error .feed {
+.feed.item.error,
+.feed.item.error > a {
color: #a44;
}
-.categories .feeds .item.error.active {
- background: #a44;
+.feed.item.empty.active,
+.feed.item.empty.active > a {
+ color: #111;
}
-.categories .feeds .item.empty.active .feed,
-.categories .feeds .item.error.active .feed {
+.feed.item.error.active,
+.feed.item.error.active > a {
color: #fff;
}
-.categories .feeds .item .feed {
- margin: 0;
- width: 165px;
- line-height: 3em;
- font-size: 0.8em;
- text-align: left;
- text-decoration: none;
-}
-.categories .feeds .feed:not([data-unread="0"]) {
- font-weight: bold;
-}
-.categories .feeds .dropdown-menu:after {
+.aside_feed .tree-folder-items .dropdown-menu:after {
left: 2px;
}
-.categories .feeds .item .dropdown-target:target ~ .dropdown-toggle > .icon,
-.categories .feeds .item:hover .dropdown-toggle > .icon,
-.categories .feeds .item.active .dropdown-toggle > .icon {
+.aside_feed .tree-folder-items .item .dropdown-target:target ~ .dropdown-toggle > .icon,
+.aside_feed .tree-folder-items .item:hover .dropdown-toggle > .icon,
+.aside_feed .tree-folder-items .item.active .dropdown-toggle > .icon {
+ border-radius: 3px;
vertical-align: middle;
background-color: #111;
- border-radius: 3px;
}
/*=== Configuration pages */
@@ -825,46 +846,34 @@ a.btn {
/*=== GLOBAL VIEW */
/*================*/
-#stream.global .box-category {
- text-align: left;
- background: #1a1a1a;
- border: 1px solid #000;
- border-radius: 5px;
+.box.category .box-title .title {
+ font-weight: normal;
+ text-decoration: none;
text-align: left;
+ color: #888;
}
-#stream.global .category {
- margin: 0;
+.box.category:not([data-unread="0"]) .box-title {
+ background: #34495E;
}
-#stream.global .btn {
- width: auto;
- height: 2em;
- margin: 0;
- padding: 0 10px;
- line-height: 2em;
- font-size: 1.2rem;
+.box.category:not([data-unread="0"]) .box-title:active {
background: #26303F;
- border: none;
- border-bottom: 1px solid #000;
- border-radius: 5px 5px 0 0;
}
-#stream.global .btn:not([data-unread="0"]) {
- font-weight: bold;
- background: #34495e;
+.box.category:not([data-unread="0"]) .box-title .title {
color: #fff;
-}
-#stream.global .btn:first-child:not([data-unread="0"]):after {
- top: 0; right: 5px;
font-weight: bold;
+}
+.box.category .title:not([data-unread="0"]):after {
+ position: absolute;
+ top: 5px; right: 10px;
border: 0;
background: none;
- color: #fff;
-}
-#stream.global .box-category .feeds {
- max-height: 250px;
+ font-weight: bold;
+ box-shadow: none;
+ text-shadow: none;
}
-#stream.global .box-category .feeds .item {
+.box.category .item.feed {
padding: 2px 10px;
- font-size: 0.9rem;
+ font-size: 0.8rem;
}
/*=== Panel */
@@ -963,17 +972,20 @@ a.btn {
}
.aside .toggle_aside,
#panel .close {
- position: absolute;
display: block;
- top: 0; right: 0;
- width: 30px;
- height: 30px;
- line-height: 30px;
+ width: 100%;
+ height: 50px;
+ line-height: 50px;
text-align: center;
background: #111;
- border-left: 1px solid #333;
border-bottom: 1px solid #333;
- border-radius: 0 0 0 5px;
+ }
+
+ .aside.aside_feed {
+ padding: 0;
+ }
+ .aside.aside_feed .tree {
+ position: static;
}
.nav_menu .btn {
diff --git a/p/themes/Flat/flat.css b/p/themes/Flat/flat.css
index e2151b1f9..eb7737c5d 100644
--- a/p/themes/Flat/flat.css
+++ b/p/themes/Flat/flat.css
@@ -473,6 +473,44 @@ a.btn {
visibility: visible;
}
+/*=== Tree */
+.tree {
+ margin: 10px 0;
+}
+.tree-folder-title {
+ position: relative;
+ padding: 0 10px;
+ background: #34495e;
+ line-height: 2.5rem;
+ font-size: 1rem;
+ font-weight: bold;
+}
+.tree-folder-title .title {
+ background: inherit;
+ color: #fff;
+}
+.tree-folder-title .title:hover {
+ text-decoration: none;
+}
+.tree-folder.active .tree-folder-title {
+ background: #2980b9;
+}
+.tree-folder-items {
+ background: #2c3e50;
+}
+.tree-folder-items > .item {
+ padding: 0 10px;
+ line-height: 2.5rem;
+ font-size: 0.8rem;
+}
+.tree-folder-items > .item.active {
+ background: #2980b9;
+}
+.tree-folder-items > .item > a {
+ text-decoration: none;
+ color: #fff;
+}
+
/*=== STRUCTURE */
/*===============*/
/*=== Header */
@@ -508,77 +546,58 @@ a.btn {
.aside {
background: #ecf0f1;
}
-.aside.aside_flux {
- padding: 10px 0 50px;
- background: #ecf0f1;
-}
-
-/*=== Aside main page (categories) */
-.categories {
+.aside.aside_feed {
+ padding: 10px 0;
text-align: center;
+ background: #34495e;
+ border-radius: 0 10px 0 0;
}
-.category {
- width: 233px;
- margin: 10px auto;
- text-align: left;
-}
-.category .btn:first-child {
- position: relative;
- width: 212px;
-}
-.category.stick .btn:first-child {
- width: 175px;
+.aside.aside_feed .tree {
+ position: sticky;
+ top: 0;
+ margin: 10px 0 50px;
}
-.category .btn:first-child:not([data-unread="0"]):after {
+
+/*=== Aside main page (categories) */
+.aside_feed .tree-folder-title > .title:not([data-unread="0"]):after {
position: absolute;
- top: 5px; right: 5px;
- padding: 1px 5px;
- background: #3498DB;
- color: #fff;
- border-radius: 5px;
+ right: 0;
+ margin: 10px 0;
+ padding: 0 10px;
+ font-size: 0.9rem;
+ line-height: 1.5rem;
+ background: inherit;
}
/*=== Aside main page (feeds) */
-.categories .feeds .item.active {
- background: #2980b9;
-}
-.categories .feeds .item.empty.active {
+.feed.item.empty.active {
background: #f39c12;
}
-.categories .feeds .item.error.active {
+.feed.item.error.active {
background: #bd362f;
}
-.categories .feeds .item.empty .feed {
+.feed.item.empty,
+.feed.item.empty > a {
color: #e67e22;
}
-.categories .feeds .item.error .feed {
+.feed.item.error,
+.feed.item.error > a {
color: #bd362f;
}
-.categories .feeds .item.active .feed,
-.categories .feeds .item.empty.active .feed,
-.categories .feeds .item.error.active .feed {
+.feed.item.empty.active,
+.feed.item.error.active,
+.feed.item.empty.active > a,
+.feed.item.error.active > a {
color: #fff;
}
-.categories .feeds .item .feed {
- margin: 0;
- width: 165px;
- line-height: 3em;
- font-size: 0.8em;
- text-align: left;
- text-decoration: none;
-}
-.categories .feeds .feed:not([data-unread="0"]) {
- font-weight: bold;
-}
-.categories .feeds .dropdown-menu:after {
+.aside_feed .tree-folder-items .dropdown-menu:after {
left: 2px;
}
-.categories .feeds .item .dropdown-target:target ~ .dropdown-toggle > .icon,
-.categories .feeds .item:hover .dropdown-toggle > .icon,
-.categories .feeds .item.active .dropdown-toggle > .icon {
- vertical-align: middle;
- background-color: #95a5a6;
+.aside_feed .tree-folder-items .item .dropdown-target:target ~ .dropdown-toggle > .icon,
+.aside_feed .tree-folder-items .item:hover .dropdown-toggle > .icon,
+.aside_feed .tree-folder-items .item.active .dropdown-toggle > .icon {
border-radius: 3px;
+ vertical-align: middle;
}
/*=== Configuration pages */
@@ -833,44 +852,33 @@ a.btn {
/*=== GLOBAL VIEW */
/*================*/
-#stream.global .box-category {
+.box.category .box-title .title {
+ font-weight: normal;
+ text-decoration: none;
text-align: left;
- border: 1px solid #ddd;
- border-radius: 5px;
}
-#stream.global .category {
- margin: 0;
+.box.category:not([data-unread="0"]) .box-title {
+ background: #3498db;
}
-#stream.global .btn {
- width: auto;
- height: 2em;
- margin: 0;
- padding: 0 10px;
- line-height: 2em;
- font-size: 1.2rem;
- background: #ecf0f1;
- color: #333;
- border-bottom: 1px solid #ddd;
- border-radius: 5px 5px 0 0;
+.box.category:not([data-unread="0"]) .box-title:active {
+ background: #2980b9;
}
-#stream.global .btn:not([data-unread="0"]) {
+.box.category:not([data-unread="0"]) .box-title .title {
font-weight: bold;
- background: #3498db;
color: #fff;
}
-#stream.global .btn:first-child:not([data-unread="0"]):after {
- top: 0; right: 5px;
- font-weight: bold;
- background: none;
+.box.category .title:not([data-unread="0"]):after {
+ position: absolute;
+ top: 5px; right: 10px;
border: 0;
- color: #fff;
-}
-#stream.global .box-category .feeds {
- max-height: 250px;
+ background: none;
+ font-weight: bold;
+ box-shadow: none;
+ text-shadow: none;
}
-#stream.global .box-category .feeds .item {
+.box.category .item.feed {
padding: 2px 10px;
- font-size: 0.9rem;
+ font-size: 0.8rem;
}
/*=== DIVERS */
@@ -961,15 +969,19 @@ a.btn {
}
.aside .toggle_aside,
#panel .close {
- position: absolute;
display: block;
- top: 0; right: 0;
- width: 32px;
- height: 32px;
- line-height: 30px;
+ width: 100%;
+ height: 50px;
+ line-height: 50px;
text-align: center;
- background: #34495e;
- border-radius: 0 0 0 5px;
+ background: #2c3e50;
+ }
+
+ .aside.aside_feed {
+ padding: 0;
+ }
+ .aside.aside_feed .tree {
+ position: static;
}
.nav_menu .btn {
diff --git a/p/themes/Origine/origine.css b/p/themes/Origine/origine.css
index b25deab0c..464422a0b 100644
--- a/p/themes/Origine/origine.css
+++ b/p/themes/Origine/origine.css
@@ -498,6 +498,51 @@ a.btn {
visibility: visible;
}
+/*=== Tree */
+.tree {
+ margin: 10px 0;
+}
+.tree-folder-title {
+ position: relative;
+ padding: 0 10px;
+ background: #fff;
+ line-height: 2.5rem;
+ font-size: 1rem;
+ font-weight: bold;
+}
+.tree-folder-title .title {
+ background: inherit;
+ color: #444;
+}
+.tree-folder-title .title:hover {
+ text-decoration: none;
+}
+.tree-folder.active .tree-folder-title {
+ background: #f0f0f0;
+}
+.tree-folder.active .tree-folder-title .title {
+ color: #0062BE;
+}
+.tree-folder-items {
+ border-top: 1px solid #ccc;
+ border-bottom: 1px solid #ccc;
+ background: #f6f6f6;
+}
+.tree-folder-items > .item {
+ padding: 0 10px;
+ line-height: 2.5rem;
+ font-size: 0.8rem;
+}
+.tree-folder-items > .item.active {
+ background: #0062be;
+}
+.tree-folder-items > .item > a {
+ text-decoration: none;
+}
+.tree-folder-items > .item.active > a {
+ color: #fff;
+}
+
/*=== STRUCTURE */
/*===============*/
/*=== Header */
@@ -536,76 +581,56 @@ a.btn {
border-right: 1px solid #aaa;
background: #fff;
}
-.aside.aside_flux {
- padding: 10px 0 50px;
-}
-
-/*=== Aside main page (categories) */
-.categories {
+.aside.aside_feed {
+ padding: 10px 0;
text-align: center;
+ background: #fff;
}
-.category {
- width: 235px;
- margin: 10px auto;
- text-align: left;
-}
-.category .btn:first-child {
- position: relative;
- width: 213px;
-}
-.category.stick .btn:first-child {
- width: 176px;
+.aside.aside_feed .tree {
+ position: sticky;
+ top: 0;
+ margin: 10px 0 50px;
}
-.category .btn:first-child:not([data-unread="0"]):after {
+
+/*=== Aside main page (categories) */
+.aside_feed .category .title:not([data-unread="0"]):after {
position: absolute;
- top: 3px; right: 3px;
- padding: 1px 5px;
- background: #ccc;
- color: #fff;
- border: 1px solid #bbb;
- border-radius: 5px;
- box-shadow: 1px 3px 3px #aaa inset;
- text-shadow: 0 0 1px #aaa;
+ right: 0;
+ margin: 10px 0;
+ padding: 0 10px;
+ font-size: 0.9rem;
+ line-height: 1.5rem;
+ background: inherit;
+ border-left: 1px solid #aaa;
}
/*=== Aside main page (feeds) */
-.categories .feeds .item.active {
- background: #0062BE;
-}
-.categories .feeds .item.empty.active {
+.feed.item.empty.active {
background: #e67e22;
}
-.categories .feeds .item.error.active {
- background: #BD362F;
+.feed.item.error.active {
+ background: #bd362f;
}
-.categories .feeds .item.empty .feed {
+.feed.item.empty,
+.feed.item.empty > a {
color: #e67e22;
}
-.categories .feeds .item.error .feed {
- color: #BD362F;
+.feed.item.error,
+.feed.item.error > a {
+ color: #bd362f;
}
-.categories .feeds .item.active .feed,
-.categories .feeds .item.empty.active .feed,
-.categories .feeds .item.error.active .feed {
+.feed.item.empty.active,
+.feed.item.error.active,
+.feed.item.empty.active > a,
+.feed.item.error.active > a {
color: #fff;
}
-.categories .feeds .item .feed {
- margin: 0;
- width: 165px;
- line-height: 3em;
- font-size: 0.8em;
- text-align: left;
- text-decoration: none;
-}
-.categories .feeds .feed:not([data-unread="0"]) {
- font-weight: bold;
-}
-.categories .feeds .dropdown-menu:after {
+.aside_feed .tree-folder-items .dropdown-menu:after {
left: 2px;
}
-.categories .feeds .item .dropdown-target:target ~ .dropdown-toggle > .icon,
-.categories .feeds .item:hover .dropdown-toggle > .icon,
-.categories .feeds .item.active .dropdown-toggle > .icon {
+.aside_feed .tree-folder-items .item .dropdown-target:target ~ .dropdown-toggle > .icon,
+.aside_feed .tree-folder-items .item:hover .dropdown-toggle > .icon,
+.aside_feed .tree-folder-items .item.active .dropdown-toggle > .icon {
background-color: #fff;
border-radius: 3px;
vertical-align: middle;
@@ -873,35 +898,24 @@ a.btn {
/*=== GLOBAL VIEW */
/*================*/
-#stream.global .box-category {
- background: #fff;
- border-radius: 5px;
+.box.category .box-title .title {
+ font-weight: normal;
+ text-decoration: none;
text-align: left;
- box-shadow: 0 0 3px #bbb;
}
-#stream.global .category {
- margin: 0;
+.box.category:not([data-unread="0"]) .box-title {
+ background: #0084CC;
}
-#stream.global .btn {
- width: auto;
- height: 2em;
- margin: 0;
- padding: 0 10px;
- background: #f6f6f6;
- border: none;
- border-bottom: 1px solid #ddd;
- border-radius: 5px 5px 0 0;
- line-height: 2em;
- font-size: 1.2rem;
+.box.category:not([data-unread="0"]) .box-title:active {
+ background: #3498db;
}
-#stream.global .btn:not([data-unread="0"]) {
- background: #0084CC;
+.box.category:not([data-unread="0"]) .box-title .title {
color: #fff;
font-weight: bold;
- text-shadow: none;
}
-#stream.global .btn:first-child:not([data-unread="0"]):after {
- top: 0; right: 5px;
+.box.category .title:not([data-unread="0"]):after {
+ position: absolute;
+ top: 5px; right: 10px;
border: 0;
background: none;
color: #fff;
@@ -909,12 +923,9 @@ a.btn {
box-shadow: none;
text-shadow: none;
}
-#stream.global .box-category .feeds {
- max-height: 250px;
-}
-#stream.global .box-category .feeds .item {
+.box.category .item.feed {
padding: 2px 10px;
- font-size: 0.9rem;
+ font-size: 0.8rem;
}
/*=== DIVERS */
@@ -1008,17 +1019,20 @@ a.btn {
}
.aside .toggle_aside,
#panel .close {
- position: absolute;
display: block;
- top: 0; right: 0;
- width: 30px;
- height: 30px;
- line-height: 30px;
+ width: 100%;
+ height: 50px;
+ line-height: 50px;
text-align: center;
background: #f6f6f6;
- border-left: 1px solid #ddd;
border-bottom: 1px solid #ddd;
- border-radius: 0 0 0 5px;
+ }
+
+ .aside.aside_feed {
+ padding: 0;
+ }
+ .aside.aside_feed .tree {
+ position: static;
}
.nav_menu .btn {
diff --git a/p/themes/Pafat/pafat.css b/p/themes/Pafat/pafat.css
index 28b17e15f..49cb3bc17 100644
--- a/p/themes/Pafat/pafat.css
+++ b/p/themes/Pafat/pafat.css
@@ -192,48 +192,12 @@ a.btn {
text-decoration: none;
}
-
-.category.stick .btn {
- background:#5bc0de;
- color : #FFF;
- border-color :#5bc0de;
-}
-
-.category.stick .btn:first-child:hover, .category.stick .btn:last-child:hover, .category.stick .btn.active:first-child, .category.stick.active .btn:last-child {
- background:#39b3d7;
- border-color : #39b3d7;
-}
-
-
.btn.active,
.btn:active,
.dropdown-target:target ~ .btn.dropdown-toggle {
background: #eee;
}
-.category.all > .btn {
- background: #428bca;
- color : #FFF;
- border-color : #428bca;
-}
-
-.category.all > .btn:hover {
- background: #3276b1;
- border-color : #3276b1;
-}
-
-.category.favorites > .btn {
- background:#f0ad4e;
- border-color: #f0ad4e;
- color : #fff;
-}
-
-.category.favorites > .btn:hover {
- background: #ed9c28;
- border-color : #ed9c28;
- color : white;
-}
-
.btn-important {
background: #5cb85c;
color: #fff;
@@ -520,6 +484,51 @@ a.btn {
visibility: visible;
}
+/*=== Tree */
+.tree {
+ margin: 10px 0;
+}
+.tree-folder-title {
+ position: relative;
+ margin: 5px;
+ padding: 0 10px;
+ line-height: 2rem;
+ font-size: 0.9rem;
+ background: #5bc0de;
+ color: #fff;
+ border-top: 1px solid transparent;
+ border-bottom: 1px solid transparent;
+ border-radius: 5px;
+}
+.tree-folder-title .title {
+ background: inherit;
+ color: #fff;
+}
+.tree-folder-title .title:hover {
+ text-decoration: none;
+}
+.tree-folder.active .tree-folder-title {
+ background: #39b3d7;
+ font-weight: bold;
+ font-size: 1rem;
+ border-top: 1px solid #666;
+ border-bottom: 1px solid #666;
+}
+.tree-folder-items > .item {
+ padding: 0 10px;
+ line-height: 2.5rem;
+ font-size: 0.8rem;
+}
+.tree-folder-items > .item.active {
+ background: #5cb85c;
+}
+.tree-folder-items > .item > a {
+ text-decoration: none;
+}
+.tree-folder-items > .item.active > a {
+ color: #fff;
+}
+
/*=== STRUCTURE */
/*===============*/
/*=== Header */
@@ -572,75 +581,69 @@ a.btn {
border-right: 1px solid #aaa;
background: #fff;
}
-.aside.aside_flux {
- padding: 10px 0 50px;
+.aside.aside_feed {
+ padding: 10px 0;
+ text-align: center;
+}
+.aside.aside_feed .tree {
+ position: sticky;
+ top: 5px;
+ margin: 10px 0 50px;
}
/*=== Aside main page (categories) */
-.categories {
- text-align: center;
+.aside_feed .tree-folder-title > .title:not([data-unread="0"]):after {
+ position: absolute;
+ top: 0.25rem; right: 3px;
+ padding: 0px 5px;
+ border: 1px solid #fff;
+ border-radius: 3px;
+ font-size: 0.8rem;
+ line-height: 1.5rem;
}
-.category {
- width: 215px;
- margin: 10px auto;
- text-align: left;
+.aside_feed .tree-folder.all .tree-folder-title {
+ background: #428bca;
}
-.category .btn:first-child {
- position: relative;
- width: 203px;
+.aside_feed .tree-folder.all.active .tree-folder-title {
+ background: #3276b1;
}
-.category.stick .btn:first-child {
- width: 176px;
+.aside_feed .tree-folder.favorites .tree-folder-title {
+ background: #f0ad4e;
}
-.category .btn:first-child:not([data-unread="0"]):after {
- position: absolute;
- top: 2px; right: 3px;
- padding: 0px 3px;
- border: 1px solid ;
- border-radius: 3px;
- font-size:10pt;
- line-height : 20px;
+.aside_feed .tree-folder.favorites.active .tree-folder-title {
+ background: #ed9c28;
}
/*=== Aside main page (feeds) */
-.categories .feeds .item.active {
- background: #5cb85c;
+.feed.item.empty.active {
+ background: #e67e22;
}
-.categories .feeds .item.active .feed {
- color: #fff;
+.feed.item.error.active {
+ background: #bd362f;
}
-.categories .feeds .item.empty .feed {
+.feed.item.empty,
+.feed.item.empty > a {
color: #e67e22;
}
-.categories .feeds .item.empty.active {
- background: #e67e22;
+.feed.item.error,
+.feed.item.error > a {
+ color: #bd362f;
}
-.categories .feeds .item.empty.active .feed {
+.feed.item.empty.active,
+.feed.item.error.active,
+.feed.item.empty.active > a,
+.feed.item.error.active > a {
color: #fff;
}
-.categories .feeds .item.error .feed {
- color: #BD362F;
-}
-.categories .feeds .item .feed {
- margin: 0;
- width: 165px;
- line-height: 3em;
- font-size: 0.8em;
- text-align: left;
- text-decoration: none;
-}
-.categories .feeds .feed:not([data-unread="0"]) {
- font-weight: bold;
-}
-.categories .feeds .dropdown-menu:after {
+.aside_feed .tree-folder-items .dropdown-menu:after {
left: 2px;
}
-.categories .feeds .item .dropdown-target:target ~ .dropdown-toggle > .icon,
-.categories .feeds .item:hover .dropdown-toggle > .icon,
-.categories .feeds .item.active .dropdown-toggle > .icon {
- background-color: #fff;
+.aside_feed .tree-folder-items .item .dropdown-target:target ~ .dropdown-toggle > .icon,
+.aside_feed .tree-folder-items .item:hover .dropdown-toggle > .icon,
+.aside_feed .tree-folder-items .item.active .dropdown-toggle > .icon {
border-radius: 3px;
vertical-align: middle;
+ background-color: #fff;
}
/*=== Configuration pages */
@@ -906,63 +909,32 @@ a.btn {
/*=== GLOBAL VIEW */
/*================*/
-#stream.global .box-category {
- background: #fff;
- border:none;
+.box.category .box-title .title {
+ font-weight: normal;
+ text-decoration: none;
text-align: left;
}
-
-#stream.global .category {
- margin: 0;
+.box.category:not([data-unread="0"]) .box-title {
+ background: #5BC0DE;
}
-
-#stream.global .category:first-child {
- margin: 0;
-}
-
-
-#stream.global .btn {
- width: auto;
- height: 2em;
- margin: 0;
- padding: 0 10px;
- background: #f6f6f6;
- border-bottom: 1px solid #aaa;
- border-radius: 5px 5px 0 0;
- line-height: 2em;
- font-size: 1.2rem;
-}
-
-#stream.global .btn:not([data-unread="0"]) {
- background: #5bc0de;
- border-color : #5bc0de;
- color: #fff;
+.box.category:not([data-unread="0"]) .box-title .title {
font-weight: bold;
- text-shadow: none;
-
+ color: #fff;
}
-
-
-#stream.global .btn:first-child:not([data-unread="0"]):after {
- top: 0; right: 5px;
+.box.category .title:not([data-unread="0"]):after {
+ position: absolute;
+ top: 5px; right: 10px;
border: 0;
background: none;
- color: #fff;
font-weight: bold;
box-shadow: none;
text-shadow: none;
+ font-size: 0.8rem;
+ line-height: 1.6rem;
}
-
-#stream.global .box-category .feeds {
- max-height: 250px;
- width: 302px;
- border : solid #aaa 1px;
- border-top : none;
-}
-
-#stream.global .box-category .feeds .item {
+.box.category .item.feed {
padding: 2px 10px;
- font-size: 0.9rem;
+ font-size: 0.8rem;
}
/*=== DIVERS */
@@ -1056,17 +1028,20 @@ a.btn {
}
.aside .toggle_aside,
#panel .close {
- position: absolute;
display: block;
- top: 0; right: 0;
- width: 30px;
- height: 30px;
- line-height: 30px;
+ width: 100%;
+ height: 40px;
+ line-height: 40px;
text-align: center;
background: #f6f6f6;
- border-left: 1px solid #ddd;
border-bottom: 1px solid #ddd;
- border-radius: 0 0 0 5px;
+ }
+
+ .aside.aside_feed {
+ padding: 0;
+ }
+ .aside.aside_feed .tree {
+ position: static;
}
.nav_menu .btn {
diff --git a/p/themes/Screwdriver/screwdriver.css b/p/themes/Screwdriver/screwdriver.css
index 6206504d1..4f55d752e 100644
--- a/p/themes/Screwdriver/screwdriver.css
+++ b/p/themes/Screwdriver/screwdriver.css
@@ -531,6 +531,54 @@ a.btn {
visibility: visible;
}
+/*=== Tree */
+.tree {
+ margin: 10px 0;
+}
+.tree-folder-title {
+ position: relative;
+ padding: 0 10px;
+ line-height: 2.5rem;
+ font-size: 0.9rem;
+}
+.tree-folder-title .title {
+ background: inherit;
+ color: #fff;
+}
+.tree-folder-title .title:hover {
+ text-decoration: none;
+}
+.tree-folder.active .tree-folder-title {
+ background: linear-gradient(180deg, #222 0%, #171717 100%) #171717;
+ background: -webkit-linear-gradient(top, #222 0%, #171717 100%);
+ box-shadow: 0px 1px #171717, 0px 1px rgba(255, 255, 255, 0.08) inset;
+ text-shadow: 0 0 2px rgba(255,255,255,0.28);
+ color: #fff;
+}
+.tree-folder-items {
+ background: #171717;
+ padding: 8px 0;
+ box-shadow: 0 4px 4px #171717 inset, 0 1px rgba(255,255,255,0.08),0 -1px rgba(255,255,255,0.08);
+}
+.tree-folder-items > .item {
+ padding: 0 10px;
+ line-height: 2.5rem;
+ font-size: 0.8rem;
+}
+.tree-folder-items > .item.active {
+ background: linear-gradient(180deg, #222 0%, #171717 100%) #171717;
+ background: -webkit-linear-gradient(top, #222 0%, #171717 100%);
+ border-radius: 4px;
+ margin: 0px 8px;
+ box-shadow: 0px 1px #171717, 0px 1px rgba(255, 255, 255, 0.08) inset, 0 2px 2px #111;
+}
+.tree-folder-items > .item > a {
+ text-decoration: none;
+ color: #fff;
+}
+.tree-folder-items > .item.active > a {
+}
+
/*=== STRUCTURE */
/*===============*/
/*=== Header */
@@ -569,7 +617,7 @@ a.btn {
/*=== Body */
#global {
background:#EDE7DE;
- height: calc(100% - 85px);
+ height: calc(100% - 60px);
}
.aside {
border-radius: 0px 12px 0px 0px;
@@ -578,103 +626,43 @@ a.btn {
background: #222;
width: 235px;
}
-.aside.aside_flux {
- padding: 10px 0 50px;
- background: #222;
-}
-
-/*=== Aside main page (categories) */
-.categories {
+.aside.aside_feed {
+ padding: 10px 0;
text-align: center;
}
-.categories .btn-important {
- border: none;
-}
-.category {
- width: 235px;
- margin: 10px auto 0;
- text-align: left;
-}
-#aside_flux ul.feeds{
- box-shadow: 0 4px 4px #171717 inset, 0 1px rgba(255,255,255,0.08),0 -1px rgba(255,255,255,0.08);
-}
-ul.feeds{
- background:#171717;
- padding:8px 0;
- box-shadow: 0 4px 4px #EDE7DE inset;
-}
-ul.feeds.active{
- box-shadow: 0 0 0 #171717 inset, 0 -2px 2px #111 inset,0 1px rgba(255,255,255,0.08),0 -1px rgba(255,255,255,0);
-}
-.category.stick.active{
- background: linear-gradient(180deg, #222 0%, #171717 100%) #171717;
- background: -webkit-linear-gradient(top, #222 0%, #171717 100%);
- box-shadow: 0px 1px #171717, 0px 1px rgba(255, 255, 255, 0.08) inset;
-}
-.category .btn {
- color: #fff;
- border: none;
- background: transparent;
-}
-.category .btn:first-child {
- position: relative;
- width: 213px;
- background: transparent;
-}
-.category.stick .btn:first-child {
- width: 176px;
+.aside.aside_feed .tree {
+ position: sticky;
+ top: 0;
+ margin: 10px 0 50px;
}
-.category .btn:first-child:not([data-unread="0"]):after {
+
+/*=== Aside main page (categories) */
+.aside_feed .tree-folder-title > .title:not([data-unread="0"]):after {
position: absolute;
- top: 3px; right: 3px;
+ right: 3px;
padding: 1px 5px;
- background: transparent;
color: #fff;
text-shadow: 0 1px rgba(255,255,255,0.08);
}
+.aside_feed .btn-important {
+ border: none;
+}
/*=== Aside main page (feeds) */
-.categories .feeds .item.active {
- background: linear-gradient(180deg, #222 0%, #171717 100%) #171717;
- background: -webkit-linear-gradient(top, #222 0%, #171717 100%);
- border-radius: 4px;
- margin: 0px 8px;
- box-shadow: 0px 1px #171717, 0px 1px rgba(255, 255, 255, 0.08) inset, 0 2px 2px #111;
-}
-.categories .feeds .item.active .feed {
- color: #fff;
-}
-.categories .feeds .item.empty .feed {
+.feed.item.empty,
+.feed.item.empty > a {
color: #e67e22;
}
-.categories .feeds .item.empty.active {
- background: #e67e22;
-}
-.categories .feeds .item.empty.active .feed {
- color: #fff;
-}
-.categories .feeds .item.error .feed {
+.feed.item.error,
+.feed.item.error > a {
color: #BD362F;
}
-.categories .feeds .item .feed {
- margin: 0;
- width: 165px;
- line-height: 3em;
- font-size: 0.8em;
- text-align: left;
- text-decoration: none;
- color:#ccc;
-}
-.categories .feeds .feed:not([data-unread="0"]) {
- font-weight: bold;
-}
-.categories .feeds .dropdown-menu:after {
+.aside_feed .tree-folder-items .dropdown-menu:after {
left: 2px;
}
-.categories .feeds .item .dropdown-target:target ~ .dropdown-toggle > .icon,
-.categories .feeds .item:hover .dropdown-toggle > .icon,
-.categories .feeds .item.active .dropdown-toggle > .icon {
- background-color: transparent;
+.aside_feed .tree-folder-items .item .dropdown-target:target ~ .dropdown-toggle > .icon,
+.aside_feed .tree-folder-items .item:hover .dropdown-toggle > .icon,
+.aside_feed .tree-folder-items .item.active .dropdown-toggle > .icon {
border-radius: 3px;
vertical-align: middle;
}
@@ -968,63 +956,50 @@ opacity: 1;
/*=== GLOBAL VIEW */
/*================*/
-#stream.global{
- background:#222;
+#stream.global {
+ background: #222;
padding: 24px 0;
box-shadow: 0 1px #fff, 0 -2px 2px #171717 inset, 0 2px 2px #171717 inset;
}
-#stream.global .box-category {
- background: #fff;
- border-radius: 4px 4px 0 0;
- text-align: left;
- box-shadow: 0 0 4px #171717;
- overflow:hidden;
-}
-#stream.global .category {
- margin: 0;
-}
-#stream.global .btn {
- width: auto;
- height: 2em;
- margin: 0;
- padding: 0 10px;
+
+.box.category .box-title {
background: linear-gradient(0deg, #EDE7DE 0%, #fff 100%) #171717;
background: -webkit-linear-gradient(bottom, #EDE7DE 0%, #fff 100%);
- border: none;
box-shadow: 0px -1px #fff inset,0 -2px #ccc inset;
border-radius: none;
line-height: 2em;
font-size: 1.2rem;
- color:#888;
text-shadow:0 1px #ccc;
}
-#stream.global .btn:not([data-unread="0"]) {
+.box.category .box-title .title {
+ font-weight: normal;
+ text-decoration: none;
+ text-align: left;
+ color: #888;
+}
+.box.category:not([data-unread="0"]) .box-title {
+}
+.box.category:not([data-unread="0"]) .box-title:active {
+}
+.box.category:not([data-unread="0"]) .box-title .title {
color: #222;
font-weight: bold;
}
-#stream.global .btn:first-child:not([data-unread="0"]):after {
- top: 0;
- right: 5px;
+.box.category .title:not([data-unread="0"]):after {
+ position: absolute;
+ top: 5px; right: 10px;
border: 0;
background: none;
- color: #222;
font-weight: bold;
- box-shadow: none;
- text-shadow: none;
}
-#stream.global .box-category .feeds {
- max-height: 250px;
- color:#222;
- background:#EDE7DE;
-}
-#stream.global .box-category .feeds .item {
+.box.category .item.feed {
padding: 2px 10px;
- font-size: 0.9rem;
- overflow:hidden;
+ font-size: 0.8rem;
}
-#stream.global .box-category .feed {
- color:#222;
+.box.category .item.feed:not(.empty):not(.error) .item-title {
+ color: #222;
}
+
/*=== PANEL */
/*===========*/
#panel {
@@ -1135,12 +1110,10 @@ opacity: 1;
}
.aside .toggle_aside,
#panel .close {
- position: absolute;
display: block;
- top: 0; right: 0;
- width: 30px;
- height: 30px;
- line-height: 30px;
+ width: 100%;
+ height: 40px;
+ line-height: 40px;
text-align: center;
background: #171717;
box-shadow: 0 1px rgba(255,255,255,0.08);
@@ -1151,6 +1124,13 @@ opacity: 1;
margin: 20px 0 0;
}
+ .aside.aside_feed {
+ padding: 0;
+ }
+ .aside.aside_feed .tree {
+ position: static;
+ }
+
.nav_menu .btn {
margin: 5px 10px;
}
diff --git a/p/themes/base-theme/base.css b/p/themes/base-theme/base.css
index 3f6ae956d..871a632d8 100644
--- a/p/themes/base-theme/base.css
+++ b/p/themes/base-theme/base.css
@@ -353,6 +353,42 @@ a.btn {
visibility: visible;
}
+/*=== Tree */
+.tree {
+ margin: 10px 0;
+}
+.tree-folder-title {
+ position: relative;
+ padding: 0 10px;
+ line-height: 2.5rem;
+ font-size: 1rem;
+}
+.tree-folder-title .title {
+ background: inherit;
+}
+.tree-folder-title .title:hover {
+ text-decoration: none;
+}
+.tree-folder.active .tree-folder-title {
+ font-weight: bold;
+}
+.tree-folder.active .tree-folder-title .title {
+}
+.tree-folder-items {
+}
+.tree-folder-items > .item {
+ padding: 0 10px;
+ line-height: 2.5rem;
+ font-size: 0.8rem;
+}
+.tree-folder-items > .item.active {
+}
+.tree-folder-items > .item > a {
+ text-decoration: none;
+}
+.tree-folder-items > .item.active > a {
+}
+
/*=== STRUCTURE */
/*===============*/
/*=== Header */
@@ -386,64 +422,49 @@ a.btn {
}
.aside {
}
-.aside.aside_flux {
- padding: 10px 0 50px;
-}
-
-/*=== Aside main page (categories) */
-.categories {
+.aside.aside_feed {
+ padding: 10px 0;
text-align: center;
}
-.category {
- width: 235px;
- margin: 10px auto;
- text-align: left;
-}
-.category .btn:first-child {
- position: relative;
- width: 213px;
-}
-.category.stick .btn:first-child {
- width: 176px;
+.aside.aside_feed .tree {
+ position: sticky;
+ top: 0;
+ margin: 10px 0 50px;
}
-.category .btn:first-child:not([data-unread="0"]):after {
+
+/*=== Aside main page (categories) */
+.aside_feed .tree-folder-title > .title:not([data-unread="0"]):after {
position: absolute;
- top: 3px; right: 3px;
- padding: 1px 5px;
+ right: 0;
+ margin: 10px 0;
+ padding: 0 10px;
+ font-size: 0.9rem;
+ line-height: 1.5rem;
}
/*=== Aside main page (feeds) */
-.categories .feeds .item.active {
-}
-.categories .feeds .item.empty.active {
+.feed.item.empty.active {
}
-.categories .feeds .item.error.active {
+.feed.item.error.active {
}
-.categories .feeds .item.empty .feed {
+.feed.item.empty,
+.feed.item.empty > a {
}
-.categories .feeds .item.error .feed {
-}
-.categories .feeds .item.active .feed,
-.categories .feeds .item.empty.active .feed,
-.categories .feeds .item.error.active .feed {
-}
-.categories .feeds .item .feed {
- margin: 0;
- width: 165px;
- line-height: 3em;
- font-size: 0.8em;
- text-align: left;
- text-decoration: none;
+.feed.item.error,
+.feed.item.error > a {
}
-.categories .feeds .feed:not([data-unread="0"]) {
- font-weight: bold;
+.feed.item.empty.active,
+.feed.item.error.active,
+.feed.item.empty.active > a,
+.feed.item.error.active > a {
}
-.categories .feeds .dropdown-menu:after {
+.aside_feed .tree-folder-items .dropdown-menu:after {
left: 2px;
}
-.categories .feeds .item .dropdown-target:target ~ .dropdown-toggle > .icon,
-.categories .feeds .item:hover .dropdown-toggle > .icon,
-.categories .feeds .item.active .dropdown-toggle > .icon {
+.aside_feed .tree-folder-items .item .dropdown-target:target ~ .dropdown-toggle > .icon,
+.aside_feed .tree-folder-items .item:hover .dropdown-toggle > .icon,
+.aside_feed .tree-folder-items .item.active .dropdown-toggle > .icon {
+ border-radius: 3px;
vertical-align: middle;
}
@@ -645,33 +666,30 @@ a.btn {
/*=== GLOBAL VIEW */
/*================*/
-#stream.global .box-category {
+.box.category .box-title .title {
+ font-weight: normal;
+ text-decoration: none;
text-align: left;
}
-#stream.global .category {
- margin: 0;
+.box.category:not([data-unread="0"]) .box-title {
}
-#stream.global .btn {
- width: auto;
- height: 2em;
- margin: 0;
- padding: 0 10px;
- line-height: 2em;
- font-size: 1.2rem;
+.box.category:not([data-unread="0"]) .box-title:active {
}
-#stream.global .btn:not([data-unread="0"]) {
+.box.category:not([data-unread="0"]) .box-title .title {
font-weight: bold;
}
-#stream.global .btn:first-child:not([data-unread="0"]):after {
- top: 0; right: 5px;
+.box.category .title:not([data-unread="0"]):after {
+ position: absolute;
+ top: 5px; right: 10px;
+ border: 0;
+ background: none;
font-weight: bold;
+ box-shadow: none;
+ text-shadow: none;
}
-#stream.global .box-category .feeds {
- max-height: 250px;
-}
-#stream.global .box-category .feeds .item {
+.box.category .item.feed {
padding: 2px 10px;
- font-size: 0.9rem;
+ font-size: 0.8rem;
}
/*=== DIVERS */
@@ -750,15 +768,20 @@ a.btn {
}
.aside .toggle_aside,
#panel .close {
- position: absolute;
display: block;
- top: 0; right: 0;
- width: 30px;
- height: 30px;
- line-height: 30px;
+ width: 100%;
+ height: 50px;
+ line-height: 50px;
text-align: center;
}
+ .aside.aside_feed {
+ padding: 0;
+ }
+ .aside.aside_feed .tree {
+ position: static;
+ }
+
.nav_menu .btn {
margin: 5px 10px;
}
diff --git a/p/themes/base-theme/template.css b/p/themes/base-theme/template.css
index 1a96f1e2f..a79d539d8 100644
--- a/p/themes/base-theme/template.css
+++ b/p/themes/base-theme/template.css
@@ -179,6 +179,7 @@ a.btn {
.dropdown {
position: relative;
display: inline-block;
+ vertical-align: middle;
}
.dropdown-target {
display: none;
@@ -289,10 +290,14 @@ a.btn {
vertical-align: top;
}
.box .box-title {
+ position: relative;
font-size: 1.2rem;
font-weight: bold;
text-align: center;
}
+.box .box-title a {
+ display: block;
+}
.box .box-title form {
margin: 0;
}
@@ -325,6 +330,39 @@ a.btn {
cursor: grab;
}
+/*=== Tree */
+.tree {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ text-align: left;
+}
+.tree-folder-items {
+ padding: 0;
+ list-style: none;
+}
+.tree-folder-title {
+ display: block;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+.tree-folder-title .title {
+ vertical-align: middle;
+}
+.tree-folder-items > .item {
+ display: block;
+ white-space: nowrap;
+}
+.tree-folder-items > .item > a {
+ display: inline-block;
+ vertical-align: middle;
+ width: calc(100% - 32px);
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
/*=== STRUCTURE */
/*===============*/
/*=== Header */
@@ -366,57 +404,21 @@ a.btn {
width: 250px;
vertical-align: top;
}
-.aside.aside_flux {
- background: #fff;
-}
-
-/*=== Aside main page (categories) */
-.categories {
- list-style: none;
- margin: 0;
-}
-.state_unread li:not(.active)[data-unread="0"] {
- display: none;
-}
-.category {
- display: block;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
-}
-.category .btn:not([data-unread="0"]):after {
- content: attr(data-unread);
-}
/*=== Aside main page (feeds) */
-.categories .feeds {
- width: 100%;
- list-style: none;
-}
-.categories .feeds:not(.active) {
+.aside_feed .tree-folder-items:not(.active) {
display: none;
}
-.categories .feeds .feed {
- display: inline-block;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- vertical-align: middle;
-}
-.categories .feeds .feed:not([data-unread="0"]):before {
- content: "(" attr(data-unread) ") ";
-}
-.categories .feeds .dropdown-menu {
+.aside_feed .tree-folder-items .dropdown-menu {
left: 0;
}
-.categories .feeds .item .dropdown-toggle > .icon {
+.aside_feed .tree-folder-items .item .dropdown-toggle > .icon {
visibility: hidden;
cursor: pointer;
- vertical-align: top;
}
-.categories .feeds .item .dropdown-target:target ~ .dropdown-toggle > .icon,
-.categories .feeds .item:hover .dropdown-toggle > .icon,
-.categories .feeds .item.active .dropdown-toggle > .icon {
+.aside_feed .tree-folder-items .item .dropdown-target:target ~ .dropdown-toggle > .icon,
+.aside_feed .tree-folder-items .item:hover .dropdown-toggle > .icon,
+.aside_feed .tree-folder-items .item.active .dropdown-toggle > .icon {
visibility: visible;
}
@@ -603,32 +605,13 @@ br + br + br {
/*=== GLOBAL VIEW */
/*================*/
-/*=== Category boxes */
-
-/* TODO <delete> */
-#stream.global .box-category {
- display: inline-block;
- width: 19em;
- max-width: 95%;
- margin: 20px 10px;
- border: 1px solid #ccc;
- vertical-align: top;
-}
-#stream.global .category {
- width: 100%;
-}
-#stream.global .btn {
- display: block;
-}
-#stream.global .box-category .feeds {
- display: block;
- overflow: auto;
+#stream.global {
+ text-align: center;
}
-#stream.global .box-category .feed {
- width: 19em;
- max-width: 90%;
+
+#stream.global .box {
+ text-align: left;
}
-/* TODO </delete */
/*=== Panel */
#overlay {
@@ -685,39 +668,45 @@ br + br + br {
/*=== DIVERS */
/*===========*/
+.category .title:not([data-unread="0"]):after {
+ content: attr(data-unread);
+}
+.feed .item-title:not([data-unread="0"]):before {
+ content: "(" attr(data-unread) ") ";
+}
+.feed .item-title:not([data-unread="0"]) {
+ font-weight: bold;
+}
+
+.state_unread .category:not(.active)[data-unread="0"],
+.state_unread .feed:not(.active)[data-unread="0"] {
+ display: none;
+}
+
.nav-login,
.nav_menu .search,
+.aside .toggle_aside,
.nav_menu .toggle_aside {
display: none;
}
-.aside .toggle_aside {
- position: absolute;
- right: 0;
- display: none;
- width: 30px;
- height: 30px;
- line-height: 30px;
- text-align: center;
-}
/*=== MOBILE */
/*===========*/
@media(max-width: 840px) {
.header,
.aside .btn-important,
- .aside .feeds .dropdown,
.flux_header .item.website span,
.item.date, .day .date,
.dropdown-menu > .no-mobile,
.no-mobile {
display: none;
}
+ .aside .toggle_aside,
.nav-login {
display: block;
}
.nav_menu .toggle_aside,
- .aside .toggle_aside,
.nav_menu .search,
#panel .close img {
display: inline-block;
@@ -735,9 +724,6 @@ br + br + br {
width: 90%;
overflow: auto;
}
- .aside .categories {
- margin: 10px 0 75px;
- }
.flux_header .item.website {
width: 40px;
@@ -759,10 +745,6 @@ br + br + br {
width: 100%;
}
- #stream.global .box-category {
- margin: 10px 0;
- }
-
#panel {
top: 0; bottom: 0;
left: 0; right: 0;