Browse Source

Merge pull request #214 from Alkarex/updateUnreads

Mise à jour automatique des nombres d'articles non lus et favoris
Alexandre Alapetite 12 years ago
parent
commit
aff58561e9

+ 17 - 30
app/layout/aside_flux.phtml

@@ -30,20 +30,16 @@
 		<?php } ?>
 
 		<li>
-			<div class="all">
-				<a class="btn<?php echo $this->get_c == 'all' ? ' active' : ''; ?>" href="<?php echo _url ('index', 'index'); ?>">
-					<i class="icon i_all"></i>
-					<?php echo Translate::t ('all_feeds', $this->nb_total); ?>
-					<?php if ($this->nb_not_read > 0) { ?>
-					<span class="notRead"><?php echo $this->nb_not_read > 1 ? Translate::t ('not_reads', $this->nb_not_read) : Translate::t ('not_read', $this->nb_not_read); ?></span>
-					<?php } ?>
+			<div class="category all">
+				<a data-unread="<?php echo $this->nb_not_read; ?>" class="btn<?php echo $this->get_c == 'all' ? ' active' : ''; ?>" href="<?php echo _url ('index', 'index'); ?>">
+					<i class="icon i_all"></i><?php echo Translate::t ('all_feeds', $this->nb_total); ?>
 				</a>
 			</div>
 		</li>
 
 		<li>
-			<div class="favorites">
-				<a class="btn<?php echo $this->get_c == 'favoris' ? ' active' : ''; ?>" href="<?php echo _url ('index', 'index', 'get', 'favoris'); ?>">
+			<div class="category favorites">
+				<a data-unread="0" class="btn<?php echo $this->get_c == 'favoris' ? ' active' : ''; ?>" href="<?php echo _url ('index', 'index', 'get', 'favoris'); ?>">
 					<i class="icon i_bookmark"></i>
 					<?php echo Translate::t ('favorite_feeds', $this->nb_favorites); ?>
 				</a>
