Show latest 5 subjects in sidebar when narrowed to a stream

This is a V1 of this feature. For now, the only way to expand is by narrowing
to the stream---future revisions may add a manual toggle if it is found to be
useful.

Additionally, showing per-subject unread counts will be coming in a future revision
as well.

(imported from commit fb5df0d27e928fa3b0f32b9ff2c1c508202cf7e5)
This commit is contained in:
Leo Franchi
2013-04-10 16:24:15 -04:00
parent 916c235d8c
commit 9130f6722f
6 changed files with 159 additions and 13 deletions

View File

@@ -42,7 +42,7 @@ var globals =
+ ' maybe_scroll_to_selected recenter_pointer_on_display suppress_scroll_pointer_update' + ' maybe_scroll_to_selected recenter_pointer_on_display suppress_scroll_pointer_update'
+ ' process_visible_unread_messages message_range message_in_table process_loaded_for_unread' + ' process_visible_unread_messages message_range message_in_table process_loaded_for_unread'
+ ' mark_all_as_read message_unread process_read_messages unread_in_current_view' + ' mark_all_as_read message_unread process_read_messages unread_in_current_view'
+ ' fast_forward_pointer' + ' fast_forward_pointer recent_subjects'
; ;

View File

@@ -371,15 +371,32 @@ exports.activate = function (operators, opts) {
compose.update_recipient_on_narrow(); compose.update_recipient_on_narrow();
compose.update_faded_messages(); compose.update_faded_messages();
$("ul.filters li").removeClass('active-filter'); $("ul.filters li").removeClass('active-filter active-subject-filter');
$("ul.expanded_subjects").addClass('hidden');
function expand_stream(stream) {
var filter_li = ui.get_filter_li('stream', operators[0][1]);
$('ul.expanded_subjects', filter_li).removeClass('hidden');
return filter_li;
}
if (operators.length === 1) { if (operators.length === 1) {
if (operators[0][0] === 'in' && operators[0][1] === 'all') { if (operators[0][0] === 'in' && operators[0][1] === 'all') {
$("#global_filters li[data-name='all']").addClass('active-filter'); $("#global_filters li[data-name='all']").addClass('active-filter');
} else if (operators[0][0] === "stream") { } else if (operators[0][0] === "stream") {
ui.get_filter_li('stream', operators[0][1]).addClass('active-filter'); var filter_li = expand_stream(operators[0][0]);
filter_li.addClass('active-filter');
} else if (operators[0][0] === "is" && operators[0][1] === "private-message") { } else if (operators[0][0] === "is" && operators[0][1] === "private-message") {
$("#global_filters li[data-name='private']").addClass('active-filter'); $("#global_filters li[data-name='private']").addClass('active-filter');
} }
} else if (operators.length === 2) {
if (operators[0][0] === 'stream' &&
operators[1][0] === 'subject') {
expand_stream(operators[0][0]);
ui.get_subject_filter_li(operators[0][1], operators[1][1])
.addClass('active-subject-filter');
}
} }
}; };
@@ -448,7 +465,8 @@ exports.deactivate = function () {
hashchange.save_narrow(); hashchange.save_narrow();
$("ul.filters li").removeClass('active-filter'); $("ul.filters li").removeClass('active-filter active-subject-filter');
$("ul.expanded_subjects").addClass('hidden');
$("#global_filters li[data-name='home']").addClass('active-filter'); $("#global_filters li[data-name='home']").addClass('active-filter');
// This really shouldn't be necessary since the act of unnarrowing // This really shouldn't be necessary since the act of unnarrowing

View File

@@ -1014,20 +1014,33 @@ $(function () {
e.preventDefault(); e.preventDefault();
}); });
$('#stream_filters li').on('click', 'a', function (e) { $('#stream_filters li').on('click', 'a.subscription_name', function (e) {
var stream = $(e.target).parents('li').data('name'); var stream = $(e.target).parents('li').data('name');
narrow.by('stream', stream, {select_first_unread: true}); narrow.by('stream', stream, {select_first_unread: true});
e.preventDefault(); e.preventDefault();
}); });
$('#stream_filters li').on('click', 'a', function (e) { $('#stream_filters').on('click', '.expanded_subject a', function (e) {
var stream = $(e.target).parents('li').data('name'); var stream = $(e.target).parents('ul').data('stream');
narrow.by('stream', stream, {select_first_unread: true}); var subject = $(e.target).parents('li').data('name');
narrow.activate([['stream', stream],
['subject', subject]],
{select_first_unread: true});
e.preventDefault(); e.preventDefault();
}); });
$('#stream_filters').on('click', '.streamlist_expand', function (e) {
var stream_li = $(e.target).parents('li');
var stream = stream_li.data('name');
$('ul.expanded_subjects', stream_li).toggleClass('hidden');
return false;
});
$('.composebox-close').click(function (e) { compose.cancel(); }); $('.composebox-close').click(function (e) { compose.cancel(); });
$('.compose_stream_button').click(function (e) { $('.compose_stream_button').click(function (e) {
compose.set_mode('stream'); compose.set_mode('stream');
@@ -1112,7 +1125,7 @@ $(function () {
}); });
function sort_narrow_list() { function sort_narrow_list() {
var items = $('#stream_filters li').get(); var items = $('#stream_filters > li').get();
var parent = $('#stream_filters'); var parent = $('#stream_filters');
items.sort(function(a,b){ items.sort(function(a,b){
return $(a).attr('data-name').localeCompare($(b).attr('data-name')); return $(a).attr('data-name').localeCompare($(b).attr('data-name'));
@@ -1125,16 +1138,25 @@ function sort_narrow_list() {
}); });
} }
exports.get_filter_li = function(type, name) { function iterate_to_find(selector, data_name, context) {
var retval = $(); var retval = $();
$("#" + type + "_filters li").each(function (idx, elem) { $(selector, context).each(function (idx, elem) {
var jelem = $(elem); var jelem = $(elem);
if (jelem.attr('data-name') === name) { if (jelem.attr('data-name') === data_name) {
retval = jelem; retval = jelem;
return false; return false;
} }
}); });
return retval; return retval;
}
exports.get_filter_li = function(type, name) {
return iterate_to_find("#" + type + "_filters > li", name);
};
exports.get_subject_filter_li = function(stream, subject) {
var stream_li = exports.get_filter_li('stream', stream);
return iterate_to_find(".expanded_subjects li", subject, stream_li);
}; };
exports.add_narrow_filter = function(name, type, uri) { exports.add_narrow_filter = function(name, type, uri) {
@@ -1289,5 +1311,58 @@ exports.restore_compose_cursor = function () {
.caret(saved_compose_cursor, saved_compose_cursor); .caret(saved_compose_cursor, saved_compose_cursor);
}; };
exports.update_recent_subjects = function () {
function same(arr1, arr2) {
var i = 0;
if (arr1.length !== arr2.length) return false;
for (i = 0; i < arr1.length; i++) {
if (arr2[i] !== arr1[i]) {
return false;
}
}
return true;
}
$("#stream_filters > li").each(function (idx, elem) {
var stream = $(elem).data('name');
var expander = $('.streamlist_expand', elem);
var subjects = recent_subjects[stream] || [];
var subject_names = $.map(subjects, function (elem, idx) {
return elem.subject;
});
expander.toggleClass('hidden', subjects.length === 0);
var currently_shown = $('ul.expanded_subjects li', elem).map(function(idx, elem) {
return $(elem).text().trim();
});
if (!same(currently_shown, subject_names)) {
var subject_list = $("ul.expanded_subjects", elem);
var was_hidden = subject_list.length === 0 || subject_list.hasClass('hidden');
// If this is the first subject in current narrow, show it regardless
var operators = narrow.operators();
if (subject_list.length === 0 && operators.length > 0 && operators[0][0] === 'stream') {
was_hidden = operators[0][1] !== stream;
}
var active_subject = $("ul.expanded_subjects li.active-subject-filter").text().trim();
subject_list.remove();
if (subjects.length > 0) {
$(elem).append(templates.render('sidebar_subject_list',
{subjects: subjects,
stream: stream,
hidden: was_hidden}));
if (active_subject !== '') {
exports.get_subject_filter_li(stream, active_subject).addClass('active-subject-filter');
}
}
}
});
};
return exports; return exports;
}()); }());

