Просмотр исходного кода

Merge branch 'dev' of github.com:marienfressinaud/FreshRSS into dev

Marien Fressinaud 12 лет назад
Родитель
Сommit
e763cd407a

+ 35 - 15
app/Controllers/configureController.php

@@ -140,21 +140,6 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
 	public function displayAction () {
 		if (Minz_Request::isPost()) {
 			$this->view->conf->_language(Minz_Request::param('language', 'en'));
-			$this->view->conf->_posts_per_page(Minz_Request::param('posts_per_page', 10));
-			$this->view->conf->_view_mode(Minz_Request::param('view_mode', 'normal'));
-			$this->view->conf->_default_view (Minz_Request::param('default_view', 'a'));
-			$this->view->conf->_auto_load_more(Minz_Request::param('auto_load_more', false));
-			$this->view->conf->_display_posts(Minz_Request::param('display_posts', false));
-			$this->view->conf->_onread_jump_next(Minz_Request::param('onread_jump_next', false));
-			$this->view->conf->_lazyload (Minz_Request::param('lazyload', false));
-			$this->view->conf->_sticky_post (Minz_Request::param('sticky_post', false));
-			$this->view->conf->_sort_order(Minz_Request::param('sort_order', 'DESC'));
-			$this->view->conf->_mark_when (array(
-				'article' => Minz_Request::param('mark_open_article', false),
-				'site' => Minz_Request::param('mark_open_site', false),
-				'scroll' => Minz_Request::param('mark_scroll', false),
-				'reception' => Minz_Request::param('mark_upon_reception', false),
-			));
 			$themeId = Minz_Request::param('theme', '');
 			if ($themeId == '') {
 				$themeId = FreshRSS_Themes::defaultTheme;
@@ -187,6 +172,41 @@ class FreshRSS_configure_Controller extends Minz_ActionController {
 
 		$this->view->themes = FreshRSS_Themes::get();
 
+		Minz_View::prependTitle (Minz_Translate::t ('display_configuration') . ' · ');
+	}
+
+	public function readingAction () {
+		if (Minz_Request::isPost()) {
+			$this->view->conf->_posts_per_page(Minz_Request::param('posts_per_page', 10));
+			$this->view->conf->_view_mode(Minz_Request::param('view_mode', 'normal'));
+			$this->view->conf->_default_view (Minz_Request::param('default_view', 'a'));
+			$this->view->conf->_auto_load_more(Minz_Request::param('auto_load_more', false));
+			$this->view->conf->_display_posts(Minz_Request::param('display_posts', false));
+			$this->view->conf->_onread_jump_next(Minz_Request::param('onread_jump_next', false));
+			$this->view->conf->_lazyload (Minz_Request::param('lazyload', false));
+			$this->view->conf->_sticky_post (Minz_Request::param('sticky_post', false));
+			$this->view->conf->_sort_order(Minz_Request::param('sort_order', 'DESC'));
+			$this->view->conf->_mark_when (array(
+				'article' => Minz_Request::param('mark_open_article', false),
+				'site' => Minz_Request::param('mark_open_site', false),
+				'scroll' => Minz_Request::param('mark_scroll', false),
+				'reception' => Minz_Request::param('mark_upon_reception', false),
+			));
+			$this->view->conf->save();
+
+			Minz_Session::_param ('language', $this->view->conf->language);
+			Minz_Translate::reset ();
+			invalidateHttpCache();
+
+			$notif = array (
+				'type' => 'good',
+				'content' => Minz_Translate::t ('configuration_updated')
+			);
+			Minz_Session::_param ('notification', $notif);
+
+			Minz_Request::forward (array ('c' => 'configure', 'a' => 'reading'), true);
+		}
+
 		Minz_View::prependTitle (Minz_Translate::t ('reading_configuration') . ' · ');
 	}
 

+ 2 - 2
app/Controllers/importExportController.php

@@ -370,7 +370,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 			$this->view->type = 'starred';
 			$unread_fav = $this->entryDAO->countUnreadReadFavorites();
 			$this->view->entries = $this->entryDAO->listWhere(
-				's', '', 'all', 'ASC',
+				's', '', FreshRSS_Entry::STATE_ALL, 'ASC',
 				$unread_fav['all']
 			);
 		} elseif ($type == 'feed' && !is_null($feed)) {
@@ -379,7 +379,7 @@ class FreshRSS_importExport_Controller extends Minz_ActionController {
 			);
 			$this->view->type = 'feed/' . $feed->id();
 			$this->view->entries = $this->entryDAO->listWhere(
-				'f', $feed->id(), 'all', 'ASC',
+				'f', $feed->id(), FreshRSS_Entry::STATE_ALL, 'ASC',
 				$this->view->conf->posts_per_page
 			);
 			$this->view->feed = $feed;

+ 7 - 6
app/Controllers/indexController.php

@@ -85,18 +85,19 @@ class FreshRSS_index_Controller extends Minz_ActionController {
 		$state_param = Minz_Request::param ('state', null);
 		$filter = Minz_Request::param ('search', '');
 		if (!empty($filter)) {
-			$state = 'all';	//Search always in read and unread articles
+			$state = FreshRSS_Entry::STATE_ALL;	//Search always in read and unread articles
 		}
 		$this->view->order = $order = Minz_Request::param ('order', $this->view->conf->sort_order);
 		$nb = Minz_Request::param ('nb', $this->view->conf->posts_per_page);
 		$first = Minz_Request::param ('next', '');
 
-		if ($state === 'not_read') {	//Any unread article in this category at all?
+		if ($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':
@@ -111,7 +112,7 @@ class FreshRSS_index_Controller extends Minz_ActionController {
 					break;
 			}
 			if (!$hasUnread && ($state_param === null)) {
-				$this->view->state = $state = 'all';
+				$this->view->state = $state = FreshRSS_Entry::STATE_ALL;
 			}
 		}
 
@@ -128,10 +129,10 @@ class FreshRSS_index_Controller extends Minz_ActionController {
 
 			// Si on a récupéré aucun article "non lus"
 			// on essaye de récupérer tous les articles
-			if ($state === 'not_read' && empty($entries) && ($state_param === null)) {
+			if ($state === FreshRSS_Entry::STATE_NOT_READ && empty($entries) && ($state_param === null)) {
 				Minz_Log::record ('Conflicting information about nbNotRead!', Minz_Log::DEBUG);
-				$this->view->state = 'all';
-				$entries = $entryDAO->listWhere($getType, $getId, 'all', $order, $nb, $first, $filter, $date_min, true, $keepHistoryDefault);
+				$this->view->state = FreshRSS_Entry::STATE_ALL;
+				$entries = $entryDAO->listWhere($getType, $getId, $this->view->state, $order, $nb, $first, $filter, $date_min, true, $keepHistoryDefault);
 			}
 
 			if (count($entries) <= $nb) {

+ 3 - 2
app/Models/Configuration.php

@@ -13,7 +13,7 @@ class FreshRSS_Configuration {
 		'apiPasswordHash' => '',	//CRYPT_BLOWFISH
 		'posts_per_page' => 20,
 		'view_mode' => 'normal',
-		'default_view' => 'not_read',
+		'default_view' => FreshRSS_Entry::STATE_NOT_READ,
 		'auto_load_more' => true,
 		'display_posts' => false,
 		'onread_jump_next' => true,
@@ -39,6 +39,7 @@ class FreshRSS_Configuration {
 			'collapse_entry' => 'c',
 			'load_more' => 'm',
 			'auto_share' => 's',
+			'focus_search' => 'a',
 		),
 		'topline_read' => true,
 		'topline_favorite' => true,
@@ -131,7 +132,7 @@ class FreshRSS_Configuration {
 		}
 	}
 	public function _default_view ($value) {
-		$this->data['default_view'] = $value === 'all' ? 'all' : 'not_read';
+		$this->data['default_view'] = $value === FreshRSS_Entry::STATE_ALL ? FreshRSS_Entry::STATE_ALL : FreshRSS_Entry::STATE_NOT_READ;
 	}
 	public function _display_posts ($value) {
 		$this->data['display_posts'] = ((bool)$value) && $value !== 'no';

+ 5 - 0
app/Models/Entry.php

@@ -1,6 +1,11 @@
 <?php
 
 class FreshRSS_Entry extends Minz_Model {
+	const STATE_ALL = 0;
+	const STATE_READ = 1;
+	const STATE_NOT_READ = 2;
+	const STATE_FAVORITE = 4;
+	const STATE_NOT_FAVORITE = 8;
 
 	private $id = 0;
 	private $guid;

+ 22 - 16
app/Models/EntryDAO.php

@@ -406,7 +406,10 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
 		return isset ($entries[0]) ? $entries[0] : null;
 	}
 
-	private function sqlListWhere($type = 'a', $id = '', $state = 'all', $order = 'DESC', $limit = 1, $firstId = '', $filter = '', $date_min = 0, $showOlderUnreadsorFavorites = false, $keepHistoryDefault = 0) {
+	private function sqlListWhere($type = 'a', $id = '', $state = FreshRSS_Entry::STATE_ALL, $order = 'DESC', $limit = 1, $firstId = '', $filter = '', $date_min = 0, $showOlderUnreadsorFavorites = false, $keepHistoryDefault = 0) {
+		if (!$state) {
+			$state = FreshRSS_Entry::STATE_ALL;
+		}
 		$where = '';
 		$joinFeed = false;
 		$values = array();
@@ -415,7 +418,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
 				$where .= 'f.priority > 0 ';
 				$joinFeed = true;
 				break;
-			case 's':
+			case 's':	//Deprecated: use $state instead
 				$where .= 'e1.is_favorite = 1 ';
 				break;
 			case 'c':
@@ -433,21 +436,24 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
 			default:
 				throw new FreshRSS_EntriesGetter_Exception ('Bad type in Entry->listByType: [' . $type . ']!');
 		}
-		switch ($state) {
-			case 'all':
-				break;
-			case 'not_read':
+
+		if ($state & FreshRSS_Entry::STATE_NOT_READ) {
+			if (!($state & FreshRSS_Entry::STATE_READ)) {
 				$where .= 'AND e1.is_read = 0 ';
-				break;
-			case 'read':
-				$where .= 'AND e1.is_read = 1 ';
-				break;
-			case 'favorite':
+			}
+		}
+		elseif ($state & FreshRSS_Entry::STATE_READ) {
+			$where .= 'AND e1.is_read = 1 ';
+		}
+		if ($state & FreshRSS_Entry::STATE_FAVORITE) {
+			if (!($state & FreshRSS_Entry::STATE_NOT_FAVORITE)) {
 				$where .= 'AND e1.is_favorite = 1 ';
-				break;
-			default:
-				throw new FreshRSS_EntriesGetter_Exception ('Bad state in Entry->listByType: [' . $state . ']!');
+			}
+		}
+		elseif ($state & FreshRSS_Entry::STATE_NOT_FAVORITE) {
+			$where .= 'AND e1.is_favorite = 0 ';
 		}
+
 		switch ($order) {
 			case 'DESC':
 			case 'ASC':
@@ -528,7 +534,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
 			. ($limit > 0 ? ' LIMIT ' . $limit : ''));	//TODO: See http://explainextended.com/2009/10/23/mysql-order-by-limit-performance-late-row-lookups/
 	}
 
-	public function listWhere($type = 'a', $id = '', $state = 'all', $order = 'DESC', $limit = 1, $firstId = '', $filter = '', $date_min = 0, $showOlderUnreadsorFavorites = false, $keepHistoryDefault = 0) {
+	public function listWhere($type = 'a', $id = '', $state = FreshRSS_Entry::STATE_ALL, $order = 'DESC', $limit = 1, $firstId = '', $filter = '', $date_min = 0, $showOlderUnreadsorFavorites = false, $keepHistoryDefault = 0) {
 		list($values, $sql) = $this->sqlListWhere($type, $id, $state, $order, $limit, $firstId, $filter, $date_min, $showOlderUnreadsorFavorites, $keepHistoryDefault);
 
 		$sql = 'SELECT e.id, e.guid, e.title, e.author, UNCOMPRESS(e.content_bin) AS content, e.link, e.date, e.is_read, e.is_favorite, e.id_feed, e.tags '
@@ -544,7 +550,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
 		return self::daoToEntry ($stm->fetchAll (PDO::FETCH_ASSOC));
 	}
 
-	public function listIdsWhere($type = 'a', $id = '', $state = 'all', $order = 'DESC', $limit = 1, $firstId = '', $filter = '', $date_min = 0, $showOlderUnreadsorFavorites = false, $keepHistoryDefault = 0) {	//For API
+	public function listIdsWhere($type = 'a', $id = '', $state = FreshRSS_Entry::STATE_ALL, $order = 'DESC', $limit = 1, $firstId = '', $filter = '', $date_min = 0, $showOlderUnreadsorFavorites = false, $keepHistoryDefault = 0) {	//For API
 		list($values, $sql) = $this->sqlListWhere($type, $id, $state, $order, $limit, $firstId, $filter, $date_min, $showOlderUnreadsorFavorites, $keepHistoryDefault);
 
 		$stm = $this->bd->prepare($sql);

+ 1 - 0
app/Models/Themes.php

@@ -85,6 +85,7 @@ class FreshRSS_Themes extends Minz_Model {
 			'non-starred' => '☆',
 			'prev' => '⏪',
 			'read' => '☑',
+			'rss' => '☄',
 			'unread' => '☐',
 			'refresh' => '🔃',	//↻
 			'search' => '🔍',

+ 6 - 4
app/i18n/en.php

@@ -27,7 +27,7 @@ return array (
 	'subscription_management'	=> 'Subscriptions management',
 	'main_stream'			=> 'Main stream',
 	'all_feeds'			=> 'All feeds',
-	'favorite_feeds'		=> 'Favourites (%d)',
+	'favorite_feeds'		=> 'Favourites (%s)',
 	'not_read'			=> '%d unread',
 	'not_reads'			=> '%d unread',
 
@@ -51,7 +51,8 @@ return array (
 	'show_all_articles'		=> 'Show all articles',
 	'show_not_reads'		=> 'Show only unread',
 	'show_read'			=> 'Show only read',
-	'show_favorite'			=> 'Show favorites',
+	'show_favorite'			=> 'Show only favorites',
+	'show_not_favorite'		=> 'Show all but favorites',
 	'older_first'			=> 'Oldest first',
 	'newer_first'			=> 'Newer first',
 
@@ -79,7 +80,6 @@ return array (
 	'sharing_management'		=> 'Sharing options management',
 	'bad_opml_file'			=> 'Your OPML file is invalid',
 	'shortcuts_updated'		=> 'Shortcuts have been updated',
-	'shortcuts_management'		=> 'Shortcuts management',
 	'shortcuts_navigation'		=> 'Navigation',
 	'shortcuts_navigation_help'	=> 'With the "Shift" modifier, navigation shortcuts apply on feeds.<br/>With the "Alt" modifier, navigation shortcuts apply on categories.',
 	'shortcuts_article_action'	=> 'Article actions',
@@ -137,6 +137,7 @@ return array (
 	'collapse_article'		=> 'Collapse',
 	'auto_share'			=> 'Share',
 	'auto_share_help'		=> 'If there is only one sharing mode, it is used. Else modes are accessible by their number.',
+	'focus_search'			=> 'Access search box',
 
 	'file_to_import'		=> 'File to import<br />(OPML, Json or Zip)',
 	'import'			=> 'Import',
@@ -212,6 +213,7 @@ return array (
 	'purge_completed'		=> 'Purge completed (%d articles deleted)',
 	'archiving_configuration_help'	=> 'More options are available in the individual stream settings',
 	'reading_configuration'		=> 'Reading',
+	'display_configuration'		=> 'Display',
 	'articles_per_page'		=> 'Number of articles per page',
 	'default_view'			=> 'Default view',
 	'sort_order'			=> 'Sort order',
@@ -219,7 +221,7 @@ return array (
 	'display_articles_unfolded'	=> 'Show articles unfolded by default',
 	'after_onread'			=> 'After “mark all as read”,',
 	'jump_next'			=> 'jump to next unread sibling (feed or category)',
-	'reading_icons'			=> 'Reading icons',
+	'article_icons'			=> 'Article icons',
 	'top_line'			=> 'Top line',
 	'bottom_line'			=> 'Bottom line',
 	'img_with_lazyload'		=> 'Use "lazy load" mode to load pictures',

+ 5 - 3
app/i18n/fr.php

@@ -27,7 +27,7 @@ return array (
 	'subscription_management'	=> 'Gestion des abonnements',
 	'main_stream'			=> 'Flux principal',
 	'all_feeds'			=> 'Tous les flux',
-	'favorite_feeds'		=> 'Favoris (%d)',
+	'favorite_feeds'		=> 'Favoris (%s)',
 	'not_read'			=> '%d non lu',
 	'not_reads'			=> '%d non lus',
 
@@ -52,6 +52,7 @@ return array (
 	'show_not_reads'		=> 'Afficher les non lus',
 	'show_read'			=> 'Afficher les lus',
 	'show_favorite'			=> 'Afficher les favoris',
+	'show_not_favorite'		=> 'Afficher tout sauf les favoris',
 	'older_first'			=> 'Plus anciens en premier',
 	'newer_first'			=> 'Plus récents en premier',
 
@@ -79,7 +80,6 @@ return array (
 	'sharing_management'		=> 'Gestion des options de partage',
 	'bad_opml_file'			=> 'Votre fichier OPML n’est pas valide',
 	'shortcuts_updated'		=> 'Les raccourcis ont été mis à jour',
-	'shortcuts_management'		=> 'Gestion des raccourcis',
 	'shortcuts_navigation'		=> 'Navigation',
 	'shortcuts_navigation_help'	=> 'Avec le modificateur "Shift", les raccourcis de navigation s’appliquent aux flux.<br/>Avec le modificateur "Alt", les raccourcis de navigation s’appliquent aux catégories.',
 	'shortcuts_article_action'	=> 'Actions associées à l’article courant',
@@ -137,6 +137,7 @@ return array (
 	'collapse_article'		=> 'Refermer',
 	'auto_share'			=> 'Partager',
 	'auto_share_help'		=> 'Si il n’y a qu’un mode de partage, celui ci est utilisé automatiquement. Sinon ils sont accessibles par leur numéro.',
+	'focus_search'			=> 'Accéder à la recherche',
 
 	'file_to_import'		=> 'Fichier à importer<br />(OPML, Json ou Zip)',
 	'import'			=> 'Importer',
@@ -212,6 +213,7 @@ return array (
 	'purge_completed'		=> 'Purge effectuée (%d articles supprimés)',
 	'archiving_configuration_help'	=> 'D’autres options sont disponibles dans la configuration individuelle des flux',
 	'reading_configuration'		=> 'Lecture',
+	'display_configuration'		=> 'Affichage',
 	'articles_per_page'		=> 'Nombre d’articles par page',
 	'default_view'			=> 'Vue par défaut',
 	'sort_order'			=> 'Ordre de tri',
@@ -219,7 +221,7 @@ return array (
 	'display_articles_unfolded'	=> 'Afficher les articles dépliés par défaut',
 	'after_onread'			=> 'Après “marquer tout comme lu”,',
 	'jump_next'			=> 'sauter au prochain voisin non lu (flux ou catégorie)',
-	'reading_icons'			=> 'Icônes de lecture',
+	'article_icons'			=> 'Icônes d’article',
 	'top_line'			=> 'Ligne du haut',
 	'bottom_line'			=> 'Ligne du bas',
 	'img_with_lazyload'		=> 'Utiliser le mode “chargement différé” pour les images',

+ 4 - 1
app/layout/aside_configure.phtml

@@ -1,7 +1,10 @@
 <ul class="nav nav-list aside">
 	<li class="nav-header"><?php echo Minz_Translate::t ('configuration'); ?></li>
 	<li class="item<?php echo Minz_Request::actionName () == 'display' ? ' active' : ''; ?>">
-		<a href="<?php echo _url ('configure', 'display'); ?>"><?php echo Minz_Translate::t ('reading_configuration'); ?></a>
+		<a href="<?php echo _url ('configure', 'display'); ?>"><?php echo Minz_Translate::t ('display_configuration'); ?></a>
+	</li>
+	<li class="item<?php echo Minz_Request::actionName () == 'reading' ? ' active' : ''; ?>">
+		<a href="<?php echo _url ('configure', 'reading'); ?>"><?php echo Minz_Translate::t ('reading_configuration'); ?></a>
 	</li>
 	<li class="item<?php echo Minz_Request::actionName () == 'archiving' ? ' active' : ''; ?>">
 		<a href="<?php echo _url ('configure', 'archiving'); ?>"><?php echo Minz_Translate::t ('archiving_configuration'); ?></a>

+ 2 - 1
app/layout/header.phtml

@@ -67,7 +67,8 @@ if (Minz_Configuration::canLogIn()) {
 			<ul class="dropdown-menu">
 				<li class="dropdown-close"><a href="#close">❌</a></li>
 				<li class="dropdown-header"><?php echo Minz_Translate::t ('configuration'); ?></li>
-				<li class="item"><a href="<?php echo _url ('configure', 'display'); ?>"><?php echo Minz_Translate::t ('reading_configuration'); ?></a></li>
+				<li class="item"><a href="<?php echo _url ('configure', 'display'); ?>"><?php echo Minz_Translate::t ('display_configuration'); ?></a></li>
+				<li class="item"><a href="<?php echo _url ('configure', 'reading'); ?>"><?php echo Minz_Translate::t ('reading_configuration'); ?></a></li>
 				<li class="item"><a href="<?php echo _url ('configure', 'archiving'); ?>"><?php echo Minz_Translate::t ('archiving_configuration'); ?></a></li>
 				<li class="item"><a href="<?php echo _url ('configure', 'sharing'); ?>"><?php echo Minz_Translate::t ('sharing'); ?></a></li>
 				<li class="item"><a href="<?php echo _url ('configure', 'shortcut'); ?>"><?php echo Minz_Translate::t ('shortcuts'); ?></a></li>

+ 101 - 71
app/layout/nav_menu.phtml

@@ -6,11 +6,81 @@
 	<a class="btn toggle_aside" href="#aside_flux"><?php echo FreshRSS_Themes::icon('category'); ?></a>
 	<?php } ?>
 
-	<?php if ($this->loginOk || Minz_Configuration::allowAnonymousRefresh()) { ?>
-	<a id="actualize" class="btn" href="<?php echo _url ('feed', 'actualize'); ?>"><?php echo FreshRSS_Themes::icon('refresh'); ?></a>
-	<?php } ?>
-
 	<?php if ($this->loginOk) { ?>
+	<?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 = '';
+		}
+	?>
+	<div class="stick">
+		<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 Minz_Translate::t ('show_read'); ?>">
+			<?php echo FreshRSS_Themes::icon('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 Minz_Translate::t ('show_not_reads'); ?>">
+			<?php echo FreshRSS_Themes::icon('unread'); ?>
+		</a>
+		<?php
+			if ($this->state & FreshRSS_Entry::STATE_FAVORITE) {
+				$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 Minz_Translate::t ('show_favorite'); ?>">
+			<?php echo FreshRSS_Themes::icon('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 = '';
+			}
+		?>
+		<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 Minz_Translate::t ('show_not_favorite'); ?>">
+			<?php echo FreshRSS_Themes::icon('non-starred'); ?>
+		</a>
+	</div>
 	<?php
 		$get = false;
 		$string_mark = Minz_Translate::t ('mark_all_read');
@@ -86,7 +156,7 @@
 			<ul class="dropdown-menu">
 				<li class="dropdown-close"><a href="#close">❌</a></li>
 
-				<li class="item"><a href="<?php echo $markReadUrl; ?>"><?php echo $string_mark; ?></a></li> 
+				<li class="item"><a href="<?php echo $markReadUrl; ?>"><?php echo $string_mark; ?></a></li>
 				<li class="separator"></li>
 <?php
 	$today = $this->today;
@@ -129,72 +199,6 @@
 				</a>
 			</li>
 			<?php } ?>
-
-			<li class="separator"></li>
-
-			<?php
-				$url_state = $this->url;
-				$url_state['params']['state'] = 'all';
-			?>
-			<li class="item" role="checkbox" aria-checked="<?php echo ($this->state === 'all') ? 'true' :'false'; ?>">
-				<a class="print_all" href="<?php echo Minz_Url::display ($url_state); ?>">
-					<?php echo Minz_Translate::t ('show_all_articles'); ?>
-				</a>
-			</li>
-			<?php
-				$url_state['params']['state'] = 'not_read';
-			?>
-			<li class="item" role="checkbox" aria-checked="<?php echo ($this->state === 'not_read') ? 'true' :'false'; ?>">
-				<a class="print_non_read" href="<?php echo Minz_Url::display ($url_state); ?>">
-					<?php echo Minz_Translate::t ('show_not_reads'); ?>
-				</a>
-			</li>
-			<?php
-				$url_state['params']['state'] = 'read';
-			?>
-			<li class="item" role="checkbox" aria-checked="<?php echo ($this->state === 'read') ? 'true' :'false'; ?>">
-				<a class="print_read" href="<?php echo Minz_Url::display ($url_state); ?>">
-					<?php echo Minz_Translate::t ('show_read'); ?>
-				</a>
-			</li>
-			<?php
-				$url_state['params']['state'] = 'favorite';
-			?>
-			<li class="item" role="checkbox" aria-checked="<?php echo ($this->state === 'favorite') ? 'true' :'false'; ?>">
-				<a class="print_favorite" href="<?php echo Minz_Url::display ($url_state); ?>">
-					<?php echo Minz_Translate::t ('show_favorite'); ?>
-				</a>
-			</li>
-
-			<li class="separator"></li>
-
-			<li class="item">
-				<?php
-					$url_order = $this->url;
-					if ($this->order === 'DESC') {
-						$url_order['params']['order'] = 'ASC';
-				?>
-				<a href="<?php echo Minz_Url::display ($url_order); ?>">
-					<?php echo Minz_Translate::t ('older_first'); ?>
-				</a>
-				<?php
-					} else {
-						$url_order['params']['order'] = 'DESC';
-				?>
-				<a href="<?php echo Minz_Url::display ($url_order); ?>">
-					<?php echo Minz_Translate::t ('newer_first'); ?>
-				</a>
-				<?php } ?>
-			</li>
-
-			<li class="separator"></li>
-
-			<li class="item">
-				<?php $url_output['params']['output'] = 'rss'; ?>
-				<a class="view_rss" target="_blank" href="<?php echo Minz_Url::display ($url_output); ?>">
-					<?php echo Minz_Translate::t ('rss_view'); ?>
-				</a>
-			</li>
 		</ul>
 	</div>
 
@@ -219,4 +223,30 @@
 			<?php } ?>
 		</form>
 	</div>
+	
+	<?php
+		if ($this->order === 'DESC') {
+			$order = 'ASC';
+			$icon = 'up';
+			$title = 'older_first';
+		} else {
+			$order = 'DESC';
+			$icon = 'down';
+			$title = 'newer_first';
+		}
+		$url_order = $this->url;
+		$url_order['params']['order'] = $order;
+	?>
+	<a class="btn" href="<?php echo Minz_Url::display ($url_order); ?>" title="<?php echo Minz_Translate::t ($title); ?>">
+		<?php echo FreshRSS_Themes::icon($icon); ?>
+	</a>
+
+	<?php $url_output['params']['output'] = 'rss'; ?>
+	<a class="btn view_rss" target="_blank" href="<?php echo Minz_Url::display ($url_output); ?>" title="<?php echo Minz_Translate::t ('rss_view'); ?>">
+		<?php echo FreshRSS_Themes::icon('rss'); ?>
+	</a>
+	
+	<?php if ($this->loginOk || Minz_Configuration::allowAnonymousRefresh()) { ?>
+	<a id="actualize" class="btn" href="<?php echo _url ('feed', 'actualize'); ?>"><?php echo FreshRSS_Themes::icon('refresh'); ?></a>
+	<?php } ?>
 </div>

+ 2 - 126
app/views/configure/display.phtml

@@ -4,7 +4,7 @@
 	<a href="<?php echo _url ('index', 'index'); ?>"><?php echo Minz_Translate::t ('back_to_rss_feeds'); ?></a>
 
 	<form method="post" action="<?php echo _url ('configure', 'display'); ?>">
-		<legend><?php echo Minz_Translate::t ('theme'); ?></legend>
+		<legend><?php echo Minz_Translate::t ('display_configuration'); ?></legend>
 
 		<div class="form-group">
 			<label class="group-name" for="language"><?php echo Minz_Translate::t ('language'); ?></label>
@@ -35,132 +35,8 @@
 			</div>
 		</div>
 
-		<div class="form-group form-actions">
-			<div class="group-controls">
-				<button type="submit" class="btn btn-important"><?php echo Minz_Translate::t ('save'); ?></button>
-				<button type="reset" class="btn"><?php echo Minz_Translate::t ('cancel'); ?></button>
-			</div>
-		</div>
-
-		<legend><?php echo Minz_Translate::t ('reading_configuration'); ?></legend>
-
-		<div class="form-group">
-			<label class="group-name" for="posts_per_page"><?php echo Minz_Translate::t ('articles_per_page'); ?></label>
-			<div class="group-controls">
-				<input type="number" id="posts_per_page" name="posts_per_page" value="<?php echo $this->conf->posts_per_page; ?>" />
-			</div>
-		</div>
-
-		<div class="form-group">
-			<label class="group-name" for="sort_order"><?php echo Minz_Translate::t ('sort_order'); ?></label>
-			<div class="group-controls">
-				<select name="sort_order" id="sort_order">
-					<option value="DESC"<?php echo $this->conf->sort_order === 'DESC' ? ' selected="selected"' : ''; ?>><?php echo Minz_Translate::t ('newer_first'); ?></option>
-					<option value="ASC"<?php echo $this->conf->sort_order === 'ASC' ? ' selected="selected"' : ''; ?>><?php echo Minz_Translate::t ('older_first'); ?></option>
-				</select>
-			</div>
-		</div>
-
-		<div class="form-group">
-			<label class="group-name" for="view_mode"><?php echo Minz_Translate::t ('default_view'); ?></label>
-			<div class="group-controls">
-				<select name="view_mode" id="view_mode">
-					<option value="normal"<?php echo $this->conf->view_mode === 'normal' ? ' selected="selected"' : ''; ?>><?php echo Minz_Translate::t ('normal_view'); ?></option>
-					<option value="reader"<?php echo $this->conf->view_mode === 'reader' ? ' selected="selected"' : ''; ?>><?php echo Minz_Translate::t ('reader_view'); ?></option>
-					<option value="global"<?php echo $this->conf->view_mode === 'global' ? ' selected="selected"' : ''; ?>><?php echo Minz_Translate::t ('global_view'); ?></option>
-				</select>
-				<label class="radio" for="radio_all">
-					<input type="radio" name="default_view" id="radio_all" value="all"<?php echo $this->conf->default_view === 'all' ? ' checked="checked"' : ''; ?> />
-					<?php echo Minz_Translate::t ('show_all_articles'); ?>
-				</label>
-				<label class="radio" for="radio_not_read">
-					<input type="radio" name="default_view" id="radio_not_read" value="not_read"<?php echo $this->conf->default_view === 'not_read' ? ' checked="checked"' : ''; ?> />
-					<?php echo Minz_Translate::t ('show_not_reads'); ?>
-				</label>
-			</div>
-		</div>
-
-		<div class="form-group">
-			<div class="group-controls">
-				<label class="checkbox" for="auto_load_more">
-					<input type="checkbox" name="auto_load_more" id="auto_load_more" value="1"<?php echo $this->conf->auto_load_more ? ' checked="checked"' : ''; ?> />
-					<?php echo Minz_Translate::t ('auto_load_more'); ?>
-					<noscript> — <strong><?php echo Minz_Translate::t ('javascript_should_be_activated'); ?></strong></noscript>
-				</label>
-			</div>
-		</div>
-
-		<div class="form-group">
-			<div class="group-controls">
-				<label class="checkbox" for="display_posts">
-					<input type="checkbox" name="display_posts" id="display_posts" value="1"<?php echo $this->conf->display_posts ? ' checked="checked"' : ''; ?> />
-					<?php echo Minz_Translate::t ('display_articles_unfolded'); ?>
-					<noscript> — <strong><?php echo Minz_Translate::t ('javascript_should_be_activated'); ?></strong></noscript>
-				</label>
-			</div>
-		</div>
-
-		<div class="form-group">
-			<div class="group-controls">
-				<label class="checkbox" for="lazyload">
-					<input type="checkbox" name="lazyload" id="lazyload" value="1"<?php echo $this->conf->lazyload ? ' checked="checked"' : ''; ?> />
-					<?php echo Minz_Translate::t ('img_with_lazyload'); ?>
-					<noscript> — <strong><?php echo Minz_Translate::t ('javascript_should_be_activated'); ?></strong></noscript>
-				</label>
-			</div>
-		</div>
-
-		<div class="form-group">
-			<div class="group-controls">
-				<label class="checkbox" for="sticky_post">
-					<input type="checkbox" name="sticky_post" id="sticky_post" value="1"<?php echo $this->conf->sticky_post ? ' checked="checked"' : ''; ?> />
-					<?php echo Minz_Translate::t ('sticky_post'); ?>
-					<noscript> — <strong><?php echo Minz_Translate::t ('javascript_should_be_activated'); ?></strong></noscript>
-				</label>
-			</div>
-		</div>
-
-		<div class="form-group">
-			<label class="group-name"><?php echo Minz_Translate::t ('auto_read_when'); ?></label>
-			<div class="group-controls">
-				<label class="checkbox" for="check_open_article">
-					<input type="checkbox" name="mark_open_article" id="check_open_article" value="1"<?php echo $this->conf->mark_when['article'] ? ' checked="checked"' : ''; ?> />
-					<?php echo Minz_Translate::t ('article_selected'); ?>
-				</label>
-				<label class="checkbox" for="check_open_site">
-					<input type="checkbox" name="mark_open_site" id="check_open_site" value="1"<?php echo $this->conf->mark_when['site'] ? ' checked="checked"' : ''; ?> />
-					<?php echo Minz_Translate::t ('article_open_on_website'); ?>
-				</label>
-				<label class="checkbox" for="check_scroll">
-					<input type="checkbox" name="mark_scroll" id="check_scroll" value="1"<?php echo $this->conf->mark_when['scroll'] ? ' checked="checked"' : ''; ?> />
-					<?php echo Minz_Translate::t ('scroll'); ?>
-				</label>
-				<label class="checkbox" for="check_reception">
-					<input type="checkbox" name="mark_upon_reception" id="check_reception" value="1"<?php echo $this->conf->mark_when['reception'] ? ' checked="checked"' : ''; ?> />
-					<?php echo Minz_Translate::t ('upon_reception'); ?>
-				</label>
-			</div>
-		</div>
-
-		<div class="form-group">
-			<label class="group-name"><?php echo Minz_Translate::t ('after_onread'); ?></label>
-			<div class="group-controls">
-				<label class="checkbox" for="onread_jump_next">
-					<input type="checkbox" name="onread_jump_next" id="onread_jump_next" value="1"<?php echo $this->conf->onread_jump_next ? ' checked="checked"' : ''; ?> />
-					<?php echo Minz_Translate::t ('jump_next'); ?>
-				</label>
-			</div>
-		</div>
-
-		<div class="form-group form-actions">
-			<div class="group-controls">
-				<button type="submit" class="btn btn-important"><?php echo Minz_Translate::t ('save'); ?></button>
-				<button type="reset" class="btn"><?php echo Minz_Translate::t ('cancel'); ?></button>
-			</div>
-		</div>
-
-		<legend><?php echo Minz_Translate::t ('reading_icons'); ?></legend>
 		<div class="form-group">
+			<label class="group-name" for="theme"><?php echo Minz_Translate::t ('article_icons'); ?></label>
 			<table>
 				<thead>
 					<tr>

+ 125 - 0
app/views/configure/reading.phtml

@@ -0,0 +1,125 @@
+<?php $this->partial ('aside_configure'); ?>
+
+<div class="post">
+	<a href="<?php echo _url ('index', 'index'); ?>"><?php echo Minz_Translate::t ('back_to_rss_feeds'); ?></a>
+
+	<form method="post" action="<?php echo _url ('configure', 'reading'); ?>">
+		<legend><?php echo Minz_Translate::t ('reading_configuration'); ?></legend>
+
+		<div class="form-group">
+			<label class="group-name" for="posts_per_page"><?php echo Minz_Translate::t ('articles_per_page'); ?></label>
+			<div class="group-controls">
+				<input type="number" id="posts_per_page" name="posts_per_page" value="<?php echo $this->conf->posts_per_page; ?>" />
+			</div>
+		</div>
+
+		<div class="form-group">
+			<label class="group-name" for="sort_order"><?php echo Minz_Translate::t ('sort_order'); ?></label>
+			<div class="group-controls">
+				<select name="sort_order" id="sort_order">
+					<option value="DESC"<?php echo $this->conf->sort_order === 'DESC' ? ' selected="selected"' : ''; ?>><?php echo Minz_Translate::t ('newer_first'); ?></option>
+					<option value="ASC"<?php echo $this->conf->sort_order === 'ASC' ? ' selected="selected"' : ''; ?>><?php echo Minz_Translate::t ('older_first'); ?></option>
+				</select>
+			</div>
+		</div>
+
+		<div class="form-group">
+			<label class="group-name" for="view_mode"><?php echo Minz_Translate::t ('default_view'); ?></label>
+			<div class="group-controls">
+				<select name="view_mode" id="view_mode">
+					<option value="normal"<?php echo $this->conf->view_mode === 'normal' ? ' selected="selected"' : ''; ?>><?php echo Minz_Translate::t ('normal_view'); ?></option>
+					<option value="reader"<?php echo $this->conf->view_mode === 'reader' ? ' selected="selected"' : ''; ?>><?php echo Minz_Translate::t ('reader_view'); ?></option>
+					<option value="global"<?php echo $this->conf->view_mode === 'global' ? ' selected="selected"' : ''; ?>><?php echo Minz_Translate::t ('global_view'); ?></option>
+				</select>
+				<label class="radio" for="radio_all">
+					<input type="radio" name="default_view" id="radio_all" value="<?php echo FreshRSS_Entry::STATE_ALL; ?>"<?php echo $this->conf->default_view === FreshRSS_Entry::STATE_ALL ? ' checked="checked"' : ''; ?> />
+					<?php echo Minz_Translate::t ('show_all_articles'); ?>
+				</label>
+				<label class="radio" for="radio_not_read">
+					<input type="radio" name="default_view" id="radio_not_read" value="<?php echo FreshRSS_Entry::STATE_NOT_READ; ?>"<?php echo $this->conf->default_view === FreshRSS_Entry::STATE_NOT_READ ? ' checked="checked"' : ''; ?> />
+					<?php echo Minz_Translate::t ('show_not_reads'); ?>
+				</label>
+			</div>
+		</div>
+
+		<div class="form-group">
+			<div class="group-controls">
+				<label class="checkbox" for="auto_load_more">
+					<input type="checkbox" name="auto_load_more" id="auto_load_more" value="1"<?php echo $this->conf->auto_load_more ? ' checked="checked"' : ''; ?> />
+					<?php echo Minz_Translate::t ('auto_load_more'); ?>
+					<noscript> — <strong><?php echo Minz_Translate::t ('javascript_should_be_activated'); ?></strong></noscript>
+				</label>
+			</div>
+		</div>
+
+		<div class="form-group">
+			<div class="group-controls">
+				<label class="checkbox" for="display_posts">
+					<input type="checkbox" name="display_posts" id="display_posts" value="1"<?php echo $this->conf->display_posts ? ' checked="checked"' : ''; ?> />
+					<?php echo Minz_Translate::t ('display_articles_unfolded'); ?>
+					<noscript> — <strong><?php echo Minz_Translate::t ('javascript_should_be_activated'); ?></strong></noscript>
+				</label>
+			</div>
+		</div>
+
+		<div class="form-group">
+			<div class="group-controls">
+				<label class="checkbox" for="lazyload">
+					<input type="checkbox" name="lazyload" id="lazyload" value="1"<?php echo $this->conf->lazyload ? ' checked="checked"' : ''; ?> />
+					<?php echo Minz_Translate::t ('img_with_lazyload'); ?>
+					<noscript> — <strong><?php echo Minz_Translate::t ('javascript_should_be_activated'); ?></strong></noscript>
+				</label>
+			</div>
+		</div>
+
+		<div class="form-group">
+			<div class="group-controls">
+				<label class="checkbox" for="sticky_post">
+					<input type="checkbox" name="sticky_post" id="sticky_post" value="1"<?php echo $this->conf->sticky_post ? ' checked="checked"' : ''; ?> />
+					<?php echo Minz_Translate::t ('sticky_post'); ?>
+					<noscript> — <strong><?php echo Minz_Translate::t ('javascript_should_be_activated'); ?></strong></noscript>
+				</label>
+			</div>
+		</div>
+
+		<div class="form-group">
+			<label class="group-name"><?php echo Minz_Translate::t ('auto_read_when'); ?></label>
+			<div class="group-controls">
+				<label class="checkbox" for="check_open_article">
+					<input type="checkbox" name="mark_open_article" id="check_open_article" value="1"<?php echo $this->conf->mark_when['article'] ? ' checked="checked"' : ''; ?> />
+					<?php echo Minz_Translate::t ('article_selected'); ?>
+				</label>
+				<label class="checkbox" for="check_open_site">
+					<input type="checkbox" name="mark_open_site" id="check_open_site" value="1"<?php echo $this->conf->mark_when['site'] ? ' checked="checked"' : ''; ?> />
+					<?php echo Minz_Translate::t ('article_open_on_website'); ?>
+				</label>
+				<label class="checkbox" for="check_scroll">
+					<input type="checkbox" name="mark_scroll" id="check_scroll" value="1"<?php echo $this->conf->mark_when['scroll'] ? ' checked="checked"' : ''; ?> />
+					<?php echo Minz_Translate::t ('scroll'); ?>
+				</label>
+				<label class="checkbox" for="check_reception">
+					<input type="checkbox" name="mark_upon_reception" id="check_reception" value="1"<?php echo $this->conf->mark_when['reception'] ? ' checked="checked"' : ''; ?> />
+					<?php echo Minz_Translate::t ('upon_reception'); ?>
+				</label>
+			</div>
+		</div>
+
+		<div class="form-group">
+			<label class="group-name"><?php echo Minz_Translate::t ('after_onread'); ?></label>
+			<div class="group-controls">
+				<label class="checkbox" for="onread_jump_next">
+					<input type="checkbox" name="onread_jump_next" id="onread_jump_next" value="1"<?php echo $this->conf->onread_jump_next ? ' checked="checked"' : ''; ?> />
+					<?php echo Minz_Translate::t ('jump_next'); ?>
+				</label>
+			</div>
+		</div>
+
+		<div class="form-group form-actions">
+			<div class="group-controls">
+				<button type="submit" class="btn btn-important"><?php echo Minz_Translate::t ('save'); ?></button>
+				<button type="reset" class="btn"><?php echo Minz_Translate::t ('cancel'); ?></button>
+			</div>
+		</div>
+
+	</form>
+</div>

+ 8 - 1
app/views/configure/shortcut.phtml

@@ -12,7 +12,7 @@
 	<?php $s = $this->conf->shortcuts; ?>
 
 	<form method="post" action="<?php echo _url ('configure', 'shortcut'); ?>">
-		<legend><?php echo Minz_Translate::t ('shortcuts_management'); ?></legend>
+		<legend><?php echo Minz_Translate::t ('shortcuts'); ?></legend>
 
 		<noscript><p class="alert alert-error"><?php echo Minz_Translate::t ('javascript_for_shortcuts'); ?></p></noscript>
 
@@ -96,6 +96,13 @@
 			</div>
 		</div>
 
+		<div class="form-group">
+			<label class="group-name" for="focus_search_shortcut"><?php echo Minz_Translate::t ('focus_search'); ?></label>
+			<div class="group-controls">
+				<input type="text" id="focus_search_shortcut" name="shortcuts[focus_search]" list="keys" value="<?php echo $s['focus_search']; ?>" />
+			</div>
+		</div>
+
 		<div class="form-group form-actions">
 			<div class="group-controls">
 				<button type="submit" class="btn btn-important"><?php echo Minz_Translate::t ('save'); ?></button>

+ 2 - 1
app/views/helpers/javascript_vars.phtml

@@ -25,7 +25,8 @@ echo ',shortcuts={',
 	'last_entry:"', $s['last_entry'], '",',
 	'collapse_entry:"', $s['collapse_entry'], '",',
 	'load_more:"', $s['load_more'], '",',
-	'auto_share:"', $s['auto_share'], '"',
+	'auto_share:"', $s['auto_share'], '",',
+	'focus_search:"', $s['focus_search'], '"',
 "},\n";
 
 if (Minz_Request::param ('output') === 'global') {

+ 1 - 1
app/views/helpers/view/normal_view.phtml

@@ -88,7 +88,7 @@ if (!empty($this->entries)) {
 
 		<div class="flux_content">
 			<div class="content">
-				<h1 class="title"><?php echo $item->title (); ?></h1>
+				<h1 class="title"><a target="_blank" href="<?php echo $item->link (); ?>"><?php echo $item->title (); ?></a></h1>
 				<?php
 					$author = $item->author ();
 					echo $author != '' ? '<div class="author">' . Minz_Translate::t ('by_author', $author) . '</div>' : '';

+ 4 - 4
p/api/greader.php

@@ -353,10 +353,10 @@ function streamContents($path, $include_target, $start_time, $count, $order, $ex
 
 	switch ($exclude_target) {
 		case 'user/-/state/com.google/read':
-			$state = 'not_read';
+			$state = FreshRSS_Entry::STATE_NOT_READ;
 			break;
 		default:
-			$state = 'all';
+			$state = FreshRSS_Entry::STATE_ALL;
 			break;
 	}
 
@@ -451,10 +451,10 @@ function streamContentsItemsIds($streamId, $start_time, $count, $order, $exclude
 
 	switch ($exclude_target) {
 		case 'user/-/state/com.google/read':
-			$state = 'not_read';
+			$state = FreshRSS_Entry::STATE_NOT_READ;
 			break;
 		default:
-			$state = 'all';
+			$state = FreshRSS_Entry::STATE_ALL;
 			break;
 	}
 

+ 1 - 1
p/i/install.php

@@ -913,7 +913,7 @@ function printStep3 () {
 		<div class="form-group">
 			<label class="group-name" for="user"><?php echo _t ('username'); ?></label>
 			<div class="group-controls">
-				<input type="text" id="user" name="user" maxlength="16" pattern="[0-9A-Za-z_]{1,16}" value="<?php echo isset ($_SESSION['bd_user']) ? $_SESSION['bd_user'] : ''; ?>" />
+				<input type="text" id="user" name="user" maxlength="16" pattern="[0-9A-Za-z_.-]{1,16}" value="<?php echo isset ($_SESSION['bd_user']) ? $_SESSION['bd_user'] : ''; ?>" />
 			</div>
 		</div>
 

Разница между файлами не показана из-за своего большого размера
+ 0 - 1
p/scripts/jquery.min.js


+ 17 - 11
p/scripts/main.js

@@ -207,14 +207,10 @@ function mark_favorite(active) {
 }
 
 function toggleContent(new_active, old_active) {
-	old_active.removeClass("active");
-
 	if (new_active.length === 0) {
 		return;
 	}
 
-	old_active.removeClass("current");
-
 	if (does_lazyload) {
 		new_active.find('img[data-original], iframe[data-original]').each(function () {
 			this.setAttribute('src', this.getAttribute('data-original'));
@@ -226,7 +222,10 @@ function toggleContent(new_active, old_active) {
 		if (isCollapsed) {
 			new_active.addClass("active");
 		}
+		old_active.removeClass("active current");
 		new_active.addClass("current");
+	} else {
+		new_active.toggleClass('active');
 	}
 
 	var box_to_move = "html,body",
@@ -236,14 +235,11 @@ function toggleContent(new_active, old_active) {
 		relative_move = true;
 	}
 
-	var new_pos = new_active.position().top,
-		old_scroll = $(box_to_move).scrollTop();
 	if (sticky_post) {
-		if (hide_posts) {
-
-			new_pos = new_active.position().top;
+		var new_pos = new_active.position().top - new_active.children('.flux_header').outerHeight(),
 			old_scroll = $(box_to_move).scrollTop();
 
+		if (hide_posts) {
 			if (relative_move) {
 				new_pos += old_scroll;
 			}
@@ -585,7 +581,7 @@ function init_shortcuts() {
 	});
 
 	shortcut.add(shortcuts.go_website, function () {
-		var url_website = $(".flux.current .link a").attr("href");
+		var url_website = $('.flux.current > .flux_header > .title > a').attr("href");
 
 		if (auto_mark_site) {
 			$(".flux.current").each(function () {
@@ -603,11 +599,17 @@ function init_shortcuts() {
 	}, {
 		'disable_in_input': true
 	});
+
+	shortcut.add(shortcuts.focus_search, function () {
+		focus_search();
+	}, {
+		'disable_in_input': true
+	});
 }
 
 function init_stream(divStream) {
 	divStream.on('click', '.flux_header,.flux_content', function (e) {	//flux_toggle
-		if ($(e.target).closest('.item.website, .item.link').length > 0) {
+		if ($(e.target).closest('.content, .item.website, .item.link').length > 0) {
 			return;
 		}
 		var old_active = $(".flux.current"),
@@ -795,6 +797,10 @@ function load_more_posts() {
 	});
 }
 
+function focus_search() {
+	$('#search').focus();
+}
+
 function init_load_more(box) {
 	box_load_more = box;
 

+ 7 - 3
p/themes/Dark/freshrss.css

@@ -88,6 +88,10 @@
 		.nav_menu .search {
 			display:none;
 		}
+		.nav_menu .btn[aria-checked="true"]{
+			border-color: #2f2f2f;
+			box-shadow: 0 0 10px 3px #2f2f2f inset;
+		}
 
 .favicon {
 	height: 16px;
@@ -290,7 +294,7 @@
 		.flux .item.title {
 			background: inherit;
 		}
-			.flux .item.title a {
+			.flux .title a {
 				color: #888;
 				outline: none;
 			}
@@ -506,10 +510,10 @@
 			font-style: italic;
 		}
 	.pagination:first-child .item {
-		border-bottom: 1px solid #aaa;
+		border-bottom: 1px solid #2f2f2f;
 	}
 	.pagination:last-child .item {
-		border-top: 1px solid #aaa;
+		border-top: 1px solid #2f2f2f;
 	}
 
 #nav_entries {

+ 0 - 6
p/themes/Dark/global.css

@@ -416,12 +416,6 @@ input, select, textarea {
 				background: #26303F;
 				color: #888;
 			}
-				.dropdown-menu > .item[aria-checked="true"] > a:before {
-					content: '✓ ';
-					font-weight: bold;
-					margin: 0 0 0 -1.2em;
-					padding: 0 0.2em 0 0;
-				}
 				.dropdown-menu > .item:hover > a {
 					color: #888;
 					text-decoration: none;

+ 5 - 1
p/themes/Flat/freshrss.css

@@ -87,6 +87,10 @@ body {
 		.nav_menu .search {
 			display:none;
 		}
+		.nav_menu .btn[aria-checked="true"]{
+			background-color: #2980B9;
+			border-bottom-color: #3498DB;
+		}
 
 .favicon {
 	height: 16px;
@@ -286,7 +290,7 @@ body {
 		.flux .item.title {
 			background: inherit;
 		}
-			.flux .item.title a {
+			.flux .title a {
 				color: #333;
 				outline: none;
 			}

+ 0 - 6
p/themes/Flat/global.css

@@ -412,12 +412,6 @@ input, select, textarea {
 				background: #2980b9;
 				color: #fff;
 			}
-				.dropdown-menu > .item[aria-checked="true"] > a:before {
-					content: '✓ ';
-					font-weight: bold;
-					margin: 0 0 0 -1.2em;
-					padding: 0 0.2em 0 0;
-				}
 				.dropdown-menu > .item:hover > a {
 					color: #fff;
 					text-decoration: none;

+ 6 - 0
p/themes/Flat/icons/rss.svg

@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
+<g fill-rule="nonzero" transform="translate(-561,-301.00012)" fill="#fff">
+<path style="enable-background:new;color:#000000;" d="m325.06,97.188c0,1.7872-0.89543,3.2361-2,3.2361s-2-1.4488-2-3.2361c0-1.7872,0.89543-3.2361,2-3.2361s2,1.4488,2,3.2361z" transform="matrix(1.0000007,0,0,0.61803426,241.93747,252.93479)"/>
+<path style="enable-background:new;color:#000000;" d="m563,303,0,1c0,0.55016,0.45347,1,1,1,4.9706,0,9,4.0294,9,9,0,0.55016,0.45347,1,1,1h1v-1c0-6.0751-4.9249-11-11-11h-1zm0,4,0,1c0,0.55016,0.45347,1,1,1,2.7614,0,5,2.2386,5,5,0,0.55016,0.45347,1,1,1h1v-1c0-3.866-3.134-7-7-7h-1z"/>
+</g>
+</svg>

+ 5 - 1
p/themes/Origine/freshrss.css

@@ -89,6 +89,10 @@
 		.nav_menu .search {
 			display:none;
 		}
+		.nav_menu .btn[aria-checked="true"]{
+			border-color: #aaa #ddd #ddd #aaa;
+			box-shadow: 0 0 10px 3px #ddd inset;
+		}
 
 .favicon {
 	height: 16px;
@@ -300,7 +304,7 @@
 		.flux .item.title {
 			background: inherit;
 		}
-			.flux .item.title a {
+			.flux .title a {
 				color: #000;
 				outline: none;
 			}

+ 0 - 6
p/themes/Origine/global.css

@@ -428,12 +428,6 @@ input, select, textarea {
 				background: #0062BE;
 				color: #fff;
 			}
-				.dropdown-menu > .item[aria-checked="true"] > a:before {
-					content: '✓ ';
-					font-weight: bold;
-					margin: 0 0 0 -1.2em;
-					padding: 0 0.2em 0 0;
-				}
 				.dropdown-menu > .item:hover > a {
 					color: #fff;
 					text-decoration: none;

+ 1 - 1
p/themes/icons/rss.svg

@@ -1,5 +1,5 @@
 <svg xmlns="http://www.w3.org/2000/svg" height="16" width="16">
-<g fill-rule="nonzero" transform="translate(-561,-301.00012)" fill="#FFF">
+<g fill-rule="nonzero" transform="translate(-561,-301.00012)" fill="#666">
 <path style="enable-background:new;color:#000000;" d="m325.06,97.188c0,1.7872-0.89543,3.2361-2,3.2361s-2-1.4488-2-3.2361c0-1.7872,0.89543-3.2361,2-3.2361s2,1.4488,2,3.2361z" transform="matrix(1.0000007,0,0,0.61803426,241.93747,252.93479)"/>
 <path style="enable-background:new;color:#000000;" d="m563,303,0,1c0,0.55016,0.45347,1,1,1,4.9706,0,9,4.0294,9,9,0,0.55016,0.45347,1,1,1h1v-1c0-6.0751-4.9249-11-11-11h-1zm0,4,0,1c0,0.55016,0.45347,1,1,1,2.7614,0,5,2.2386,5,5,0,0.55016,0.45347,1,1,1h1v-1c0-3.866-3.134-7-7-7h-1z"/>
 </g>

Некоторые файлы не были показаны из-за большого количества измененных файлов