mirror of https://github.com/zulip/zulip.git
parent
c0ad0b3b10
commit
38a4751b7b
|
@ -15,6 +15,7 @@ mock_esm("../../static/js/stream_topic_history", {
|
||||||
|
|
||||||
mock_esm("../../static/js/recent_senders", {
|
mock_esm("../../static/js/recent_senders", {
|
||||||
process_stream_message: noop,
|
process_stream_message: noop,
|
||||||
|
process_private_message: noop,
|
||||||
});
|
});
|
||||||
|
|
||||||
set_global("document", "document-stub");
|
set_global("document", "document-stub");
|
||||||
|
|
|
@ -26,6 +26,9 @@ function make_stream_message({stream_id, topic, sender_id}) {
|
||||||
mock_esm("../../static/js/message_store", {
|
mock_esm("../../static/js/message_store", {
|
||||||
get: (message_id) => messages.get(message_id),
|
get: (message_id) => messages.get(message_id),
|
||||||
});
|
});
|
||||||
|
mock_esm("../../static/js/people", {
|
||||||
|
my_current_user_id: () => 1,
|
||||||
|
});
|
||||||
|
|
||||||
const rs = zrequire("recent_senders");
|
const rs = zrequire("recent_senders");
|
||||||
zrequire("message_util.js");
|
zrequire("message_util.js");
|
||||||
|
@ -310,3 +313,38 @@ test("process_stream_message", () => {
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("process_pms", () => {
|
||||||
|
const sender1 = 1; // Current user id
|
||||||
|
const sender2 = 2;
|
||||||
|
const sender3 = 3;
|
||||||
|
|
||||||
|
const user_ids_string = "2,3,4";
|
||||||
|
rs.process_private_message({
|
||||||
|
to_user_ids: user_ids_string,
|
||||||
|
sender_id: sender2,
|
||||||
|
id: 1,
|
||||||
|
});
|
||||||
|
rs.process_private_message({
|
||||||
|
to_user_ids: user_ids_string,
|
||||||
|
sender_id: sender3,
|
||||||
|
id: 2,
|
||||||
|
});
|
||||||
|
rs.process_private_message({
|
||||||
|
to_user_ids: user_ids_string,
|
||||||
|
sender_id: sender1,
|
||||||
|
id: 3,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Recent topics displays avatars in the opposite order to this since
|
||||||
|
// that was simpler to implement in HTML.
|
||||||
|
assert.deepEqual(rs.get_pm_recent_senders(user_ids_string), {
|
||||||
|
participants: [1, 3, 2],
|
||||||
|
non_participants: [4],
|
||||||
|
});
|
||||||
|
// PM doesn't exist.
|
||||||
|
assert.deepEqual(rs.get_pm_recent_senders("1000,2000"), {
|
||||||
|
participants: [],
|
||||||
|
non_participants: [],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -65,6 +65,7 @@ export function process_new_message(message) {
|
||||||
|
|
||||||
pm_conversations.process_message(message);
|
pm_conversations.process_message(message);
|
||||||
|
|
||||||
|
recent_senders.process_private_message(message);
|
||||||
if (people.is_my_user_id(message.sender_id)) {
|
if (people.is_my_user_id(message.sender_id)) {
|
||||||
for (const recip of message.display_recipient) {
|
for (const recip of message.display_recipient) {
|
||||||
message_user_ids.add_user_id(recip.id);
|
message_user_ids.add_user_id(recip.id);
|
||||||
|
|
|
@ -2,6 +2,7 @@ import _ from "lodash";
|
||||||
|
|
||||||
import {FoldDict} from "./fold_dict";
|
import {FoldDict} from "./fold_dict";
|
||||||
import * as message_store from "./message_store";
|
import * as message_store from "./message_store";
|
||||||
|
import * as people from "./people";
|
||||||
|
|
||||||
// This class is only exported for unit testing purposes.
|
// This class is only exported for unit testing purposes.
|
||||||
// If we find reuse opportunities, we should just put it into
|
// If we find reuse opportunities, we should just put it into
|
||||||
|
@ -46,6 +47,9 @@ const stream_senders = new Map();
|
||||||
// topic_senders[stream_id][topic_id][sender_id] = IdTracker
|
// topic_senders[stream_id][topic_id][sender_id] = IdTracker
|
||||||
const topic_senders = new Map();
|
const topic_senders = new Map();
|
||||||
|
|
||||||
|
// pm_senders[user_ids_string][user_id] = IdTracker
|
||||||
|
const pm_senders = new Map();
|
||||||
|
|
||||||
export function clear_for_testing() {
|
export function clear_for_testing() {
|
||||||
stream_senders.clear();
|
stream_senders.clear();
|
||||||
topic_senders.clear();
|
topic_senders.clear();
|
||||||
|
@ -211,3 +215,38 @@ export function get_topic_recent_senders(stream_id, topic) {
|
||||||
}
|
}
|
||||||
return recent_senders;
|
return recent_senders;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function process_private_message({to_user_ids, sender_id, id}) {
|
||||||
|
const sender_dict = pm_senders.get(to_user_ids) || new Map();
|
||||||
|
const id_tracker = sender_dict.get(sender_id) || new IdTracker();
|
||||||
|
pm_senders.set(to_user_ids, sender_dict);
|
||||||
|
sender_dict.set(sender_id, id_tracker);
|
||||||
|
id_tracker.add(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function get_pm_recent_senders(user_ids_string) {
|
||||||
|
const user_ids = user_ids_string.split(",").map((id) => Number.parseInt(id, 10));
|
||||||
|
const sender_dict = pm_senders.get(user_ids_string);
|
||||||
|
const pm_senders_info = {participants: [], non_participants: []};
|
||||||
|
if (!sender_dict) {
|
||||||
|
return pm_senders_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
function compare_pm_user_ids_by_recency(user_id1, user_id2) {
|
||||||
|
const max_id1 = sender_dict.get(user_id1)?.max_id() || -1;
|
||||||
|
const max_id2 = sender_dict.get(user_id2)?.max_id() || -1;
|
||||||
|
return max_id2 - max_id1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add current user to user_ids.
|
||||||
|
user_ids.push(people.my_current_user_id());
|
||||||
|
pm_senders_info.non_participants = user_ids.filter((user_id) => {
|
||||||
|
if (sender_dict.get(user_id)) {
|
||||||
|
pm_senders_info.participants.push(user_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
pm_senders_info.participants.sort(compare_pm_user_ids_by_recency);
|
||||||
|
return pm_senders_info;
|
||||||
|
}
|
||||||
|
|
|
@ -430,10 +430,6 @@ function format_conversation(conversation_data) {
|
||||||
context.pm_url = last_msg.pm_with_url;
|
context.pm_url = last_msg.pm_with_url;
|
||||||
context.is_group = last_msg.display_recipient.length > 2;
|
context.is_group = last_msg.display_recipient.length > 2;
|
||||||
|
|
||||||
// Display in most recent sender first order
|
|
||||||
all_senders = last_msg.display_recipient;
|
|
||||||
senders = all_senders.slice(-MAX_AVATAR).map((sender) => sender.id);
|
|
||||||
|
|
||||||
if (!context.is_group) {
|
if (!context.is_group) {
|
||||||
const user_id = Number.parseInt(last_msg.to_user_ids, 10);
|
const user_id = Number.parseInt(last_msg.to_user_ids, 10);
|
||||||
const user = people.get_by_user_id(user_id);
|
const user = people.get_by_user_id(user_id);
|
||||||
|
@ -446,6 +442,17 @@ function format_conversation(conversation_data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Since the css for displaying senders in reverse order is much simpler,
|
||||||
|
// we provide our handlebars with senders in opposite order.
|
||||||
|
// Display in most recent sender first order.
|
||||||
|
// To match the behavior for streams, we display the set of users who've actually
|
||||||
|
// participated, with the most recent participants first. It could make sense to
|
||||||
|
// display the other recipients on the PM conversation with different styling,
|
||||||
|
// but it's important to not destroy the information of "who's actually talked".
|
||||||
|
all_senders = recent_senders
|
||||||
|
.get_pm_recent_senders(context.user_ids_string)
|
||||||
|
.participants.reverse();
|
||||||
|
senders = all_senders.slice(-MAX_AVATAR);
|
||||||
// Collect extra senders fullname for tooltip.
|
// Collect extra senders fullname for tooltip.
|
||||||
extra_sender_ids = all_senders.slice(0, -MAX_AVATAR);
|
extra_sender_ids = all_senders.slice(0, -MAX_AVATAR);
|
||||||
displayed_other_senders = extra_sender_ids
|
displayed_other_senders = extra_sender_ids
|
||||||
|
|
Loading…
Reference in New Issue