mirror of
https://github.com/zulip/zulip.git
synced 2025-11-06 15:03:34 +00:00
reactions.js: Migrate webapp to use the new reactions API.
Fixes: #6909.
This commit is contained in:
committed by
Tim Abbott
parent
6981ac3d2f
commit
8a4fc9970f
@@ -25,12 +25,21 @@ set_global('emoji', {
|
|||||||
emoji_url: 'TBD',
|
emoji_url: 'TBD',
|
||||||
deactivated: true,
|
deactivated: true,
|
||||||
},
|
},
|
||||||
|
zulip: {
|
||||||
|
emoji_name: 'zulip',
|
||||||
|
emoji_url: 'TBD',
|
||||||
|
deactivated: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
active_realm_emojis: {
|
active_realm_emojis: {
|
||||||
realm_emoji: {
|
realm_emoji: {
|
||||||
emoji_name: 'realm_emoji',
|
emoji_name: 'realm_emoji',
|
||||||
emoji_url: 'TBD',
|
emoji_url: 'TBD',
|
||||||
},
|
},
|
||||||
|
zulip: {
|
||||||
|
emoji_name: 'zulip',
|
||||||
|
emoji_url: 'TBD',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
deactivated_realm_emojis: {
|
deactivated_realm_emojis: {
|
||||||
inactive_realm_emoji: {
|
inactive_realm_emoji: {
|
||||||
@@ -52,6 +61,8 @@ set_global('emoji_codes', {
|
|||||||
name_to_codepoint: {
|
name_to_codepoint: {
|
||||||
alien: '1f47d',
|
alien: '1f47d',
|
||||||
smile: '1f604',
|
smile: '1f604',
|
||||||
|
frown: '1f626',
|
||||||
|
octopus: '1f419',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
set_global('emoji_picker', {
|
set_global('emoji_picker', {
|
||||||
@@ -80,15 +91,15 @@ people.add_in_realm(cali);
|
|||||||
var message = {
|
var message = {
|
||||||
id: 1001,
|
id: 1001,
|
||||||
reactions: [
|
reactions: [
|
||||||
{emoji_name: 'smile', user: {id: 5}, reaction_type: 'unicode_emoji', emoji_code: '1'},
|
{emoji_name: 'smile', user: {id: 5}, reaction_type: 'unicode_emoji', emoji_code: '1f604'},
|
||||||
{emoji_name: 'smile', user: {id: 6}, reaction_type: 'unicode_emoji', emoji_code: '1'},
|
{emoji_name: 'smile', user: {id: 6}, reaction_type: 'unicode_emoji', emoji_code: '1f604'},
|
||||||
{emoji_name: 'frown', user: {id: 7}, reaction_type: 'unicode_emoji', emoji_code: '2'},
|
{emoji_name: 'frown', user: {id: 7}, reaction_type: 'unicode_emoji', emoji_code: '1f626'},
|
||||||
{emoji_name: 'inactive_realm_emoji', user: {id: 5}, reaction_type: 'realm_emoji',
|
{emoji_name: 'inactive_realm_emoji', user: {id: 5}, reaction_type: 'realm_emoji',
|
||||||
emoji_code: '1'},
|
emoji_code: 'inactive_realm_emoji'},
|
||||||
|
|
||||||
// add some bogus user_ids
|
// add some bogus user_ids
|
||||||
{emoji_name: 'octopus', user: {id: 8888}, reaction_type: 'unicode_emoji', emoji_code: '3'},
|
{emoji_name: 'octopus', user: {id: 8888}, reaction_type: 'unicode_emoji', emoji_code: '1f419'},
|
||||||
{emoji_name: 'frown', user: {id: 9999}, reaction_type: 'unicode_emoji', emoji_code: '2'},
|
{emoji_name: 'frown', user: {id: 9999}, reaction_type: 'unicode_emoji', emoji_code: '1f626'},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -141,8 +152,8 @@ set_global('current_msg_list', {
|
|||||||
(function test_basics() {
|
(function test_basics() {
|
||||||
var result = reactions.get_message_reactions(message);
|
var result = reactions.get_message_reactions(message);
|
||||||
|
|
||||||
assert(reactions.current_user_has_reacted_to_emoji(message, 'smile'));
|
assert(reactions.current_user_has_reacted_to_emoji(message, '1f604', 'unicode_emoji'));
|
||||||
assert(!reactions.current_user_has_reacted_to_emoji(message, 'frown'));
|
assert(!reactions.current_user_has_reacted_to_emoji(message, '1f626', 'unicode_emoji'));
|
||||||
|
|
||||||
result.sort(function (a, b) { return a.count - b.count; });
|
result.sort(function (a, b) { return a.count - b.count; });
|
||||||
|
|
||||||
@@ -150,8 +161,8 @@ set_global('current_msg_list', {
|
|||||||
{
|
{
|
||||||
emoji_name: 'frown',
|
emoji_name: 'frown',
|
||||||
reaction_type: 'unicode_emoji',
|
reaction_type: 'unicode_emoji',
|
||||||
emoji_code: '2',
|
emoji_code: '1f626',
|
||||||
emoji_name_css_class: '2',
|
local_id: 'unicode_emoji,frown,1f626',
|
||||||
count: 1,
|
count: 1,
|
||||||
user_ids: [7],
|
user_ids: [7],
|
||||||
title: 'Cali reacted with :frown:',
|
title: 'Cali reacted with :frown:',
|
||||||
@@ -161,8 +172,8 @@ set_global('current_msg_list', {
|
|||||||
{
|
{
|
||||||
emoji_name: 'inactive_realm_emoji',
|
emoji_name: 'inactive_realm_emoji',
|
||||||
reaction_type: 'realm_emoji',
|
reaction_type: 'realm_emoji',
|
||||||
emoji_code: '1',
|
emoji_code: 'inactive_realm_emoji',
|
||||||
emoji_name_css_class: '1',
|
local_id: 'realm_emoji,inactive_realm_emoji,inactive_realm_emoji',
|
||||||
count: 1,
|
count: 1,
|
||||||
user_ids: [5],
|
user_ids: [5],
|
||||||
title: 'You (click to remove) reacted with :inactive_realm_emoji:',
|
title: 'You (click to remove) reacted with :inactive_realm_emoji:',
|
||||||
@@ -174,8 +185,8 @@ set_global('current_msg_list', {
|
|||||||
{
|
{
|
||||||
emoji_name: 'smile',
|
emoji_name: 'smile',
|
||||||
reaction_type: 'unicode_emoji',
|
reaction_type: 'unicode_emoji',
|
||||||
emoji_code: '1',
|
emoji_code: '1f604',
|
||||||
emoji_name_css_class: '1',
|
local_id: 'unicode_emoji,smile,1f604',
|
||||||
count: 2,
|
count: 2,
|
||||||
user_ids: [5, 6],
|
user_ids: [5, 6],
|
||||||
title: 'You (click to remove) and Bob van Roberts reacted with :smile:',
|
title: 'You (click to remove) and Bob van Roberts reacted with :smile:',
|
||||||
@@ -194,8 +205,12 @@ set_global('current_msg_list', {
|
|||||||
global.channel.del = stub.f;
|
global.channel.del = stub.f;
|
||||||
reactions.toggle_emoji_reaction(message_id, emoji_name);
|
reactions.toggle_emoji_reaction(message_id, emoji_name);
|
||||||
var args = stub.get_args('args').args;
|
var args = stub.get_args('args').args;
|
||||||
assert.equal(args.url, '/json/messages/1001/emoji_reactions/smile');
|
assert.equal(args.url, '/json/messages/1001/reactions');
|
||||||
|
assert.deepEqual(args.data, {
|
||||||
|
reaction_type: 'unicode_emoji',
|
||||||
|
emoji_name: 'smile',
|
||||||
|
emoji_code: '1f604',
|
||||||
|
});
|
||||||
// args.success() does nothing; just make sure it doesn't crash
|
// args.success() does nothing; just make sure it doesn't crash
|
||||||
args.success();
|
args.success();
|
||||||
|
|
||||||
@@ -206,10 +221,15 @@ set_global('current_msg_list', {
|
|||||||
|
|
||||||
emoji_name = 'alien'; // not set yet
|
emoji_name = 'alien'; // not set yet
|
||||||
global.with_stub(function (stub) {
|
global.with_stub(function (stub) {
|
||||||
global.channel.put = stub.f;
|
global.channel.post = stub.f;
|
||||||
reactions.toggle_emoji_reaction(message_id, emoji_name);
|
reactions.toggle_emoji_reaction(message_id, emoji_name);
|
||||||
var args = stub.get_args('args').args;
|
var args = stub.get_args('args').args;
|
||||||
assert.equal(args.url, '/json/messages/1001/emoji_reactions/alien');
|
assert.equal(args.url, '/json/messages/1001/reactions');
|
||||||
|
assert.deepEqual(args.data, {
|
||||||
|
reaction_type: 'unicode_emoji',
|
||||||
|
emoji_name: 'alien',
|
||||||
|
emoji_code: '1f47d',
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
emoji_name = 'inactive_realm_emoji'; // Test removing a deactivated realm emoji.
|
emoji_name = 'inactive_realm_emoji'; // Test removing a deactivated realm emoji.
|
||||||
@@ -217,11 +237,36 @@ set_global('current_msg_list', {
|
|||||||
global.channel.del = stub.f;
|
global.channel.del = stub.f;
|
||||||
reactions.toggle_emoji_reaction(message_id, emoji_name);
|
reactions.toggle_emoji_reaction(message_id, emoji_name);
|
||||||
var args = stub.get_args('args').args;
|
var args = stub.get_args('args').args;
|
||||||
assert.equal(args.url, '/json/messages/1001/emoji_reactions/inactive_realm_emoji');
|
assert.equal(args.url, '/json/messages/1001/reactions');
|
||||||
|
assert.deepEqual(args.data, {
|
||||||
|
reaction_type: 'realm_emoji',
|
||||||
|
emoji_name: 'inactive_realm_emoji',
|
||||||
|
emoji_code: 'inactive_realm_emoji',
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
emoji_name = 'unknown-emoji';
|
emoji_name = 'zulip'; // Test adding zulip emoji.
|
||||||
|
global.with_stub(function (stub) {
|
||||||
|
global.channel.post = stub.f;
|
||||||
reactions.toggle_emoji_reaction(message_id, emoji_name);
|
reactions.toggle_emoji_reaction(message_id, emoji_name);
|
||||||
|
var args = stub.get_args('args').args;
|
||||||
|
assert.equal(args.url, '/json/messages/1001/reactions');
|
||||||
|
assert.deepEqual(args.data, {
|
||||||
|
reaction_type: 'zulip_extra_emoji',
|
||||||
|
emoji_name: 'zulip',
|
||||||
|
emoji_code: 'zulip',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var orig_func = global.blueslip.warn;
|
||||||
|
var error_msg;
|
||||||
|
global.blueslip.warn = function (msg) {
|
||||||
|
error_msg = msg;
|
||||||
|
};
|
||||||
|
emoji_name = 'unknown-emoji'; // Test sending an emoji unknown to frontend.
|
||||||
|
reactions.toggle_emoji_reaction(message_id, emoji_name);
|
||||||
|
assert.equal(error_msg, 'Bad emoji name: ' + emoji_name);
|
||||||
|
global.blueslip.warn = orig_func;
|
||||||
}());
|
}());
|
||||||
|
|
||||||
(function test_set_reaction_count() {
|
(function test_set_reaction_count() {
|
||||||
@@ -252,7 +297,9 @@ set_global('current_msg_list', {
|
|||||||
// Insert 8ball for Alice.
|
// Insert 8ball for Alice.
|
||||||
var alice_event = {
|
var alice_event = {
|
||||||
message_id: 1001,
|
message_id: 1001,
|
||||||
|
reaction_type: 'unicode_emoji',
|
||||||
emoji_name: '8ball',
|
emoji_name: '8ball',
|
||||||
|
emoji_code: '1f3b1',
|
||||||
user: {
|
user: {
|
||||||
user_id: alice.user_id,
|
user_id: alice.user_id,
|
||||||
},
|
},
|
||||||
@@ -296,7 +343,9 @@ set_global('current_msg_list', {
|
|||||||
|
|
||||||
var bob_event = {
|
var bob_event = {
|
||||||
message_id: 1001,
|
message_id: 1001,
|
||||||
|
reaction_type: 'unicode_emoji',
|
||||||
emoji_name: '8ball',
|
emoji_name: '8ball',
|
||||||
|
emoji_code: '1f3b1',
|
||||||
user: {
|
user: {
|
||||||
user_id: bob.user_id,
|
user_id: bob.user_id,
|
||||||
},
|
},
|
||||||
@@ -316,7 +365,7 @@ set_global('current_msg_list', {
|
|||||||
};
|
};
|
||||||
|
|
||||||
message_reactions.find = function (selector) {
|
message_reactions.find = function (selector) {
|
||||||
assert.equal(selector, "[data-emoji-name='8ball']");
|
assert.equal(selector, "[data-reaction-id='unicode_emoji,8ball,1f3b1']");
|
||||||
return reaction_element;
|
return reaction_element;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -358,7 +407,9 @@ set_global('current_msg_list', {
|
|||||||
// Now add Cali's realm_emoji reaction.
|
// Now add Cali's realm_emoji reaction.
|
||||||
var cali_event = {
|
var cali_event = {
|
||||||
message_id: 1001,
|
message_id: 1001,
|
||||||
|
reaction_type: 'realm_emoji',
|
||||||
emoji_name: 'realm_emoji',
|
emoji_name: 'realm_emoji',
|
||||||
|
emoji_code: 'realm_emoji',
|
||||||
user: {
|
user: {
|
||||||
user_id: cali.user_id,
|
user_id: cali.user_id,
|
||||||
},
|
},
|
||||||
@@ -384,14 +435,16 @@ set_global('current_msg_list', {
|
|||||||
// And then have Alice update it.
|
// And then have Alice update it.
|
||||||
alice_event = {
|
alice_event = {
|
||||||
message_id: 1001,
|
message_id: 1001,
|
||||||
|
reaction_type: 'realm_emoji',
|
||||||
emoji_name: 'realm_emoji',
|
emoji_name: 'realm_emoji',
|
||||||
|
emoji_code: 'realm_emoji',
|
||||||
user: {
|
user: {
|
||||||
user_id: alice.user_id,
|
user_id: alice.user_id,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
message_reactions.find = function (selector) {
|
message_reactions.find = function (selector) {
|
||||||
assert.equal(selector, "[data-emoji-name='realm_emoji']");
|
assert.equal(selector, "[data-reaction-id='realm_emoji,realm_emoji,realm_emoji']");
|
||||||
return reaction_element;
|
return reaction_element;
|
||||||
};
|
};
|
||||||
reaction_element.prop = function () {};
|
reaction_element.prop = function () {};
|
||||||
@@ -450,7 +503,9 @@ set_global('current_msg_list', {
|
|||||||
|
|
||||||
var alice_8ball_event = {
|
var alice_8ball_event = {
|
||||||
message_id: 2001,
|
message_id: 2001,
|
||||||
|
reaction_type: 'unicode_emoji',
|
||||||
emoji_name: '8ball',
|
emoji_name: '8ball',
|
||||||
|
emoji_code: '1f3b1',
|
||||||
user: {
|
user: {
|
||||||
user_id: alice.user_id,
|
user_id: alice.user_id,
|
||||||
},
|
},
|
||||||
@@ -458,7 +513,9 @@ set_global('current_msg_list', {
|
|||||||
|
|
||||||
var bob_8ball_event = {
|
var bob_8ball_event = {
|
||||||
message_id: 2001,
|
message_id: 2001,
|
||||||
|
reaction_type: 'unicode_emoji',
|
||||||
emoji_name: '8ball',
|
emoji_name: '8ball',
|
||||||
|
emoji_code: '1f3b1',
|
||||||
user: {
|
user: {
|
||||||
user_id: bob.user_id,
|
user_id: bob.user_id,
|
||||||
},
|
},
|
||||||
@@ -466,7 +523,9 @@ set_global('current_msg_list', {
|
|||||||
|
|
||||||
var cali_airplane_event = {
|
var cali_airplane_event = {
|
||||||
message_id: 2001,
|
message_id: 2001,
|
||||||
|
reaction_type: 'unicode_emoji',
|
||||||
emoji_name: 'airplane',
|
emoji_name: 'airplane',
|
||||||
|
emoji_code: '2708',
|
||||||
user: {
|
user: {
|
||||||
user_id: cali.user_id,
|
user_id: cali.user_id,
|
||||||
},
|
},
|
||||||
@@ -481,7 +540,9 @@ set_global('current_msg_list', {
|
|||||||
name: 'insert_new_reaction',
|
name: 'insert_new_reaction',
|
||||||
opts: {
|
opts: {
|
||||||
message_id: 2001,
|
message_id: 2001,
|
||||||
|
reaction_type: 'unicode_emoji',
|
||||||
emoji_name: '8ball',
|
emoji_name: '8ball',
|
||||||
|
emoji_code: '1f3b1',
|
||||||
user_id: alice.user_id,
|
user_id: alice.user_id,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -497,7 +558,9 @@ set_global('current_msg_list', {
|
|||||||
name: 'update_existing_reaction',
|
name: 'update_existing_reaction',
|
||||||
opts: {
|
opts: {
|
||||||
message_id: 2001,
|
message_id: 2001,
|
||||||
|
reaction_type: 'unicode_emoji',
|
||||||
emoji_name: '8ball',
|
emoji_name: '8ball',
|
||||||
|
emoji_code: '1f3b1',
|
||||||
user_id: bob.user_id,
|
user_id: bob.user_id,
|
||||||
user_list: [alice.user_id, bob.user_id],
|
user_list: [alice.user_id, bob.user_id],
|
||||||
},
|
},
|
||||||
@@ -514,7 +577,9 @@ set_global('current_msg_list', {
|
|||||||
name: 'insert_new_reaction',
|
name: 'insert_new_reaction',
|
||||||
opts: {
|
opts: {
|
||||||
message_id: 2001,
|
message_id: 2001,
|
||||||
|
reaction_type: 'unicode_emoji',
|
||||||
emoji_name: 'airplane',
|
emoji_name: 'airplane',
|
||||||
|
emoji_code: '2708',
|
||||||
user_id: cali.user_id,
|
user_id: cali.user_id,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -530,7 +595,9 @@ set_global('current_msg_list', {
|
|||||||
name: 'remove_reaction',
|
name: 'remove_reaction',
|
||||||
opts: {
|
opts: {
|
||||||
message_id: 2001,
|
message_id: 2001,
|
||||||
|
reaction_type: 'unicode_emoji',
|
||||||
emoji_name: '8ball',
|
emoji_name: '8ball',
|
||||||
|
emoji_code: '1f3b1',
|
||||||
user_id: bob.user_id,
|
user_id: bob.user_id,
|
||||||
user_list: [alice.user_id],
|
user_list: [alice.user_id],
|
||||||
},
|
},
|
||||||
@@ -547,7 +614,9 @@ set_global('current_msg_list', {
|
|||||||
name: 'remove_reaction',
|
name: 'remove_reaction',
|
||||||
opts: {
|
opts: {
|
||||||
message_id: 2001,
|
message_id: 2001,
|
||||||
|
reaction_type: 'unicode_emoji',
|
||||||
emoji_name: '8ball',
|
emoji_name: '8ball',
|
||||||
|
emoji_code: '1f3b1',
|
||||||
user_id: alice.user_id,
|
user_id: alice.user_id,
|
||||||
user_list: [],
|
user_list: [],
|
||||||
},
|
},
|
||||||
@@ -575,8 +644,12 @@ set_global('current_msg_list', {
|
|||||||
user_id: 99,
|
user_id: 99,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
reactions.toggle_emoji_reaction(55);
|
|
||||||
|
var original_func = reactions.current_user_has_reacted_to_emoji;
|
||||||
|
reactions.current_user_has_reacted_to_emoji = function () { return true; };
|
||||||
|
reactions.toggle_emoji_reaction(55, bogus_event.emoji_name);
|
||||||
assert.equal(error_msg, 'reactions: Bad message id: 55');
|
assert.equal(error_msg, 'reactions: Bad message id: 55');
|
||||||
|
reactions.current_user_has_reacted_to_emoji = original_func;
|
||||||
|
|
||||||
error_msg = undefined;
|
error_msg = undefined;
|
||||||
reactions.add_reaction(bogus_event);
|
reactions.add_reaction(bogus_event);
|
||||||
@@ -585,3 +658,50 @@ set_global('current_msg_list', {
|
|||||||
reactions.remove_reaction(bogus_event);
|
reactions.remove_reaction(bogus_event);
|
||||||
assert.equal(error_msg, undefined);
|
assert.equal(error_msg, undefined);
|
||||||
}());
|
}());
|
||||||
|
|
||||||
|
(function test_local_reaction_id() {
|
||||||
|
var reaction_info = {
|
||||||
|
reaction_type: 'unicode_emoji',
|
||||||
|
emoji_name: 'thumbs_up',
|
||||||
|
emoji_code: '1f44d',
|
||||||
|
};
|
||||||
|
var local_id = reactions.get_local_reaction_id(reaction_info);
|
||||||
|
assert.equal(local_id, 'unicode_emoji,thumbs_up,1f44d');
|
||||||
|
|
||||||
|
var reverse_info = reactions.get_reaction_info(local_id);
|
||||||
|
assert.deepEqual(reverse_info, reaction_info);
|
||||||
|
}());
|
||||||
|
|
||||||
|
(function test_process_reaction_click() {
|
||||||
|
var message_id = 1001;
|
||||||
|
var expected_reaction_info = {
|
||||||
|
reaction_type: 'unicode_emoji',
|
||||||
|
emoji_name: '8ball',
|
||||||
|
emoji_code: '1f3b1',
|
||||||
|
};
|
||||||
|
global.message_store.get = function (message_id) {
|
||||||
|
assert.equal(message_id, 1001);
|
||||||
|
return message;
|
||||||
|
};
|
||||||
|
|
||||||
|
global.with_stub(function (stub) {
|
||||||
|
global.channel.post = stub.f;
|
||||||
|
reactions.process_reaction_click(message_id, 'unicode_emoji,8ball,1f3b1');
|
||||||
|
var args = stub.get_args('args').args;
|
||||||
|
assert.equal(args.url, '/json/messages/1001/reactions');
|
||||||
|
assert.deepEqual(args.data, expected_reaction_info);
|
||||||
|
});
|
||||||
|
|
||||||
|
expected_reaction_info = {
|
||||||
|
reaction_type: 'unicode_emoji',
|
||||||
|
emoji_name: 'smile',
|
||||||
|
emoji_code: '1f604',
|
||||||
|
};
|
||||||
|
global.with_stub(function (stub) {
|
||||||
|
global.channel.del = stub.f;
|
||||||
|
reactions.process_reaction_click(message_id, 'unicode_emoji,smile,1f604');
|
||||||
|
var args = stub.get_args('args').args;
|
||||||
|
assert.equal(args.url, '/json/messages/1001/reactions');
|
||||||
|
assert.deepEqual(args.data, expected_reaction_info);
|
||||||
|
});
|
||||||
|
}());
|
||||||
|
|||||||
@@ -852,7 +852,10 @@ function render(template_name, args) {
|
|||||||
|
|
||||||
(function message_reaction() {
|
(function message_reaction() {
|
||||||
var args = {
|
var args = {
|
||||||
|
class: 'message_reaction',
|
||||||
emoji_name: 'smile',
|
emoji_name: 'smile',
|
||||||
|
emoji_code: '1f604',
|
||||||
|
local_id: 'unicode_emoji,smile,1f604',
|
||||||
message_id: '1',
|
message_id: '1',
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -861,8 +864,10 @@ function render(template_name, args) {
|
|||||||
html += render('message_reaction', args);
|
html += render('message_reaction', args);
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
|
var reaction = $(html).find(".message_reaction");
|
||||||
|
assert.equal(reaction.data("reaction-id"), "unicode_emoji,smile,1f604");
|
||||||
|
assert(reaction.find(".emoji").hasClass("emoji-1f604"));
|
||||||
global.write_handlebars_output("message_reaction", html);
|
global.write_handlebars_output("message_reaction", html);
|
||||||
assert($(html).find(".message_reaction").has(".emoji .emoji-smile"));
|
|
||||||
}());
|
}());
|
||||||
|
|
||||||
(function more_topics() {
|
(function more_topics() {
|
||||||
|
|||||||
@@ -178,9 +178,9 @@ $(function () {
|
|||||||
|
|
||||||
$("#main_div").on("click", ".message_reaction", function (e) {
|
$("#main_div").on("click", ".message_reaction", function (e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
var emoji_name = $(this).attr('data-emoji-name');
|
var local_id = $(this).attr('data-reaction-id');
|
||||||
var message_id = rows.get_message_id(this);
|
var message_id = rows.get_message_id(this);
|
||||||
reactions.toggle_emoji_reaction(message_id, emoji_name);
|
reactions.process_reaction_click(message_id, local_id);
|
||||||
});
|
});
|
||||||
|
|
||||||
$("#main_div").on("click", "a.stream", function (e) {
|
$("#main_div").on("click", "a.stream", function (e) {
|
||||||
|
|||||||
@@ -3,6 +3,21 @@ var exports = {};
|
|||||||
|
|
||||||
exports.view = {}; // function namespace
|
exports.view = {}; // function namespace
|
||||||
|
|
||||||
|
exports.get_local_reaction_id = function (reaction_info) {
|
||||||
|
return [reaction_info.reaction_type,
|
||||||
|
reaction_info.emoji_name,
|
||||||
|
reaction_info.emoji_code].join(',');
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.get_reaction_info = function (reaction_id) {
|
||||||
|
var reaction_info = reaction_id.split(',');
|
||||||
|
return {
|
||||||
|
reaction_type: reaction_info[0],
|
||||||
|
emoji_name: reaction_info[1],
|
||||||
|
emoji_code: reaction_info[2],
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
exports.open_reactions_popover = function () {
|
exports.open_reactions_popover = function () {
|
||||||
var message = current_msg_list.selected_message();
|
var message = current_msg_list.selected_message();
|
||||||
var target = $(current_msg_list.selected_row()).find(".actions_hover")[0];
|
var target = $(current_msg_list.selected_row()).find(".actions_hover")[0];
|
||||||
@@ -13,38 +28,37 @@ exports.open_reactions_popover = function () {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
function should_send_reaction(emoji_name, operation) {
|
exports.current_user_has_reacted_to_emoji = function (message, emoji_code, type) {
|
||||||
// If a default emoji with this name exists then always send it irrespective
|
var user_id = page_params.user_id;
|
||||||
// of whether a realm emoji with this name exists or not.
|
return _.any(message.reactions, function (r) {
|
||||||
if (!emoji_codes.name_to_codepoint.hasOwnProperty(emoji_name)) {
|
return (r.user.id === user_id) &&
|
||||||
// When the user attempts to add a reaction for a given emoji
|
(r.reaction_type === type) &&
|
||||||
// name, and a built-in emoji with this name doesn't exist,
|
(r.emoji_code === emoji_code);
|
||||||
// then send the request only if there is an active realm
|
});
|
||||||
// emoji with this name.
|
};
|
||||||
//
|
|
||||||
// This behavior isn't exactly correct: A user should be add
|
|
||||||
// their support to an emoji reaction for a deactivated (no
|
|
||||||
// longer available for new messages) realm emoji, but more
|
|
||||||
// backend work is required to support that anyway.
|
|
||||||
if (operation === "add") {
|
|
||||||
return emoji.active_realm_emojis.hasOwnProperty(emoji_name);
|
|
||||||
}
|
|
||||||
// While removing a reaction and a default emoji with this name doesn't
|
|
||||||
// exist then send the request if there is any realm emoji with this name
|
|
||||||
// whether active or inactive.
|
|
||||||
return emoji.all_realm_emojis.hasOwnProperty(emoji_name);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function send_reaction_ajax(message_id, emoji_name, operation) {
|
function get_message(message_id) {
|
||||||
if (!should_send_reaction(emoji_name, operation)) {
|
var message = message_store.get(message_id);
|
||||||
// Emoji doesn't exist
|
if (!message) {
|
||||||
|
blueslip.error('reactions: Bad message id: ' + message_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
function send_reaction_ajax(message_id, reaction_info) {
|
||||||
|
var message = get_message(message_id);
|
||||||
|
var has_reacted = exports.current_user_has_reacted_to_emoji(
|
||||||
|
message,
|
||||||
|
reaction_info.emoji_code,
|
||||||
|
reaction_info.reaction_type
|
||||||
|
);
|
||||||
|
var operation = has_reacted ? 'remove' : 'add';
|
||||||
|
|
||||||
var args = {
|
var args = {
|
||||||
url: '/json/messages/' + message_id + '/emoji_reactions/' + encodeURIComponent(emoji_name),
|
url: '/json/messages/' + message_id + '/reactions',
|
||||||
data: {},
|
data: reaction_info,
|
||||||
success: function () {},
|
success: function () {},
|
||||||
error: function (xhr) {
|
error: function (xhr) {
|
||||||
var response = channel.xhr_error_message("Error sending reaction", xhr);
|
var response = channel.xhr_error_message("Error sending reaction", xhr);
|
||||||
@@ -57,56 +71,55 @@ function send_reaction_ajax(message_id, emoji_name, operation) {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
if (operation === 'add') {
|
if (operation === 'add') {
|
||||||
channel.put(args);
|
channel.post(args);
|
||||||
} else if (operation === 'remove') {
|
} else if (operation === 'remove') {
|
||||||
channel.del(args);
|
channel.del(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.current_user_has_reacted_to_emoji = function (message, emoji_name) {
|
function get_user_list_for_message_reaction(message, local_id) {
|
||||||
var user_id = page_params.user_id;
|
|
||||||
return _.any(message.reactions, function (r) {
|
|
||||||
return (r.user.id === user_id) && (r.emoji_name === emoji_name);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function get_user_list_for_message_reaction(message, emoji_name) {
|
|
||||||
var matching_reactions = message.reactions.filter(function (reaction) {
|
var matching_reactions = message.reactions.filter(function (reaction) {
|
||||||
return reaction.emoji_name === emoji_name;
|
return reaction.local_id === local_id;
|
||||||
});
|
});
|
||||||
return matching_reactions.map(function (reaction) {
|
return matching_reactions.map(function (reaction) {
|
||||||
return reaction.user.id;
|
return reaction.user.id;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_message(message_id) {
|
|
||||||
var message = message_store.get(message_id);
|
|
||||||
if (!message) {
|
|
||||||
blueslip.error('reactions: Bad message id: ' + message_id);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.toggle_emoji_reaction = function (message_id, emoji_name) {
|
exports.toggle_emoji_reaction = function (message_id, emoji_name) {
|
||||||
// This toggles the current user's reaction to the clicked emoji.
|
// This toggles the current user's reaction to the clicked emoji.
|
||||||
|
var reaction_info = {
|
||||||
|
emoji_name: emoji_name,
|
||||||
|
};
|
||||||
|
|
||||||
var message = get_message(message_id);
|
if (emoji.all_realm_emojis.hasOwnProperty(emoji_name)) {
|
||||||
if (!message) {
|
if (emoji_name === 'zulip') {
|
||||||
|
reaction_info.reaction_type = 'zulip_extra_emoji';
|
||||||
|
} else {
|
||||||
|
reaction_info.reaction_type = 'realm_emoji';
|
||||||
|
}
|
||||||
|
reaction_info.emoji_code = emoji_name;
|
||||||
|
} else if (emoji_codes.name_to_codepoint.hasOwnProperty(emoji_name)) {
|
||||||
|
reaction_info.reaction_type = 'unicode_emoji';
|
||||||
|
reaction_info.emoji_code = emoji_codes.name_to_codepoint[emoji_name];
|
||||||
|
} else {
|
||||||
|
blueslip.warn('Bad emoji name: ' + emoji_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var has_reacted = exports.current_user_has_reacted_to_emoji(message, emoji_name);
|
send_reaction_ajax(message_id, reaction_info);
|
||||||
var operation = has_reacted ? 'remove' : 'add';
|
|
||||||
|
|
||||||
send_reaction_ajax(message_id, emoji_name, operation);
|
|
||||||
|
|
||||||
// The next line isn't always necessary, but it is harmless/quick
|
// The next line isn't always necessary, but it is harmless/quick
|
||||||
// when no popovers are there.
|
// when no popovers are there.
|
||||||
emoji_picker.hide_emoji_popover();
|
emoji_picker.hide_emoji_popover();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.process_reaction_click = function (message_id, local_id) {
|
||||||
|
var reaction_info = exports.get_reaction_info(local_id);
|
||||||
|
|
||||||
|
send_reaction_ajax(message_id, reaction_info);
|
||||||
|
};
|
||||||
|
|
||||||
function full_name(user_id) {
|
function full_name(user_id) {
|
||||||
if (user_id === page_params.user_id) {
|
if (user_id === page_params.user_id) {
|
||||||
return 'You (click to remove)';
|
return 'You (click to remove)';
|
||||||
@@ -135,9 +148,9 @@ exports.get_reaction_section = function (message_id) {
|
|||||||
return section;
|
return section;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.find_reaction = function (message_id, emoji_name) {
|
exports.find_reaction = function (message_id, local_id) {
|
||||||
var reaction_section = exports.get_reaction_section(message_id);
|
var reaction_section = exports.get_reaction_section(message_id);
|
||||||
var reaction = reaction_section.find("[data-emoji-name='" + emoji_name + "']");
|
var reaction = reaction_section.find("[data-reaction-id='" + local_id + "']");
|
||||||
return reaction;
|
return reaction;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -154,9 +167,8 @@ exports.set_reaction_count = function (reaction, count) {
|
|||||||
|
|
||||||
exports.add_reaction = function (event) {
|
exports.add_reaction = function (event) {
|
||||||
var message_id = event.message_id;
|
var message_id = event.message_id;
|
||||||
var emoji_name = event.emoji_name;
|
|
||||||
|
|
||||||
var message = message_store.get(message_id);
|
var message = message_store.get(message_id);
|
||||||
|
|
||||||
if (message === undefined) {
|
if (message === undefined) {
|
||||||
// If we don't have the message in cache, do nothing; if we
|
// If we don't have the message in cache, do nothing; if we
|
||||||
// ever fetch it from the server, it'll come with the
|
// ever fetch it from the server, it'll come with the
|
||||||
@@ -165,24 +177,24 @@ exports.add_reaction = function (event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
event.user.id = event.user.user_id;
|
event.user.id = event.user.user_id;
|
||||||
|
event.local_id = exports.get_local_reaction_id(event);
|
||||||
|
|
||||||
message.reactions.push(event);
|
message.reactions.push(event);
|
||||||
|
|
||||||
var user_list = get_user_list_for_message_reaction(message, emoji_name);
|
var user_list = get_user_list_for_message_reaction(message, event.local_id);
|
||||||
|
var opts = {
|
||||||
|
message_id: event.message_id,
|
||||||
|
reaction_type: event.reaction_type,
|
||||||
|
emoji_name: event.emoji_name,
|
||||||
|
emoji_code: event.emoji_code,
|
||||||
|
user_id: event.user.id,
|
||||||
|
};
|
||||||
|
|
||||||
if (user_list.length > 1) {
|
if (user_list.length > 1) {
|
||||||
exports.view.update_existing_reaction({
|
opts.user_list = user_list;
|
||||||
message_id: event.message_id,
|
exports.view.update_existing_reaction(opts);
|
||||||
emoji_name: event.emoji_name,
|
|
||||||
user_list: user_list,
|
|
||||||
user_id: event.user.id,
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
exports.view.insert_new_reaction({
|
exports.view.insert_new_reaction(opts);
|
||||||
message_id: event.message_id,
|
|
||||||
emoji_name: event.emoji_name,
|
|
||||||
user_id: event.user.id,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -195,8 +207,8 @@ exports.view.update_existing_reaction = function (opts) {
|
|||||||
var emoji_name = opts.emoji_name;
|
var emoji_name = opts.emoji_name;
|
||||||
var user_list = opts.user_list;
|
var user_list = opts.user_list;
|
||||||
var user_id = opts.user_id;
|
var user_id = opts.user_id;
|
||||||
|
var local_id = exports.get_local_reaction_id(opts);
|
||||||
var reaction = exports.find_reaction(message_id, emoji_name);
|
var reaction = exports.find_reaction(message_id, local_id);
|
||||||
|
|
||||||
exports.set_reaction_count(reaction, user_list.length);
|
exports.set_reaction_count(reaction, user_list.length);
|
||||||
|
|
||||||
@@ -216,25 +228,27 @@ exports.view.insert_new_reaction = function (opts) {
|
|||||||
|
|
||||||
var message_id = opts.message_id;
|
var message_id = opts.message_id;
|
||||||
var emoji_name = opts.emoji_name;
|
var emoji_name = opts.emoji_name;
|
||||||
|
var emoji_code = opts.emoji_code;
|
||||||
var user_id = opts.user_id;
|
var user_id = opts.user_id;
|
||||||
var user_list = [user_id];
|
var user_list = [user_id];
|
||||||
|
|
||||||
var context = {
|
var context = {
|
||||||
message_id: message_id,
|
message_id: message_id,
|
||||||
emoji_name: emoji_name,
|
emoji_name: emoji_name,
|
||||||
|
emoji_code: emoji_code,
|
||||||
};
|
};
|
||||||
|
|
||||||
var new_title = generate_title(emoji_name, user_list);
|
var new_title = generate_title(emoji_name, user_list);
|
||||||
|
|
||||||
if (emoji.active_realm_emojis[emoji_name]) {
|
if (opts.reaction_type !== 'unicode_emoji') {
|
||||||
context.is_realm_emoji = true;
|
context.is_realm_emoji = true;
|
||||||
context.url = emoji.active_realm_emojis[emoji_name].emoji_url;
|
context.url = emoji.all_realm_emojis[emoji_code].emoji_url;
|
||||||
}
|
}
|
||||||
|
|
||||||
context.count = 1;
|
context.count = 1;
|
||||||
context.title = new_title;
|
context.title = new_title;
|
||||||
context.emoji_alt_code = page_params.emoji_alt_code;
|
context.emoji_alt_code = page_params.emoji_alt_code;
|
||||||
context.emoji_name_css_class = emoji.emojis_name_to_css_class[emoji_name];
|
context.local_id = exports.get_local_reaction_id(opts);
|
||||||
|
|
||||||
if (opts.user_id === page_params.user_id) {
|
if (opts.user_id === page_params.user_id) {
|
||||||
context.class = "message_reaction reacted";
|
context.class = "message_reaction reacted";
|
||||||
@@ -250,11 +264,14 @@ exports.view.insert_new_reaction = function (opts) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
exports.remove_reaction = function (event) {
|
exports.remove_reaction = function (event) {
|
||||||
|
var reaction_type = event.reaction_type;
|
||||||
var emoji_name = event.emoji_name;
|
var emoji_name = event.emoji_name;
|
||||||
|
var emoji_code = event.emoji_code;
|
||||||
var message_id = event.message_id;
|
var message_id = event.message_id;
|
||||||
var user_id = event.user.user_id;
|
var user_id = event.user.user_id;
|
||||||
var i = -1;
|
var i = -1;
|
||||||
var message = message_store.get(message_id);
|
var message = message_store.get(message_id);
|
||||||
|
var local_id = exports.get_local_reaction_id(event);
|
||||||
|
|
||||||
if (message === undefined) {
|
if (message === undefined) {
|
||||||
// If we don't have the message in cache, do nothing; if we
|
// If we don't have the message in cache, do nothing; if we
|
||||||
@@ -266,7 +283,7 @@ exports.remove_reaction = function (event) {
|
|||||||
// Do the data part first:
|
// Do the data part first:
|
||||||
// Remove reactions from our message object.
|
// Remove reactions from our message object.
|
||||||
_.each(message.reactions, function (reaction, index) {
|
_.each(message.reactions, function (reaction, index) {
|
||||||
if (reaction.emoji_name === emoji_name && reaction.user.id === user_id) {
|
if (reaction.local_id === local_id && reaction.user.id === user_id) {
|
||||||
i = index;
|
i = index;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -276,11 +293,13 @@ exports.remove_reaction = function (event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Compute the new user list for this reaction.
|
// Compute the new user list for this reaction.
|
||||||
var user_list = get_user_list_for_message_reaction(message, emoji_name);
|
var user_list = get_user_list_for_message_reaction(message, local_id);
|
||||||
|
|
||||||
exports.view.remove_reaction({
|
exports.view.remove_reaction({
|
||||||
message_id: message_id,
|
message_id: message_id,
|
||||||
|
reaction_type: reaction_type,
|
||||||
emoji_name: emoji_name,
|
emoji_name: emoji_name,
|
||||||
|
emoji_code: emoji_code,
|
||||||
user_list: user_list,
|
user_list: user_list,
|
||||||
user_id: user_id,
|
user_id: user_id,
|
||||||
});
|
});
|
||||||
@@ -292,8 +311,8 @@ exports.view.remove_reaction = function (opts) {
|
|||||||
var emoji_name = opts.emoji_name;
|
var emoji_name = opts.emoji_name;
|
||||||
var user_list = opts.user_list;
|
var user_list = opts.user_list;
|
||||||
var user_id = opts.user_id;
|
var user_id = opts.user_id;
|
||||||
|
var local_id = exports.get_local_reaction_id(opts);
|
||||||
var reaction = exports.find_reaction(message_id, emoji_name);
|
var reaction = exports.find_reaction(message_id, local_id);
|
||||||
|
|
||||||
if (user_list.length === 0) {
|
if (user_list.length === 0) {
|
||||||
// If this user was the only one reacting for this emoji, we simply
|
// If this user was the only one reacting for this emoji, we simply
|
||||||
@@ -331,6 +350,7 @@ exports.get_message_reactions = function (message) {
|
|||||||
var message_reactions = new Dict();
|
var message_reactions = new Dict();
|
||||||
_.each(message.reactions, function (reaction) {
|
_.each(message.reactions, function (reaction) {
|
||||||
var user_id = reaction.user.id;
|
var user_id = reaction.user.id;
|
||||||
|
reaction.local_id = exports.get_local_reaction_id(reaction);
|
||||||
if (!people.is_known_user_id(user_id)) {
|
if (!people.is_known_user_id(user_id)) {
|
||||||
blueslip.warn('Unknown user_id ' + user_id +
|
blueslip.warn('Unknown user_id ' + user_id +
|
||||||
'in reaction for message ' + message.id);
|
'in reaction for message ' + message.id);
|
||||||
@@ -338,14 +358,17 @@ exports.get_message_reactions = function (message) {
|
|||||||
}
|
}
|
||||||
reaction.user_ids = [];
|
reaction.user_ids = [];
|
||||||
var collapsed_reaction = message_reactions.setdefault(
|
var collapsed_reaction = message_reactions.setdefault(
|
||||||
reaction.emoji_name,
|
reaction.local_id,
|
||||||
_.omit(reaction, 'user')
|
_.omit(reaction, 'user')
|
||||||
);
|
);
|
||||||
collapsed_reaction.user_ids.push(user_id);
|
collapsed_reaction.user_ids.push(user_id);
|
||||||
});
|
});
|
||||||
var reactions = message_reactions.items().map(function (item) {
|
var reactions = message_reactions.items().map(function (item) {
|
||||||
var reaction = item[1];
|
var reaction = item[1];
|
||||||
reaction.emoji_name_css_class = reaction.emoji_code;
|
reaction.local_id = reaction.local_id;
|
||||||
|
reaction.reaction_type = reaction.reaction_type;
|
||||||
|
reaction.emoji_name = reaction.emoji_name;
|
||||||
|
reaction.emoji_code = reaction.emoji_code;
|
||||||
reaction.count = reaction.user_ids.length;
|
reaction.count = reaction.user_ids.length;
|
||||||
reaction.title = generate_title(reaction.emoji_name, reaction.user_ids);
|
reaction.title = generate_title(reaction.emoji_name, reaction.user_ids);
|
||||||
reaction.emoji_alt_code = page_params.emoji_alt_code;
|
reaction.emoji_alt_code = page_params.emoji_alt_code;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<div class="{{this.class}}" title="{{this.title}}" data-emoji-name="{{this.emoji_name}}">
|
<div class="{{this.class}}" title="{{this.title}}" data-reaction-id={{this.local_id}}>
|
||||||
{{#if this.emoji_alt_code}}
|
{{#if this.emoji_alt_code}}
|
||||||
<div class="emoji_alt_code"> :{{this.emoji_name}}:</div>
|
<div class="emoji_alt_code"> :{{this.emoji_name}}:</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if this.is_realm_emoji}}
|
{{#if this.is_realm_emoji}}
|
||||||
<img src="{{this.url}}" class="emoji" />
|
<img src="{{this.url}}" class="emoji" />
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="emoji emoji-{{this.emoji_name_css_class}}" />
|
<div class="emoji emoji-{{this.emoji_code}}" />
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<div class="message_reaction_count">{{this.count}}</div>
|
<div class="message_reaction_count">{{this.count}}</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user