buddy list: Shrink overly large lists.

If we would have more than 600 people in a buddy list, it's kind of
cumbersome to scroll through it, and it's also expensive to render
it (short of doing progressive rendering, which adds a lot of
complexity).

So, as a short term measure, we filter out offline users whenever the
list would exceed 600 users.  Note that if you are doing a search that
narrows to fewer 600 users, the offline users will appear again.
This commit is contained in:
Steve Howell 2018-04-20 16:22:28 +00:00 committed by Tim Abbott
parent 3f1930f9c5
commit 54389f7b41
2 changed files with 79 additions and 11 deletions

View File

@ -0,0 +1,50 @@
zrequire('people');
zrequire('presence');
zrequire('util');
zrequire('buddy_data');
// The buddy_data module is mostly tested indirectly through
// activity.js, but we should feel free to add direct tests
// here.
set_global('page_params', {});
(function make_people() {
_.each(_.range(1000, 2000), (i) => {
const person = {
user_id: i,
full_name: `Person ${i}`,
email: `person${i}@example.com`,
};
people.add_in_realm(person);
});
}());
(function activate_people() {
const server_time = 9999;
const info = {
website: {
status: "active",
timestamp: server_time,
},
};
// Make 400 of the users active
_.each(_.range(1000, 1400), (user_id) => {
presence.set_user_status(user_id, info, server_time);
});
// And then 300 not active
_.each(_.range(1400, 1700), (user_id) => {
presence.set_user_status(user_id, {}, server_time);
});
}());
(function test_user_ids() {
const user_ids = buddy_data.get_filtered_and_sorted_user_ids();
// Even though we have 900 users, we only get the 400 active
// users. This is a consequence of buddy_data.maybe_shrink_list.
assert.equal(user_ids.length, 400);
}());

View File

@ -11,24 +11,25 @@ var exports = {};
*/
var max_size_before_shrinking = 600;
var presence_descriptions = {
active: 'is active',
idle: 'is not active',
};
exports.compare_function = function (a, b) {
function level(status) {
switch (status) {
case 'active':
return 1;
case 'idle':
return 2;
default:
return 3;
}
function level(status) {
switch (status) {
case 'active':
return 1;
case 'idle':
return 2;
default:
return 3;
}
}
exports.compare_function = function (a, b) {
var level_a = level(presence.get_status(a));
var level_b = level(presence.get_status(b));
var diff = level_a - level_b;
@ -102,6 +103,21 @@ exports.info_for = function (user_id) {
};
};
function user_is_recently_active(user_id) {
// return true if the user has a green/orange cirle
return level(presence.get_status(user_id)) <= 2;
}
function maybe_shrink_list(user_ids) {
if (user_ids.length <= max_size_before_shrinking) {
return user_ids;
}
user_ids = _.filter(user_ids, user_is_recently_active);
return user_ids;
}
exports.get_filtered_and_sorted_user_ids = function (filter_text) {
var user_ids;
@ -116,6 +132,8 @@ exports.get_filtered_and_sorted_user_ids = function (filter_text) {
user_ids = presence.get_user_ids();
}
user_ids = maybe_shrink_list(user_ids);
return exports.sort_users(user_ids);
};