Show 5 most recent "Private messages" when clicked.

Like the Stream Subject lists, Private messages are now shown
when the user clicks on the "Private message" link. User can drill in
to get more than 5 conversations. Selecting PMs from the user or group
PM lists on the right sidebar also opens the list & highlights the
selected conversation.

[Edited by tabbott@mit.edu to fix some small bugs.]
This commit is contained in:
Kara McNair 2015-11-25 12:41:32 -05:00 committed by Tim Abbott
parent 29fa601328
commit fd66d9f703
8 changed files with 275 additions and 9 deletions

View File

@ -13,6 +13,9 @@ add_dependencies({
set_global('recent_subjects', new global.Dict());
set_global('unread', {});
set_global('message_store', {
recent_private_messages: new global.Array()
});
var stream_list = require('js/stream_list.js');
@ -23,6 +26,7 @@ $.fn.expectOne = function () {
};
global.use_template('sidebar_subject_list');
global.use_template('sidebar_private_message_list');
global.use_template('stream_sidebar_row');
global.use_template('stream_privacy');
@ -46,6 +50,29 @@ global.use_template('stream_privacy');
assert.equal(topic, 'coding');
}());
(function test_build_private_messages_list() {
var reply_tos = "alice@zulip.com,bob@zulip.com";
var active_conversation = "Alice, Bob";
var max_conversations = 5;
var conversations = {reply_to: reply_tos,
display_reply_to: active_conversation,
timestamp: 0 };
global.message_store.recent_private_messages.push(conversations);
global.unread.num_unread_for_person = function () {
return 1;
};
var convos_html = stream_list._build_private_messages_list(active_conversation, max_conversations);
global.write_test_output("test_build_private_messages_list", convos_html);
var conversation = $(convos_html).find('a').text().trim();
assert.equal(conversation, active_conversation);
}());
(function test_add_stream_to_sidebar() {
// Make a couple calls to add_stream_to_sidebar() and make sure they
// generate the right markup as well as play nice with get_stream_li().

View File

@ -196,6 +196,7 @@ exports.edit_locally = function edit_locally(message, raw_content, new_topic) {
narrowed_msg_list.view.rerender_messages([message]);
}
stream_list.update_streams_sidebar();
stream_list.update_private_messages();
};
exports.reify_message_id = function reify_message_id(local_id, server_id) {

View File

@ -10,6 +10,7 @@ var load_more_enabled = true;
// used for our URL rewriting in insert_new_messages
var humbug_images_re = new RegExp("https://humbug-user-uploads.s3.amazonaws.com/([^\"]+)", 'g');
exports.recent_private_messages = [];
exports.get = function get(message_id) {
return stored_messages[message_id];
@ -58,6 +59,25 @@ exports.process_message_for_recent_subjects = function process_message_for_recen
recent_subjects.set(stream, recents);
};
exports.process_message_for_recent_private_messages = function process_message_for_recent_private_messages(message, remove_message) {
var current_timestamp = 0;
// If this conversation is already tracked, we'll replace with new timestamp,
// so remove it from the current list.
exports.recent_private_messages = _.filter(exports.recent_private_messages, function (recent_pm) {
return recent_pm.reply_to !== message.reply_to;
});
var new_conversation = {reply_to: message.reply_to,
display_reply_to: message.display_reply_to,
timestamp: Math.max(message.timestamp, current_timestamp)};
exports.recent_private_messages.push(new_conversation);
exports.recent_private_messages.sort(function (a, b) {
return b.timestamp - a.timestamp;
});
};
function set_topic_edit_properties(message) {
message.always_visible_topic_edit = false;
message.on_hover_topic_edit = false;
@ -120,6 +140,7 @@ function add_message_metadata(message) {
get_private_message_recipient(message, 'email'));
message.display_reply_to = get_private_message_recipient(message, 'full_name', 'email');
exports.process_message_for_recent_private_messages(message);
involved_people = message.display_recipient;
break;
}
@ -333,6 +354,7 @@ exports.update_messages = function update_messages(events) {
}
unread.update_unread_counts();
stream_list.update_streams_sidebar();
stream_list.update_private_messages();
};
exports.insert_new_messages = function insert_new_messages(messages) {
@ -383,6 +405,7 @@ exports.insert_new_messages = function insert_new_messages(messages) {
unread.process_visible();
notifications.received_messages(messages);
stream_list.update_streams_sidebar();
stream_list.update_private_messages();
};
function process_result(messages, opts) {
@ -410,6 +433,7 @@ function process_result(messages, opts) {
}
stream_list.update_streams_sidebar();
stream_list.update_private_messages();
if (opts.cont !== undefined) {
opts.cont(messages);

View File

@ -157,6 +157,10 @@ exports.hide_streamlist_sidebar = function () {
$(".app-main .column-left").removeClass("expanded");
};
exports.hide_pm_list_sidebar = function () {
$(".app-main .column-left").removeClass("expanded");
};
exports.show_userlist_sidebar = function () {
$(".app-main .column-right").addClass("expanded");
resize.resize_page_components();
@ -167,6 +171,11 @@ exports.show_streamlist_sidebar = function () {
resize.resize_page_components();
};
exports.show_pm_list_sidebar = function () {
$(".app-main .column-left").addClass("expanded");
resize.resize_page_components();
};
var current_stream_sidebar_elem;
var current_topic_sidebar_elem;
var current_user_sidebar_email;

View File

@ -175,6 +175,13 @@ exports.resize_bottom_whitespace = function (h) {
}
};
exports.resize_stream_filters_container = function (h) {
h = narrow_window ? left_userlist_get_new_heights() : get_new_heights();
exports.resize_bottom_whitespace(h);
$("#stream-filters-container").css('max-height', h.stream_filters_max_height);
$('#stream-filters-container').perfectScrollbar('update');
};
exports.resize_page_components = function () {
var composebox = $("#compose");
var floating_recipient_bar = $("#floating_recipient_bar");

View File

@ -4,6 +4,7 @@ var exports = {};
var zoomed_to_topics = false;
var zoomed_stream = '';
var private_messages_open = false;
var last_private_message_count = 0;
var last_mention_count = 0;
var previous_sort_order;
@ -115,13 +116,21 @@ function remove_expanded_subjects() {
$("ul.expanded_subjects").remove();
}
function remove_expanded_private_messages() {
popovers.hide_topic_sidebar_popover();
$("ul.expanded_private_messages").remove();
resize.resize_stream_filters_container();
}
function reset_to_unnarrowed(narrowed_within_same_stream) {
if (zoomed_to_topics && narrowed_within_same_stream !== true) {
zoom_out();
}
private_messages_open = false;
$("ul.filters li").removeClass('active-filter active-sub-filter');
remove_expanded_subjects();
remove_expanded_private_messages();
}
function get_subject_filter_li(stream, subject) {
@ -129,6 +138,12 @@ function get_subject_filter_li(stream, subject) {
return iterate_to_find(".expanded_subjects li.expanded_subject", subject, stream_li);
}
function get_private_message_filter_li(conversation) {
var pm_li = get_filter_li('global', 'private');
return iterate_to_find(".expanded_private_messages li.expanded_private_message",
conversation, pm_li);
}
exports.set_in_home_view = function (stream, in_home) {
var li = get_filter_li('stream', stream);
if (in_home) {
@ -257,6 +272,20 @@ exports.set_subject_count = function (stream, subject, count) {
update_count_in_dom(count_span, value_span, count);
};
exports.set_pm_conversation_count = function (conversation, count) {
var pm_li = get_private_message_filter_li(conversation);
var count_span = pm_li.find('.private_message_count');
var value_span = count_span.find('.value');
if (count_span.length === 0 || value_span.length === 0) {
return;
}
count_span.removeClass("zero_count");
update_count_in_dom(count_span, value_span, count);
};
exports.remove_narrow_filter = function (name, type) {
get_filter_li(type, name).remove();
};
@ -301,6 +330,42 @@ exports._build_subject_list = function (stream, active_topic, max_subjects) {
return topic_dom;
};
exports._build_private_messages_list = function (active_conversation, max_private_messages) {
var private_messages = message_store.recent_private_messages || [];
var display_messages = [];
var hiding_messages = false;
_.each(private_messages, function (private_message_obj, idx) {
var recipients_string = private_message_obj.display_reply_to;
var replies_to = private_message_obj.reply_to;
var num_unread = unread.num_unread_for_person(private_message_obj.reply_to);
// Show the most recent subjects, as well as any with unread messages
var always_visible = (idx < max_private_messages) || (num_unread > 0)
|| (replies_to === active_conversation);
if (!always_visible) {
hiding_messages = true;
}
var display_message = {
recipients: recipients_string,
reply_to: replies_to,
unread: num_unread,
is_zero: num_unread === 0,
zoom_out_hide: !always_visible,
url: narrow.pm_with_uri(private_message_obj.reply_to)
};
display_messages.push(display_message);
});
var recipients_dom = templates.render('sidebar_private_message_list',
{messages: display_messages,
want_show_more_messages_links: hiding_messages});
return recipients_dom;
};
function rebuild_recent_subjects(stream, active_topic) {
// TODO: Call rebuild_recent_subjects less, not on every new
// message.
@ -316,6 +381,23 @@ function rebuild_recent_subjects(stream, active_topic) {
}
}
function rebuild_recent_private_messages(active_conversation) {
remove_expanded_private_messages();
if (private_messages_open)
{
var max_private_messages = 5;
var private_li = get_filter_li('global', 'private');
var private_messages_dom = exports._build_private_messages_list(active_conversation,
max_private_messages);
private_li.append(private_messages_dom);
}
if (active_conversation) {
get_private_message_filter_li(active_conversation).addClass('active-sub-filter');
}
resize.resize_stream_filters_container();
}
exports.update_streams_sidebar = function () {
exports.build_stream_list();
@ -336,6 +418,25 @@ exports.update_streams_sidebar = function () {
}
};
exports.update_private_messages = function () {
exports._build_private_messages_list();
if (! narrow.active()) {
return;
}
var is_pm_filter = _.contains(narrow.filter().operands('is'), "private");
var conversation = narrow.filter().operands('pm-with');
if (conversation.length === 1) {
rebuild_recent_private_messages(conversation[0]);
} else if (conversation.length !== 0) {
// TODO: This should be the reply-to of the thread.
rebuild_recent_private_messages("");
} else if (is_pm_filter) {
rebuild_recent_private_messages("");
}
};
function do_new_messages_animation(message_type) {
var li = get_filter_li("global", message_type);
li.addClass("new_messages");
@ -385,9 +486,9 @@ exports.update_dom_with_unread_counts = function (counts) {
});
});
counts.pm_count.each(function (count, person) {
exports.set_presence_list_count(person, count);
exports.set_pm_conversation_count(person, count);
});
// integer counts
@ -420,10 +521,26 @@ $(function () {
}
var op_is = event.filter.operands('is');
if (op_is.length !== 0) {
if (['private', 'starred', 'mentioned'].indexOf(op_is[0]) !== -1) {
if (['starred', 'mentioned'].indexOf(op_is[0]) !== -1) {
$("#global_filters li[data-name='" + op_is[0] + "']").addClass('active-filter');
}
}
var op_pm = event.filter.operands('pm-with');
if ((op_is.length !== 0 && _.contains(op_is, "private")) || op_pm.length !== 0) {
private_messages_open = true;
if (op_pm.length === 1) {
$("#user_presences li[data-email='" + op_pm[0] + "']").addClass('active-filter');
rebuild_recent_private_messages(op_pm[0]);
} else if (op_pm.length !== 0) {
// TODO: Should pass the reply-to of the thread
rebuild_recent_private_messages("");
} else {
$("#global_filters li[data-name='private']").addClass('active-filter zoom-out');
rebuild_recent_private_messages("");
}
}
var op_stream = event.filter.operands('stream');
if (op_stream.length !== 0 && stream_data.is_subscribed(op_stream[0])) {
var stream_li = get_filter_li('stream', op_stream[0]);
@ -437,10 +554,6 @@ $(function () {
rebuild_recent_subjects(op_stream[0], subject);
unread.process_visible();
}
var op_pm = event.filter.operands('pm-with');
if (op_pm.length === 1) {
$("#user_presences li[data-email='" + op_pm[0] + "']").addClass('active-filter');
}
});
$(document).on('narrow_deactivated.zulip', function (event) {
@ -489,6 +602,17 @@ $(function () {
e.stopPropagation();
});
$('#global_filters').on('click', '.show-more-private-messages', function (e) {
popovers.hide_all();
$(".expanded_private_messages").expectOne().removeClass("zoom-out").addClass("zoom-in");
$(".expanded_private_messages li.expanded_private_message").each(function () {
$(this).show();
});
e.preventDefault();
e.stopPropagation();
});
$('#stream_filters').on('click', 'li .subscription_block', function (e) {
if (e.metaKey || e.ctrlKey) {
return;

View File

@ -484,7 +484,7 @@ ul.filters hr {
li.active-filter,
li.active-sub-filter {
font-weight: 600;
font-weight: 600 !important;
background: #ddedf6;
position: relative;
}
@ -606,6 +606,21 @@ ul.filters {
letter-spacing: 0.6px;
}
.private_message_count {
display: block;
position: absolute;
line-height: 1em;
right: 10px;
top: 2px;
padding: 2px 3px 0px 3px;
background: #a6ada4;
color: #ffffff;
border-radius: 1px;
font-size: 12px;
font-weight: normal;
letter-spacing: 0.6px;
}
ul.filters i {
padding-right: 0.25em;
/* Make filter icons the same width so labels line up. */
@ -2460,6 +2475,13 @@ div.floating_recipient {
text-overflow: ellipsis;
}
.conversation-partners {
display: block;
line-height: 1.2em;
width: 90%;
overflow: hidden;
}
.subscription_header {
min-height: 47px;
}
@ -2831,12 +2853,32 @@ ul.expanded_subjects {
padding-bottom: 2px;
}
ul.expanded_private_messages {
list-style-type: none;
font-weight: 300;
font-size: 84%;
margin-left: 0px;
padding-bottom: 2px;
}
li.show-more-topics,
li.expanded_subject {
position: relative;
padding-left: 33px;
}
li.show-more-private-messages,
li.expanded_private_message {
position: relative;
padding-left: 24px;
padding-bottom: 1px;
padding-top: 2px;
}
#global_filters li:hover {
background-color: #e2e8dd;
}
.show-all-streams a {
color: #333;
}
@ -2846,12 +2888,14 @@ li.expanded_subject {
margin-bottom: -5px;
}
.expanded_subject .subject_box {
.expanded_subject .subject_box,
#private .expanded_private_message .subject_box {
display: block;
margin-right: 38px;
}
.expanded_subject.zero-subject-unreads .subject_box {
.expanded_subject.zero-subject-unreads .subject_box,
#private .expanded_private_messages.zero-subject-unreads .subject_box {
display: block;
margin-right: 15px;
}
@ -3979,10 +4023,18 @@ li.show-more-topics a {
font-size: 75%;
}
li.show-more-private-messages a {
font-size: 90%
}
.zoom-in .show-more-topics {
display: none;
}
.zoom-in .show-more-private-messages {
display: none;
}
.zoom-out .zoom-out-hide {
display: none;
}

View File

@ -0,0 +1,22 @@
<ul class='expanded_private_messages' data-name='private'>
{{#each messages}}
<li class='{{#if is_zero}}zero-subject-unreads{{/if}} {{#if zoom_out_hide}}zoom-out-hide{{/if}} expanded_private_message' data-name='{{reply_to}}'>
<span class='subject_box'>
<a href='{{url}}' class="conversation-partners">
{{recipients}}
</a>
<div class="private_message_count {{#if is_zero}}zero_count{{/if}}">
<div class="value">{{unread}}</div>
</div>
</span>
<span class="arrow topic-sidebar-arrow">
<i class="icon-vector-chevron-down"></i>
</span>
</li>
{{/each}}
{{#if want_show_more_messages_links}}
<li class="show-more-private-messages" data-name='more-private-messages'>
<a href="#">(more conversations)</a>
</li>
{{/if}}
</ul>