zulip/static/js/message_helper.js

83 lines
3.0 KiB
JavaScript
Raw Normal View History

import * as alert_words from "./alert_words";
import * as message_store from "./message_store";
import * as message_user_ids from "./message_user_ids";
import * as people from "./people";
import * as pm_conversations from "./pm_conversations";
import * as recent_senders from "./recent_senders";
import * as stream_topic_history from "./stream_topic_history";
import * as user_status from "./user_status";
import * as util from "./util";
export function process_new_message(message) {
// Call this function when processing a new message. After
// a message is processed and inserted into the message store
// cache, most modules use message_store.get to look at
// messages.
const cached_msg = message_store.get_cached_message(message.id);
if (cached_msg !== undefined) {
// Copy the match topic and content over if they exist on
// the new message
if (util.get_match_topic(message) !== undefined) {
util.set_match_data(cached_msg, message);
}
return cached_msg;
}
narrow: Fix messages being cached without flags set. f0c680e9c0d1a62fd414bccc82e4ac255173aaa9 introduced a call to message_helper.process_new_message without first calling message_store.set_message_flags on the message. This resulted in it being possible as a race, when loading the Zulip app to a stream/topic/near narrow, for a message to have the `historical` flag be undefined due to not being initialized. That invalid state, in turn, resulted in the message_list_view code path for rendering the message feed incorrectly displaying additional recipient bars around the message. We could fix this by just calling message_store.set_message_booleans in this code path. However, this bug exposes the fact that it's very fragile to expect every code path to call that function before message_helper.process_new_message. So we instead fix this by moving message_store.set_message_booleans inside message_helper.process_new_message. One call point of concern in this change is maybe_add_narrow_messages, which could theoretically reintroduce the double set_message_flags bugs detailed in 9729b1a4ad51b69c98ce4f8374c9d9f8cf69430c. However, I believe that to not be possible, because that call should never experience a cache miss. The other existing code paths were already calling set_message_booleans immediately before message_helper.process_new_message. They are still changing here, in that we now do a cache lookup before attempting to call set_message_booleans. Because the message booleans do not affect the cache lookup and the local message object is discarded in case of a cache hit, this should have no functional impact. Because I found the existing comment at that call site confusing and almost proposed removing it as pointless, extend the block comment to explicitly mention that the purpose is refreshing our object. Fixes #21503.
2022-03-24 01:07:56 +01:00
message_store.set_message_booleans(message);
message.sent_by_me = people.is_current_user(message.sender_email);
people.extract_people_from_message(message);
people.maybe_incr_recipient_count(message);
const sender = people.get_by_user_id(message.sender_id);
if (sender) {
message.sender_full_name = sender.full_name;
message.sender_email = sender.email;
message.status_emoji_info = user_status.get_status_emoji(message.sender_id);
}
// Convert topic even for PMs, as legacy code
// wants the empty field.
util.convert_message_topic(message);
switch (message.type) {
case "stream":
message.is_stream = true;
message.stream = message.display_recipient;
message.reply_to = message.sender_email;
stream_topic_history.add_message({
stream_id: message.stream_id,
topic_name: message.topic,
message_id: message.id,
});
recent_senders.process_message_for_senders(message);
message_user_ids.add_user_id(message.sender_id);
break;
case "private":
message.is_private = true;
message.reply_to = util.normalize_recipients(message_store.get_pm_emails(message));
message.display_reply_to = message_store.get_pm_full_names(message);
message.pm_with_url = people.pm_with_url(message);
message.to_user_ids = people.pm_reply_user_string(message);
pm_conversations.process_message(message);
if (people.is_my_user_id(message.sender_id)) {
for (const recip of message.display_recipient) {
message_user_ids.add_user_id(recip.id);
}
}
break;
}
alert_words.process_message(message);
if (!message.reactions) {
message.reactions = [];
}
message_store.update_message_cache(message);
return message;
}