Split out new module people.js for tracking people.

(imported from commit fb9b769819ade25d1d3d6e452e68c7ee8651cfdd)
This commit is contained in:
Tim Abbott
2014-01-30 16:42:19 -05:00
parent d0ae8795c3
commit e505583f52
12 changed files with 215 additions and 171 deletions

View File

@@ -67,7 +67,7 @@ exports.full_huddle_name = function (huddle) {
var emails = huddle.split(',');
var names = _.map(emails, function (email) {
var person = people_dict.get(email);
var person = people.get_by_email(email);
return person ? person.full_name : email;
});
@@ -79,7 +79,7 @@ exports.short_huddle_name = function (huddle) {
var num_to_show = 3;
var names = _.map(emails.slice(0, num_to_show), function (email) {
var person = people_dict.get(email);
var person = people.get_by_email(email);
return person ? person.full_name : email;
});
var others = emails.length - num_to_show;
@@ -127,11 +127,11 @@ function sort_users(users, presence_info) {
// Sort equivalent PM names alphabetically
var full_name_a = a;
var full_name_b = b;
if (people_dict.has(a)) {
full_name_a = people_dict.get(a).full_name;
if (people.get_by_email(a)) {
full_name_a = people.get_by_email(a).full_name;
}
if (people_dict.has(b)) {
full_name_b = people_dict.get(b).full_name;
if (people.get_by_email(b)) {
full_name_b = people.get_by_email(b).full_name;
}
return util.strcmp(full_name_a, full_name_b);
});
@@ -163,7 +163,7 @@ function filter_users_by_search(users) {
});
var filtered_users = _.filter(users, function (user) {
var person = people_dict.get(user);
var person = people.get_by_email(user);
if (!person || !person.full_name) {
return false;
}
@@ -189,7 +189,7 @@ function actually_update_users() {
var users = Object.keys(presence_info);
users = filter_users_by_search(users);
users = _.filter(users, function (email) {
return people_dict.has(email);
return people.get_by_email(email);
});
users = sort_users(users, presence_info);
@@ -208,7 +208,7 @@ function actually_update_users() {
function info_for(email) {
var presence = presence_info[email];
return {
name: people_dict.get(email).full_name,
name: people.get_by_email(email).full_name,
email: email,
num_unread: get_num_unread(email),
type: presence,

View File

@@ -111,7 +111,7 @@ exports.would_receive_message = function (email) {
}
if (focused_recipient.type === 'stream') {
var user = realm_people_dict.get(email);
var user = people.realm_get(email);
var sub = stream_data.get_sub(focused_recipient.stream);
if (user && sub && user.is_bot && !sub.invite_only) {
// Bots may receive messages on public streams even if they are

View File

@@ -149,7 +149,7 @@ function insert_local_message(message_request, local_id) {
var emails = message_request.private_message_recipient.split(',');
message.display_recipient = _.map(emails, function (email) {
email = email.trim();
var person = people_dict.get(email);
var person = people.get_by_email(email);
if (person !== undefined) {
return person;
}
@@ -239,8 +239,8 @@ exports.process_from_server = function process_from_server(messages) {
if (client_message.display_reply_to !== reply_to) {
client_message.display_reply_to = reply_to;
_.each(message.display_recipient, function (person) {
if (people_dict.get(person.email).full_name !== person.full_name) {
reify_person(person);
if (people.get_by_email(person.email).full_name !== person.full_name) {
people.reify(person);
}
});
updated = true;
@@ -308,8 +308,8 @@ function handleEmoji(emoji_name) {
}
function handleUserMentions(username) {
if (people_by_name_dict.get(username)) {
var person = people_by_name_dict.get(username);
var person = people.get_by_name(username);
if (person !== undefined) {
return '<span class="user-mention" data-user-email="' + person.email + '">' +
'@' + person.full_name + '</span>';
} else if (username === 'all' || username === 'everyone') {

163
static/js/people.js Normal file
View File

@@ -0,0 +1,163 @@
var people = (function () {
var exports = {};
// The following three Dicts point to the same objects
// All people we've seen
var people_dict = new Dict();
var people_by_name_dict = new Dict();
// People in this realm
var realm_people_dict = new Dict();
exports.get_by_email = function get_by_email(email) {
return people_dict.get(email);
};
exports.realm_get = function realm_get(email) {
return realm_people_dict.get(email);
};
exports.get_by_name = function realm_get(name) {
return people_by_name_dict.get(name);
};
// TODO: Replace these with the tests setting up page_params before
// loading people.js
exports.test_set_people_dict = function (data) {
people_dict = new Dict.from(data);
};
exports.test_set_people_name_dict = function (data) {
people_by_name_dict = new Dict.from(data);
};
function people_cmp(person1, person2) {
// Compares objects of the form used in people_list.
var name_cmp = util.strcmp(person1.full_name, person2.full_name);
if (name_cmp < 0) {
return -1;
} else if (name_cmp > 0) {
return 1;
}
return util.strcmp(person1.email, person2.email);
}
exports.get_rest_of_realm = function get_rest_of_realm() {
var people_minus_you = [];
realm_people_dict.each(function (person) {
if (person.email !== page_params.email) {
people_minus_you.push({"email": person.email,
"full_name": person.full_name});
}
});
return people_minus_you.sort(people_cmp);
};
exports.add = function add(person, in_realm) {
page_params.people_list.push(person);
people_dict.set(person.email, person);
people_by_name_dict.set(person.full_name, person);
person.pm_recipient_count = 0;
};
exports.add_in_realm = function add_in_realm(person) {
realm_people_dict.set(person.email, person);
exports.add(person);
};
exports.remove = function remove(person) {
var i;
for (i = 0; i < page_params.people_list.length; i++) {
if (page_params.people_list[i].email === person.email) {
page_params.people_list.splice(i, 1);
break;
}
}
people_dict.del(person.email);
people_by_name_dict.del(person.full_name);
realm_people_dict.del(person.email);
};
exports.reify = function reify(person) {
// If a locally sent message is a PM to
// an out-of-realm recipient, a people_dict
// entry is created with simply an email address
// Once we've received the full person object, replace
// it
if (! people_dict.has(person.email)) {
return;
}
var old_person = people_dict.get(person.email);
var old_idx = page_params.people_list.indexOf(old_person);
var new_person = _.extend({}, old_person, person);
people_dict.set(person.email, person);
people_by_name_dict.set(person.full_name, person);
page_params.people_list[old_idx] = new_person;
if (people_by_name_dict.has(person.email)) {
people_by_name_dict.del(person.email);
}
};
exports.update = function update(person) {
// Currently the only attribute that can change is full_name, so
// we just push out changes to that field. As we add more things
// that can change, this will need to either get complicated or be
// replaced by MVC
if (! people_dict.has(person.email)) {
blueslip.error("Got update_person event for unexpected user",
{email: person.email});
return;
}
var person_obj = people_dict.get(person.email);
if (_.has(person, 'full_name')) {
if (people_by_name_dict.has(person_obj.full_name)) {
people_by_name_dict.set(person.full_name, person_obj);
people_by_name_dict.del(person_obj.full_name);
}
person_obj.full_name = person.full_name;
if (person.email === page_params.email) {
page_params.fullname = person.full_name;
}
}
if (_.has(person, 'is_admin')) {
person_obj.is_admin = person.is_admin;
if (person.email === page_params.email) {
page_params.is_admin = person.is_admin;
admin.show_or_hide_menu_item();
}
}
activity.set_user_statuses([]);
// TODO: update sender names on messages
};
$(function () {
_.each(page_params.people_list, function (person) {
people_dict.set(person.email, person);
people_by_name_dict.set(person.full_name, person);
realm_people_dict.set(person.email, person);
person.pm_recipient_count = 0;
});
// The special account feedback@zulip.com is used for in-app
// feedback and should always show up as an autocomplete option.
if (! people.get_by_email('feedback@zulip.com')) {
exports.add({"email": "feedback@zulip.com",
"full_name": "Zulip Feedback Bot"});
}
});
return exports;
}());
if (typeof module !== 'undefined') {
module.exports = people;
}

View File

@@ -63,11 +63,11 @@ function get_events_success(events) {
break;
case 'realm_user':
if (event.op === 'add') {
add_person_in_realm(event.person);
people.add_in_realm(event.person);
} else if (event.op === 'remove') {
remove_person(event.person);
people.remove(event.person);
} else if (event.op === 'update') {
update_person(event.person);
people.update(event.person);
}
break;
case 'stream':

View File

@@ -548,17 +548,6 @@ function ajaxSubscribeForCreation(stream, principals, invite_only, announce) {
});
}
function people_cmp(person1, person2) {
// Compares objects of the form used in people_list.
var name_cmp = util.strcmp(person1.full_name, person2.full_name);
if (name_cmp < 0) {
return -1;
} else if (name_cmp > 0) {
return 1;
}
return util.strcmp(person1.email, person2.email);
}
// Within the new stream modal...
function update_announce_stream_state() {
// If the stream is invite only, or everyone's added, disable
@@ -579,16 +568,8 @@ function update_announce_stream_state() {
}
function show_new_stream_modal() {
var people_minus_you_and_internal_users = [];
realm_people_dict.each(function (person) {
if (person.email !== page_params.email) {
people_minus_you_and_internal_users.push({"email": person.email,
"full_name": person.full_name});
}
});
$('#people_to_add').html(templates.render('new_stream_users', {
users: people_minus_you_and_internal_users.sort(people_cmp)
users: people.get_rest_of_realm()
}));
// Make the options default to the same each time:
@@ -797,7 +778,7 @@ $(function () {
// mark_subscribed adds the user to the member list
mark_subscribed(stream);
} else {
add_to_member_list(list, people_dict.get(principal).full_name, principal);
add_to_member_list(list, people.get_by_email(principal).full_name, principal);
}
} else {
error_elem.addClass("hide");
@@ -961,11 +942,11 @@ $(function () {
success: function (data) {
util.destroy_loading_indicator(indicator_elem);
var subscribers = _.map(data.subscribers, function (elem) {
var person = people_dict.get(elem);
var person = people.get_by_email(elem);
if (person === undefined) {
return elem;
}
return format_member_list_elem(people_dict.get(elem).full_name, elem);
return format_member_list_elem(people.get_by_email(elem).full_name, elem);
});
_.each(subscribers.sort().reverse(), function (elem) {
// add_element_to_member_list *prepends* the element,

View File

@@ -50,10 +50,10 @@ function make_tab_data() {
if (filter.has_operator("pm-with")) {
var emails = filter.operands("pm-with")[0].split(',');
var names = _.map(emails, function (email) {
if (! people_dict.has(email)) {
if (! people.get_by_email(email)) {
return email;
}
return people_dict.get(email).full_name;
return people.get_by_email(email).full_name;
});
tabs.push(make_tab(names.join(', '), hashed));
@@ -69,8 +69,8 @@ function make_tab_data() {
tabs.push(make_tab("Mentions", hashed));
} else if (filter.has_operator("sender")) {
var sender = filter.operands("sender")[0];
if (people_dict.has(sender)) {
sender = people_dict.get(sender).full_name;
if (people.get_by_email(sender)) {
sender = people.get_by_email(sender).full_name;
}
tabs.push(make_tab("Sent by " + sender, hashed));
} else if (filter.has_operator("search")) {

View File

@@ -12,13 +12,6 @@ var home_msg_list = new MessageList('zhome',
var narrowed_msg_list;
var current_msg_list = home_msg_list;
// The following three Dicts point to the same objects
// All people we've seen
var people_dict = new Dict();
var people_by_name_dict = new Dict();
// People in this realm
var realm_people_dict = new Dict();
var recent_subjects = new Dict({fold_case: true});
var queued_mark_as_read = [];
@@ -46,93 +39,6 @@ var suppress_unread_counts = true;
var waiting_on_browser_scroll = true;
function add_person(person, in_realm) {
page_params.people_list.push(person);
people_dict.set(person.email, person);
people_by_name_dict.set(person.full_name, person);
person.pm_recipient_count = 0;
}
function add_person_in_realm(person) {
realm_people_dict.set(person.email, person);
add_person(person);
}
function remove_person(person) {
var i;
for (i = 0; i < page_params.people_list.length; i++) {
if (page_params.people_list[i].email === person.email) {
page_params.people_list.splice(i, 1);
break;
}
}
people_dict.del(person.email);
people_by_name_dict.del(person.full_name);
realm_people_dict.del(person.email);
}
function reify_person(person) {
// If a locally sent message is a PM to
// an out-of-realm recipient, a people_dict
// entry is created with simply an email address
// Once we've received the full person object, replace
// it
if (! people_dict.has(person.email)) {
return;
}
var old_person = people_dict.get(person.email);
var old_idx = page_params.people_list.indexOf(old_person);
var new_person = _.extend({}, old_person, person);
people_dict.set(person.email, person);
people_by_name_dict.set(person.full_name, person);
page_params.people_list[old_idx] = new_person;
if (people_by_name_dict.has(person.email)) {
people_by_name_dict.del(person.email);
}
}
function update_person(person) {
// Currently the only attribute that can change is full_name, so
// we just push out changes to that field. As we add more things
// that can change, this will need to either get complicated or be
// replaced by MVC
if (! people_dict.has(person.email)) {
blueslip.error("Got update_person event for unexpected user",
{email: person.email});
return;
}
var person_obj = people_dict.get(person.email);
if (_.has(person, 'full_name')) {
if (people_by_name_dict.has(person_obj.full_name)) {
people_by_name_dict.set(person.full_name, person_obj);
people_by_name_dict.del(person_obj.full_name);
}
person_obj.full_name = person.full_name;
if (person.email === page_params.email) {
page_params.fullname = person.full_name;
}
}
if (_.has(person, 'is_admin')) {
person_obj.is_admin = person.is_admin;
if (person.email === page_params.email) {
page_params.is_admin = person.is_admin;
admin.show_or_hide_menu_item();
}
}
activity.set_user_statuses([]);
// TODO: update sender names on messages
}
function within_viewport(row_offset, row_height) {
// Returns true if a message is fully within the effectively visible
// part of the viewport.
@@ -683,17 +589,17 @@ function add_message_metadata(message) {
_.each(involved_people, function (person) {
// Do the hasOwnProperty() call via the prototype to avoid problems
// with keys like "hasOwnProperty"
if (! people_dict.has(person.email)) {
add_person(person);
if (! people.get_by_email(person.email)) {
people.add(person);
}
if (people_dict.get(person.email).full_name !== person.full_name) {
reify_person(person);
if (people.get_by_email(person.email).full_name !== person.full_name) {
people.reify(person);
}
if (message.type === 'private' && message.sent_by_me) {
// Track the number of PMs we've sent to this person to improve autocomplete
people_dict.get(person.email).pm_recipient_count += 1;
people.get_by_email(person.email).pm_recipient_count += 1;
}
});
@@ -1090,20 +996,6 @@ function consider_bankruptcy() {
}
}
_.each(page_params.people_list, function (person) {
people_dict.set(person.email, person);
people_by_name_dict.set(person.full_name, person);
realm_people_dict.set(person.email, person);
person.pm_recipient_count = 0;
});
// The special account feedback@zulip.com is used for in-app
// feedback and should always show up as an autocomplete option.
if (! people_dict.has('feedback@zulip.com')){
add_person({"email": "feedback@zulip.com",
"full_name": "Zulip Feedback Bot"});
}
function main() {
activity.set_user_statuses(page_params.initial_presences,
page_params.initial_servertime);

View File

@@ -25,7 +25,7 @@ var globals =
+ ' compose compose_fade rows hotkeys narrow reload notifications_bar search subs'
+ ' composebox_typeahead server_events typeahead_helper notifications hashchange'
+ ' invite ui util activity timerender MessageList MessageListView blueslip unread stream_list'
+ ' message_edit tab_bar emoji popovers navigate settings'
+ ' message_edit tab_bar emoji popovers navigate people settings'
+ ' avatar feature_flags search_suggestion referral stream_color Dict'
+ ' Filter summary admin stream_data muting WinChan muting_ui Socket channel'
@@ -53,7 +53,6 @@ var globals =
// zulip.js
+ ' all_msg_list home_msg_list narrowed_msg_list current_msg_list get_updates_params'
+ ' add_messages'
+ ' people_dict people_by_name_dict realm_people_dict'
+ ' keep_pointer_in_view unread_messages_read_in_narrow'
+ ' respond_to_message recenter_view last_viewport_movement_direction'
+ ' scroll_to_selected get_private_message_recipient'
@@ -65,7 +64,6 @@ var globals =
+ ' mark_current_list_as_read message_range message_in_table process_loaded_for_unread'
+ ' mark_all_as_read message_unread process_read_messages unread_in_current_view'
+ ' fast_forward_pointer recent_subjects unread_subjects'
+ ' add_person_in_realm remove_person update_person'
+ ' furthest_read server_furthest_read update_messages'
+ ' add_message_metadata'
+ ' mark_message_as_read batched_flag_updater'
@@ -74,7 +72,7 @@ var globals =
+ ' suppress_unread_counts'
+ ' msg_metadata_cache'
+ ' report_as_received'
+ ' insert_new_messages process_message_for_recent_subjects reify_person'
+ ' insert_new_messages process_message_for_recent_subjects'
;

View File

@@ -1,11 +1,5 @@
var assert = require('assert');
add_dependencies({
_: 'third/underscore/underscore.js',
util: 'js/util.js',
Dict: 'js/dict.js'
});
set_global('$', function () {
return {
on: function () {
@@ -13,6 +7,18 @@ set_global('$', function () {
}
};
});
$.fn = {};
$.fn.expectOne = function () {
assert(this.length === 1);
return this;
};
add_dependencies({
_: 'third/underscore/underscore.js',
util: 'js/util.js',
Dict: 'js/dict.js',
people: 'js/people.js'
});
set_global('document', {
hasFocus: function () {
@@ -20,7 +26,8 @@ set_global('document', {
}
});
set_global('people_dict', new global.Dict.from({
var people = require("js/people.js");
people.test_set_people_dict({
'alice@zulip.com': {
full_name: 'Alice Smith'
},
@@ -36,7 +43,7 @@ set_global('people_dict', new global.Dict.from({
'norbert@zulip.com': {
full_name: 'Norbert Oswald'
}
}));
});
var activity = require('js/activity.js');

View File

@@ -10,6 +10,7 @@ add_dependencies({
marked: 'third/marked/lib/marked.js',
Dict: 'js/dict.js',
emoji: 'js/emoji.js',
people: 'js/people.js',
fenced_code: 'js/fenced_code.js'
});
@@ -35,7 +36,8 @@ set_global('page_params', {
set_global('feature_flags', {local_echo: true});
set_global('people_by_name_dict', Dict.from({'Cordelia Lear': {full_name: 'Cordelia Lear', email: 'cordelia@zulip.com'}}));
var people = require("js/people.js");
people.test_set_people_name_dict({'Cordelia Lear': {full_name: 'Cordelia Lear', email: 'cordelia@zulip.com'}});
var echo = require('js/echo.js');

View File

@@ -553,6 +553,7 @@ JS_SPECS = {
'js/message_list.js',
'js/alert_words.js',
'js/alert_words_ui.js',
'js/people.js',
'js/server_events.js',
'js/zulip.js',
'js/activity.js',