From fcdaa7f3fd2b830ca566386a1711070407c7f191 Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: Mon, 3 Jun 2013 20:23:45 +0200 Subject: Add a navigation bar to skip through unread messages --- hyperkitty/static/css/hyperkitty-message.css | 33 +++++++++++++-- hyperkitty/static/js/hyperkitty.js | 21 ++++++---- hyperkitty/templates/thread.html | 62 ++++++++++++++-------------- hyperkitty/templates/threads/right_col.html | 18 +++++++- hyperkitty/views/thread.py | 10 +++++ 5 files changed, 101 insertions(+), 43 deletions(-) diff --git a/hyperkitty/static/css/hyperkitty-message.css b/hyperkitty/static/css/hyperkitty-message.css index 3e43e3d..3525aed 100644 --- a/hyperkitty/static/css/hyperkitty-message.css +++ b/hyperkitty/static/css/hyperkitty-message.css @@ -88,15 +88,22 @@ margin-right: 2em; } -.favorite a { +#thread-overview-info form.favorite { + margin-bottom: 0; +} +#thread-overview-info .favorite a { color: rgb(167, 169, 172); } -.favorite a.saved, -.favorite a.notsaved { +#thread-overview-info .favorite a.saved, +#thread-overview-info .favorite a.notsaved { /* Will be shown via Javascript */ display: none; } +#thread-overview-info .unread { + margin: 0 2px 0 2px; +} + /* Tags */ #tags { color: rgb(167, 169, 172); @@ -261,3 +268,23 @@ border-left: 2px solid rgb(55, 113, 200); padding-left: 0.2em; } + + +/* + * Navigation for unread messages + */ +#unreadnavbar { + position: fixed; + bottom: 0; + right: 0; + text-align: right; + padding-right: 2em; + display: none; +} +#unreadnavbar div { + width: auto; + padding: 0.2em 1em; + border: 1px solid #888; + border-bottom: none; + background-color: #eee; +} diff --git a/hyperkitty/static/js/hyperkitty.js b/hyperkitty/static/js/hyperkitty.js index 4b64b91..e43f766 100644 --- a/hyperkitty/static/js/hyperkitty.js +++ b/hyperkitty/static/js/hyperkitty.js @@ -263,14 +263,15 @@ function setup_replies(baseElem) { }).change(); } -function setup_navkeys() { +function setup_unreadnavbar(element) { + element = $(element); + if (element.length === 0) { + return; + } var current_index; - function scroll(e) { - var inc; + function scroll(inc) { var unreads = $(".email.unread"); if (unreads.length == 0) { return; } - if (e.data == "j") { inc = 1; } - if (e.data == "k") { inc = -1; } if (typeof current_index == "undefined") { if (inc == 1) { current_index = -1; } if (inc == -1) { current_index = unreads.length; } @@ -278,14 +279,18 @@ function setup_navkeys() { current_index = current_index + inc; if (current_index < 0) { current_index = unreads.length - 1; } if (current_index >= unreads.length) { current_index = 0; } + element.find(".unreadindex").text(current_index + 1); // compensate for the fixed banner at the top var target = unreads.eq(current_index).offset().top - 70; - $("html,body").animate({ + $("html,body").stop(true, false).animate({ scrollTop: target }, 500); } - $(document).bind("keydown", "j", scroll); - $(document).bind("keydown", "k", scroll); + element.find(".nextunread").click(function(e) { e.preventDefault(); scroll(1); }); + element.find(".prevunread").click(function(e) { e.preventDefault(); scroll(-1); }); + $(document).bind("keydown", "j", function(e) { scroll(1); }); + $(document).bind("keydown", "k", function(e) { scroll(-1); }); + element.animate({height: "show"}, 700); } diff --git a/hyperkitty/templates/thread.html b/hyperkitty/templates/thread.html index a25046e..e8b8139 100644 --- a/hyperkitty/templates/thread.html +++ b/hyperkitty/templates/thread.html @@ -31,38 +31,38 @@
-
- -
- - - {% include 'messages/message.html' with email=first_mail unfolded='True' %} - - -

- {% if sort_mode == "date" %} - Show replies by thread - {% else %} - Show replies by date - {% endif %} -

- -
- {% if is_bot %} - {% include 'ajax/replies.html' %} - {% else %} - Loading... - {% endif %} +
+ +
+ + + {% include 'messages/message.html' with email=first_mail unfolded='True' %} + + +

+ {% if sort_mode == "date" %} + Show replies by thread + {% else %} + Show replies by date + {% endif %} +

+ +
+ {% if is_bot %} + {% include 'ajax/replies.html' %} + {% else %} + Loading... + {% endif %} +
+ +
-
-
- -
- {% include 'threads/right_col.html' %} -
+
+ {% include 'threads/right_col.html' %} +
@@ -81,7 +81,7 @@ fold_quotes(); // Load the replies update_thread_replies("{% url 'thread_replies' threadid=threadid mlist_fqdn=mlist.name %}?sort={{sort_mode}}&last_view={{last_view|date:'U'}}"); - setup_navkeys(); + setup_unreadnavbar("#unreadnavbar"); }); diff --git a/hyperkitty/templates/threads/right_col.html b/hyperkitty/templates/threads/right_col.html index 7f200fc..5011993 100644 --- a/hyperkitty/templates/threads/right_col.html +++ b/hyperkitty/templates/threads/right_col.html @@ -23,6 +23,7 @@ old +
{% csrf_token %} @@ -32,7 +33,11 @@ Remove from favorite discussions

- +

+ {% if user.is_authenticated %} + {{ unread_count }} unread messages + {% endif %} +

{% include 'threads/tags.html' %}
@@ -56,4 +61,15 @@ +{% if user.is_authenticated %} +
+
+ Unreads: 0/{{unread_count}} +   + Go to: next ↓ + - prev ↑ +
+
+{% endif %} + {# vim: set noet: #} diff --git a/hyperkitty/views/thread.py b/hyperkitty/views/thread.py index 03cfd6a..1e44714 100644 --- a/hyperkitty/views/thread.py +++ b/hyperkitty/views/thread.py @@ -118,6 +118,15 @@ def thread_index(request, mlist_fqdn, threadid, month=None, year=None): if not created: last_view = last_view_obj.view_date last_view_obj.save() # update timestamp + # get the number of unread messages + if last_view is None: + if request.user.is_authenticated(): + unread_count = len(thread) + else: + unread_count = 0 + else: + # XXX: Storm-specific + unread_count = thread.replies_after(last_view).count() # TODO: eventually move to a middleware ? # http://djangosnippets.org/snippets/1865/ @@ -145,6 +154,7 @@ def thread_index(request, mlist_fqdn, threadid, month=None, year=None): 'is_bot': is_bot, 'participants': thread.participants, 'last_view': last_view, + 'unread_count': unread_count, } context["participants"].sort(key=lambda x: x[0].lower()) -- cgit