@@ -51,36 +47,27 @@
 		</li>
 
 		<?php foreach ($this->cat_aside as $cat) { ?>
-		<?php $feeds = $cat->feeds (); $catNotRead = $cat->nbNotRead (); ?>
+		<?php $feeds = $cat->feeds (); ?>
 		<?php if (!empty ($feeds)) { ?>
 		<li>
 			<?php $c_active = false; if ($this->get_c == $cat->id ()) { $c_active = true; } ?>
 			<div class="category<?php echo $c_active ? ' active' : ''; ?>">
-				<a class="btn<?php echo $c_active ? ' active' : ''; ?>" href="<?php echo _url ('index', 'index', 'get', 'c_' . $cat->id ()); ?>">
-					<?php echo $cat->name (); ?>
-					<?php if ($catNotRead > 0) { ?>
-					<span class="notRead" title="<?php echo $catNotRead > 1 ? Translate::t ('not_reads', $catNotRead) : Translate::t ('not_read', $catNotRead); ?>"><?php echo $catNotRead ; ?></span>
-					<?php } ?>
-				</a>
+				<a data-unread="<?php echo $cat->nbNotRead (); ?>" class="btn<?php echo $c_active ? ' active' : ''; ?>" href="<?php echo _url ('index', 'index', 'get', 'c_' . $cat->id ()); ?>"><?php echo $cat->name (); ?></a>
 			</div>
 
 			<ul class="feeds<?php echo $c_active ? ' active' : ''; ?>">
-				<?php foreach ($feeds as $feed) { ?>
-				<?php $nbEntries = $feed->nbEntries (); ?>
-				<?php $f_active = false; if ($this->get_f == $feed->id ()) { $f_active = true; } ?>
-				<li class="item<?php echo $f_active ? ' active' : ''; ?><?php echo $feed->inError () ? ' error' : ''; ?><?php echo $nbEntries == 0 ? ' empty' : ''; ?>">
+				<?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' : ''; ?>">
 					<div class="dropdown">
 						<div class="dropdown-target"></div>
-						<a class="dropdown-toggle" data-fid="<?php echo $feed->id (); ?>" data-fweb="<?php echo $feed->website (); ?>"><i class="icon i_configure"></i></a>
+						<a class="dropdown-toggle" data-fweb="<?php echo $feed->website (); ?>"><i class="icon i_configure"></i></a>
 <?php /* feed_config_template */ ?>
 					</div>
-					<?php $not_read = $feed->nbNotRead (); ?>
-					<img class="favicon" src="<?php echo $feed->favicon (); ?>" alt="" />
-					<?php echo $not_read > 0 ? '<b>' : ''; ?>
-					<a class="feed" href="<?php echo _url ('index', 'index', 'get', 'f_' . $feed->id ()); ?>">
-						<?php echo ($not_read > 0 ? '(' . $not_read . ') ' : ''), $feed->name(); ?>
-					</a>
-					<?php echo $not_read > 0 ? '</b>' : ''; ?>
+					<img class="favicon" src="<?php echo $feed->favicon (); ?>" />
+					<a class="feed" data-unread="<?php echo $feed->nbNotRead (); ?>" data-priority="<?php echo $feed->priority (); ?>" href="<?php echo _url ('index', 'index', 'get', 'f_' . $feed_id); ?>"><?php echo $feed->name(); ?></a>
 				</li>
 				<?php } ?>
 			</ul>
@@ -94,13 +81,13 @@
 <script id="feed_config_template" type="text/html">
 	<ul class="dropdown-menu">
 		<li class="dropdown-close"><a href="#close">&nbsp;</a></li>
-		<li class="item"><a href="<?php echo _url ('index', 'index', 'get', 'f_' . '!!!!!!'); ?>"><?php echo Translate::t ('filter'); ?></a></li>
+		<li class="item"><a href="<?php echo _url ('index', 'index', 'get', 'f_!!!!!!'); ?>"><?php echo Translate::t ('filter'); ?></a></li>
 		<li class="item"><a target="_blank" href="http://example.net/"><?php echo Translate::t ('see_website'); ?></a></li>
 		<?php if (!login_is_conf ($this->conf) || is_logged ()) { ?>
 		<li class="separator"></li>
 		<li class="item"><a href="<?php echo _url ('configure', 'feed', 'id', '!!!!!!'); ?>"><?php echo Translate::t ('administration'); ?></a></li>
 		<li class="item"><a href="<?php echo _url ('feed', 'actualize', 'id', '!!!!!!'); ?>"><?php echo Translate::t ('actualize'); ?></a></li>
-		<li class="item"><a href="<?php echo _url ('entry', 'read', 'is_read', 1, 'get', 'f_' . '!!!!!!'); ?>"><?php echo Translate::t ('mark_read'); ?></a></li>
+		<li class="item"><a href="<?php echo _url ('entry', 'read', 'is_read', 1, 'get', 'f_!!!!!!'); ?>"><?php echo Translate::t ('mark_read'); ?></a></li>
 		<?php } ?>
 	</ul>
 </script>

+ 49 - 4
public/scripts/main.js

@@ -71,6 +71,11 @@ function toggleContent (new_active, old_active) {
 	}
 }
 
+function _incLabel(p, inc) {
+	var i = (parseInt(p.replace(/\D/g, '')) || 0) + inc;
+	return i > 0 ? ' (' + i + ')' : '';
+}
+
 function mark_read (active, only_not_read) {
 	if (active[0] === undefined || (
 		only_not_read === true && !active.hasClass("not_read"))) {
@@ -91,11 +96,41 @@ function mark_read (active, only_not_read) {
 
 		active.find ("a.read").attr ("href", res.url);
 
+		var inc = 0;
 		if (active.hasClass ("not_read")) {
 			active.removeClass ("not_read");
+			inc--;
 		} else if (only_not_read !== true || active.hasClass("not_read")) {
 			active.addClass ("not_read");
+			inc++;
+		}
+
+		//Update unread: feed	//Alex
+		var feed_url = active.find(".website>a").attr("href"),
+			feed_id = feed_url.substr(feed_url.lastIndexOf('f_')),
+			elem = $('#' + feed_id + ' .feed').get(0),
+			attr_unread = elem ? elem.getAttributeNode('data-unread') : null,
+			feed_priority = elem ? parseInt(elem.getAttribute('data-priority')) : 0;
+		if (attr_unread)
+			attr_unread.value = Math.max(0, parseInt(attr_unread.value) + inc);
+
+		//Update unread: category
+		elem = $('#' + feed_id).parent().prevAll('.category').children(':first').get(0);
+		attr_unread = elem ? elem.getAttributeNode('data-unread') : null;
+		if (attr_unread)
+			attr_unread.value = Math.max(0, parseInt(attr_unread.value) + inc);
+
+		if (feed_priority > 0) {	//Update unread: all
+			elem = $('#aside_flux .all').children(':first').get(0);
+			attr_unread = elem ? elem.getAttributeNode('data-unread') : null;
+			if (attr_unread)
+				attr_unread.value = Math.max(0, parseInt(attr_unread.value) + inc);
 		}
+
+		//Update unread: title
+		document.title = document.title.replace(/((?: \(\d+\))?)( - .*?)((?: \(\d+\))?)$/, function(m, p1, p2, p3) {
+			return _incLabel(p1, inc) + p2 + _incLabel(p3, feed_priority > 0 ? inc : 0);
+		});
 	});
 }
 
@@ -117,11 +152,20 @@ function mark_favorite (active) {
 		res = jQuery.parseJSON(data);
 
 		active.find ("a.bookmark").attr ("href", res.url);
+		var inc = 0;
 		if (active.hasClass ("favorite")) {
 			active.removeClass ("favorite");
+			inc--;
 		} else {
 			active.addClass ("favorite");
+			inc++;
 		}
+
+		var favourites = $('.favorites>a').contents().last().get(0);
+		if (favourites && favourites.textContent)
+			favourites.textContent = favourites.textContent.replace(/((?: \(\d+\))?\s*)$/, function(m, p1) {
+				return _incLabel(p1, inc);
+			});
 	});
 }
 
