local echo: Bypass message.flags array.

We no longer set message.flags in the local echo path.

In the markdown parsing step, we just set message.mentioned
directly.

And then we change `insert_new_messages` to no longer
convert flags to booleans, and move that code to only
happen for incoming server message events.
This commit is contained in:
Steve Howell
2017-12-16 17:25:31 -05:00
committed by showell
parent 4d8d17d134
commit 0a3d769911
8 changed files with 81 additions and 32 deletions

View File

@@ -12,6 +12,7 @@ zrequire('people');
zrequire('user_groups');
zrequire('emoji_codes', 'generated/emoji/emoji_codes');
zrequire('emoji');
zrequire('message_store');
zrequire('markdown');
set_global('window', {
@@ -193,15 +194,18 @@ var bugdown_data = JSON.parse(fs.readFileSync(path.join(__dirname, '../../zerver
(function test_message_flags() {
var message = {raw_content: '@**Leo**'};
markdown.apply_markdown(message);
assert(!_.contains(message.flags, 'mentioned'));
assert(!message.mentioned);
assert(!message.mentioned_me_directly);
message = {raw_content: '@**Cordelia Lear**'};
markdown.apply_markdown(message);
assert(_.contains(message.flags, 'mentioned'));
assert(message.mentioned);
assert(message.mentioned_me_directly);
message = {raw_content: '@**all**'};
markdown.apply_markdown(message);
assert(_.contains(message.flags, 'mentioned'));
assert(message.mentioned);
assert(!message.mentioned_me_directly);
}());
(function test_marked() {
@@ -342,44 +346,38 @@ var bugdown_data = JSON.parse(fs.readFileSync(path.join(__dirname, '../../zerver
(function test_message_flags() {
var input = "/me is testing this";
var message = {subject: "No links here", raw_content: input};
message.flags = ['read'];
markdown.apply_markdown(message);
assert.equal(message.is_me_message, true);
assert.equal(message.flags.length, 1);
assert(message.flags.indexOf('read') !== -1);
assert(!message.unread);
input = "testing this @**all** @**Cordelia Lear**";
message = {subject: "No links here", raw_content: input};
markdown.apply_markdown(message);
assert.equal(message.is_me_message, false);
assert.equal(message.flags.length, 1);
assert(message.flags.indexOf('mentioned') !== -1);
assert.equal(message.mentioned, true);
assert.equal(message.mentioned_me_directly, true);
input = "test @all";
message = {subject: "No links here", raw_content: input};
markdown.apply_markdown(message);
assert.equal(message.flags.length, 1);
assert(message.flags.indexOf('mentioned') !== -1);
assert.equal(message.mentioned, true);
input = "test @any";
message = {subject: "No links here", raw_content: input};
markdown.apply_markdown(message);
assert.equal(message.flags.length, 0);
assert(message.flags.indexOf('mentioned') === -1);
assert.equal(message.mentioned, false);
input = "test @*hamletcharacters*";
message = {subject: "No links here", raw_content: input};
markdown.apply_markdown(message);
assert.equal(message.flags.length, 1);
assert(message.flags.indexOf('mentioned') !== -1);
assert.equal(message.mentioned, true);
input = "test @*backend*";
message = {subject: "No links here", raw_content: input};
markdown.apply_markdown(message);
assert.equal(message.flags.length, 0);
assert(message.flags.indexOf('mentioned') === -1);
assert.equal(message.mentioned, false);
}());
(function test_backend_only_realm_filters() {

View File

@@ -183,6 +183,38 @@ global.people.initialize_current_user(me.user_id);
assert.equal(num_partner, 0);
}());
(function test_update_booleans() {
var message = {};
// First, test fields that we do actually want to update.
message.mentioned = false;
message.mentioned_me_directly = false;
message.alerted = false;
var flags = ['mentioned', 'has_alert_word', 'read'];
message_store.update_booleans(message, flags);
assert.equal(message.mentioned, true);
assert.equal(message.mentioned_me_directly, true);
assert.equal(message.alerted, true);
flags = ['read'];
message_store.update_booleans(message, flags);
assert.equal(message.mentioned, false);
assert.equal(message.mentioned_me_directly, false);
assert.equal(message.alerted, false);
// Make sure we don't muck with unread.
message.unread = false;
flags = [''];
message_store.update_booleans(message, flags);
assert.equal(message.unread, false);
message.unread = true;
flags = ['read'];
message_store.update_booleans(message, flags);
assert.equal(message.unread, true);
}());
(function test_message_id_change() {
var message = {
sender_email: 'me@example.com',

View File

@@ -6,6 +6,7 @@ set_global('window', {
});
global.stub_out_jquery();
zrequire('message_store');
zrequire('server_events_dispatch');
zrequire('server_events');

View File

@@ -229,9 +229,7 @@ exports.process_from_server = function process_from_server(messages) {
sent_messages.mark_disparity(message.local_id);
}
// Update our flags based on what the server gave us.
client_message.flags = message.flags;
message_store.set_message_booleans(client_message);
message_store.update_booleans(client_message, message.flags);
// We don't try to highlight alert words locally, so we have to
// do it now. (Note that we will indeed highlight alert words in

View File

@@ -42,16 +42,8 @@ exports.contains_backend_only_syntax = function (content) {
return markedup !== undefined || false_filter_match !== undefined;
};
function push_uniquely(lst, elem) {
if (!_.contains(lst, elem)) {
lst.push(elem);
}
}
exports.apply_markdown = function (message) {
if (message.flags === undefined) {
message.flags = [];
}
message_store.init_booleans(message);
// Our python-markdown processor appends two \n\n to input
var options = {
@@ -59,13 +51,14 @@ exports.apply_markdown = function (message) {
var person = people.get_by_name(name);
if (person !== undefined) {
if (people.is_my_user_id(person.user_id)) {
push_uniquely(message.flags, 'mentioned');
message.mentioned = true;
message.mentioned_me_directly = true;
}
return '<span class="user-mention" data-user-id="' + person.user_id + '">' +
'@' + person.full_name +
'</span>';
} else if (name === 'all' || name === 'everyone') {
push_uniquely(message.flags, 'mentioned');
message.mentioned = true;
return '<span class="user-mention" data-user-id="*">' +
'@' + name +
'</span>';
@@ -76,7 +69,7 @@ exports.apply_markdown = function (message) {
var group = user_groups.get_user_group_from_name(name);
if (group !== undefined) {
if (user_groups.is_member_of(group.id, people.my_current_user_id())) {
push_uniquely(message.flags, 'mentioned');
message.mentioned = true;
}
return '<span class="user-group-mention" data-user-group-id="' + group.id + '">' +
'@' + group.name +

View File

@@ -55,7 +55,6 @@ function maybe_add_narrowed_messages(messages, msg_list, messages_are_new) {
exports.insert_new_messages = function insert_new_messages(messages, locally_echoed) {
_.each(messages, message_store.set_message_booleans);
messages = _.map(messages, message_store.add_message_metadata);
unread.process_loaded_messages(messages);

View File

@@ -107,6 +107,33 @@ exports.set_message_booleans = function (message) {
message.alerted = convert_flag('has_alert_word');
};
exports.init_booleans = function (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;
};
exports.update_booleans = function (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.indexOf(flag_name) >= 0;
}
message.mentioned = convert_flag('mentioned') || convert_flag('wildcard_mentioned');
message.mentioned_me_directly = convert_flag('mentioned');
message.alerted = convert_flag('has_alert_word');
};
exports.add_message_metadata = function (message) {
var cached_msg = stored_messages[message.id];
if (cached_msg !== undefined) {

View File

@@ -95,6 +95,7 @@ function get_events_success(events) {
messages = _.sortBy(messages, 'id');
try {
messages = echo.process_from_server(messages);
_.each(messages, message_store.set_message_booleans);
message_events.insert_new_messages(messages);
} catch (ex2) {
blueslip.error('Failed to insert new messages\n' +