import * as blueslip from "./blueslip"; import * as people from "./people"; const stored_messages = new Map(); export function update_message_cache(message) { // You should only call this from message_helper (or in tests). stored_messages.set(message.id, message); } export function get_cached_message(message_id) { // You should only call this from message_helper. // Use the get() wrapper below for most other use cases. return stored_messages.get(message_id); } export function clear_for_testing() { stored_messages.clear(); } export function get(message_id) { if (message_id === undefined || message_id === null) { blueslip.error("message_store.get got bad value: " + message_id); return undefined; } if (typeof message_id !== "number") { blueslip.error("message_store got non-number: " + message_id); // Try to soldier on, assuming the caller treats message // ids as strings. message_id = Number.parseFloat(message_id); } return stored_messages.get(message_id); } export function get_pm_emails(message) { const user_ids = people.pm_with_user_ids(message); const emails = user_ids .map((user_id) => { const person = people.get_by_user_id(user_id); if (!person) { blueslip.error("Unknown user id " + user_id); return "?"; } return person.email; }) .sort(); return emails.join(", "); } export function get_pm_full_names(message) { const user_ids = people.pm_with_user_ids(message); const names = people.get_display_full_names(user_ids).sort(); return names.join(", "); } export function set_message_booleans(message) { const flags = message.flags || []; function convert_flag(flag_name) { return flags.includes(flag_name); } message.unread = !convert_flag("read"); message.historical = convert_flag("historical"); message.starred = convert_flag("starred"); message.mentioned = convert_flag("mentioned") || convert_flag("wildcard_mentioned"); message.mentioned_me_directly = convert_flag("mentioned"); message.collapsed = convert_flag("collapsed"); message.alerted = convert_flag("has_alert_word"); // Once we have set boolean flags here, the `flags` attribute is // just a distraction, so we delete it. (All the downstream code // uses booleans.) delete message.flags; } export function init_booleans(message) { // This initializes booleans for the local-echo path where // we don't have flags from the server yet. (We want to // explicitly set flags to false to be consistent with other // codepaths.) message.unread = false; message.historical = false; message.starred = false; message.mentioned = false; message.mentioned_me_directly = false; message.collapsed = false; message.alerted = false; } export function update_booleans(message, flags) { // When we get server flags for local echo or message edits, // we are vulnerable to race conditions, so only update flags // that are driven by message content. function convert_flag(flag_name) { return flags.includes(flag_name); } message.mentioned = convert_flag("mentioned") || convert_flag("wildcard_mentioned"); message.mentioned_me_directly = convert_flag("mentioned"); message.alerted = convert_flag("has_alert_word"); } export function update_property(property, value, info) { switch (property) { case "sender_full_name": case "small_avatar_url": for (const msg of stored_messages.values()) { if (msg.sender_id && msg.sender_id === info.user_id) { msg[property] = value; } } break; case "stream_name": for (const msg of stored_messages.values()) { if (msg.stream_id && msg.stream_id === info.stream_id) { msg.display_recipient = value; msg.stream = value; } } break; case "status_emoji_info": for (const msg of stored_messages.values()) { if (msg.sender_id && msg.sender_id === info.user_id) { msg[property] = value; } } break; } } export function reify_message_id({old_id, new_id}) { if (stored_messages.has(old_id)) { stored_messages.set(new_id, stored_messages.get(old_id)); stored_messages.delete(old_id); } }