@@ -235,9 +279,10 @@ function init_column_categories () {
 		return;
 	}
 
-	$(".category").addClass ("stick");
-	$(".categories .category .btn:first-child").width ("160px");
-	$(".category").append ("<a class=\"btn dropdown-toggle\" href=\"#\"><i class=\"icon i_down\"></i></a>");
+	//TODO: toggle class in PHP and remove the CSS changes done in JavaScript
+	$(".category:not(.all):not(.favorites) .btn:first-child").width ("160px");
+	$(".category:not(.all):not(.favorites)").addClass("stick").
+		append ("<a class=\"btn dropdown-toggle\" href=\"#\"><i class=\"icon i_down\"></i></a>");
 
 	$(".category + .feeds").not(".active").hide();
 	$(".category.active a.dropdown-toggle i").toggleClass ("i_up");
@@ -391,7 +436,7 @@ function init_nav_entries() {
 function init_templates() {
 	$('#aside_flux').on('click', '.dropdown-toggle', function () {
 		if ($(this).nextAll('.dropdown-menu').length === 0) {
-			var feed_id = $(this).data('fid'),
+			var feed_id = $(this).closest('li').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);

+ 21 - 18
public/themes/default/freshrss.css

@@ -93,9 +93,7 @@
 	text-align: center;
 	list-style: none;
 }
-	.categories .all,
-	.categories .favorites,
-	.categories .category {
+	.category {
 		display: block;
 		padding: 5px 0;
 		width: 220px;
@@ -105,12 +103,23 @@
 		white-space: nowrap;
 		text-overflow: ellipsis;
 	}
-		.categories .all .btn,
-		.categories .favorites .btn,
-		.categories .category .btn:first-child {
+		.category .btn:first-child {
 			width: 195px;
 			position: relative;
 		}
+		.category .btn:first-child:not([data-unread="0"]):after {
+			content: attr(data-unread);
+			position: absolute;
+			top: 3px; right: 3px;
+			padding: 1px 5px;
+			background: #ccc;
+			color: #fff;
+			font-size: 90%;
+			border: 1px solid #bbb;
+			border-radius: 5px;
+			box-shadow: 1px 3px 3px #aaa inset;
+			text-shadow: 0 0 1px #aaa;
+		}
 	.categories .feeds {
 		width: 100%;
 		margin: 0;
@@ -146,6 +155,12 @@
 			white-space: nowrap;
 			text-overflow: ellipsis;
 		}
+		.feed:not([data-unread="0"]) {
+			font-weight:bold;
+		}
+		.feed:not([data-unread="0"]):before {
+			content: "(" attr(data-unread) ") ";
+		}
 		.categories .feeds .dropdown .dropdown-menu {
 			left: 0;
 		}
@@ -163,18 +178,6 @@
 				background-color: #fff;
 				border-radius: 3px;
 			}
-	.categories .notRead {
-		position: absolute;
-		top: 3px; right: 3px;
-		padding: 1px 5px;
-		background: #ccc;
-		color: #fff;
-		font-size: 90%;
-		border: 1px solid #bbb;
-		border-radius: 5px;
-		box-shadow: 1px 3px 3px #aaa inset;
-		text-shadow: 0 0 1px #aaa;
-	}
 
 .post {
 	padding: 10px 50px;

+ 19 - 16
public/themes/flat-design/freshrss.css

@@ -92,9 +92,7 @@ body {
 	text-align: center;
 	list-style: none;
 }
-	.categories .all,
-	.categories .favorites,
-	.categories .category {
+	.category {
 		display: block;
 		padding: 5px 0;
 		width: 220px;
@@ -104,12 +102,21 @@ body {
 		white-space: nowrap;
 		text-overflow: ellipsis;
 	}
-		.categories .all .btn,
-		.categories .favorites .btn,
-		.categories .category .btn:first-child {
+		.category .btn:first-child {
 			width: 195px;
 			position: relative;
 		}
+		.category .btn:first-child:not([data-unread="0"]):after {
+			content: attr(data-unread);
+			position: absolute;
+			top: 5px; right: 0px;
+			padding: 0 5px;
+			color: #fff;
+			font-size: 90%;
+			background: #3498DB;
+			border-left: 3px solid #2980B9;
+			border-radius: 5px 0 0 5px;
+		}
 	.categories .feeds {
 		width: 220px;
 		margin: 0 auto;
@@ -138,6 +145,12 @@ body {
 			white-space: nowrap;
 			text-overflow: ellipsis;
 		}
+		.feed:not([data-unread="0"]) {
+			font-weight:bold;
+		}
+		.feed:not([data-unread="0"]):before {
+			content: "(" attr(data-unread) ") ";
+		}
 		.categories .feeds .dropdown .dropdown-menu {
 			left: 0;
 		}
@@ -155,16 +168,6 @@ body {
 				background-color: #95a5a6;
 				border-radius: 3px;
 			}
-	.categories .notRead {
-		position: absolute;
-		top: 5px; right: 0px;
-		padding: 0 5px;
-		color: #fff;
-		font-size: 90%;
-		background: #3498DB;
-		border-left: 3px solid #2980B9;
-		border-radius: 5px 0 0 5px;
-	}
 	.categories .btn:hover .notRead,
 	.categories .btn.active .notRead {
 		background: #2980B9;