View File

@@ -4,6 +4,7 @@ var narrowed_msg_list;
var current_msg_list = home_msg_list; var current_msg_list = home_msg_list;
var subject_dict = {}; var subject_dict = {};
var people_dict = {}; var people_dict = {};
var recent_subjects = {};
var queued_mark_as_read = []; var queued_mark_as_read = [];
var queued_flag_timer; var queued_flag_timer;
@@ -462,6 +463,40 @@ function case_insensitive_find(term, array) {
}).length !== 0; }).length !== 0;
} }
var update_recent_subjects = $.debounce(100, ui.update_recent_subjects);
function process_message_for_recent_subjects(message) {
var current_timestamp = 0;
if (! recent_subjects.hasOwnProperty(message.display_recipient)) {
recent_subjects[message.display_recipient] = [];
} else {
recent_subjects[message.display_recipient] =
$.grep(recent_subjects[message.display_recipient], function (item) {
if (item.subject === message.subject) {
current_timestamp = item.timestamp;
}
return item.subject !== message.subject;
});
}
var recents = recent_subjects[message.display_recipient];
if (recents.length >= 5 && message.timestamp > recents[4].timestamp) {
recents = recents.slice(0, recents.length - 1);
}
recents.push({subject: message.subject,
timestamp: Math.max(message.timestamp, current_timestamp)});
recents.sort(function (a, b) {
return a.timestamp < b.timestamp;
});
recent_subjects[message.display_recipient] = recents;
update_recent_subjects();
}
function add_message_metadata(message, dummy) { function add_message_metadata(message, dummy) {
if (all_msg_list.get(message.id)) { if (all_msg_list.get(message.id)) {
return all_msg_list.get(message.id); return all_msg_list.get(message.id);
@@ -487,6 +522,8 @@ function add_message_metadata(message, dummy) {
} }
message.reply_to = message.sender_email; message.reply_to = message.sender_email;
process_message_for_recent_subjects(message);
involved_people = [{'full_name': message.sender_full_name, involved_people = [{'full_name': message.sender_full_name,
'email': message.sender_email}]; 'email': message.sender_email}];
break; break;

View File

@@ -206,7 +206,7 @@ ul.filters hr {
margin-bottom: 10px; margin-bottom: 10px;
} }
li.active-filter { li.active-filter, li.active-subject-filter {
font-weight: bold; font-weight: bold;
} }
@@ -1045,6 +1045,15 @@ table.floating_recipient {
vertical-align: middle; vertical-align: middle;
} }
ul.expanded_subjects {
list-style-type: none;
font-weight: normal;
}
li.expanded_subject {
margin-left: .3em;
}
.twitter-tweet { .twitter-tweet {
border: 1px solid #ddd; border: 1px solid #ddd;
padding: .5em .75em; padding: .5em .75em;

View File

@@ -0,0 +1,7 @@
<ul class='expanded_subjects {{#if hidden}}hidden{{/if}}' data-stream='{{stream}}'>
{{#each subjects}}
<li class='expanded_subject' data-name='{{subject}}'>
<a href='#narrow/stream/{{../stream}}/subject/{{subject}}'>{{subject}}</a>
</li>
{{/each}}
</ul>