Some sorting optimizations
* Differentiate between adding new roster items and rendering existing ones. * Also, only sort pending and requesting contacts once they've all been added (similar to what was already being done with existing contacts)
This commit is contained in:
parent
b1b63b0267
commit
434e21d046
88
converse.js
88
converse.js
@ -122,6 +122,14 @@
|
||||
var KEY = {
|
||||
ENTER: 13
|
||||
};
|
||||
var STATUS_WEIGHTS = {
|
||||
'offline': 6,
|
||||
'unavailable': 5,
|
||||
'xa': 4,
|
||||
'away': 3,
|
||||
'dnd': 2,
|
||||
'online': 1
|
||||
};
|
||||
var HAS_CSPRNG = ((typeof crypto !== 'undefined') &&
|
||||
((typeof crypto.randomBytes === 'function') ||
|
||||
(typeof crypto.getRandomValues === 'function')
|
||||
@ -3231,7 +3239,7 @@
|
||||
|
||||
initialize: function () {
|
||||
this.model.on("add", function (item) {
|
||||
this.addRosterItemView(item).renderRosterItem(item).updateRoster();
|
||||
this.addRosterItemView(item).addRosterItem(item).updateRoster();
|
||||
if (item.get('is_last')) {
|
||||
this.sortRoster().showRoster();
|
||||
}
|
||||
@ -3317,33 +3325,40 @@
|
||||
},
|
||||
|
||||
renderRosterItem: function (item) {
|
||||
var $contact_requests = this.$('#xmpp-contact-requests'),
|
||||
$pending_contacts = this.$('#pending-xmpp-contacts'),
|
||||
$current_contacts = this.$el.find('.roster-group'),
|
||||
crit = {order:'asc'};
|
||||
var view = this.get(item.id);
|
||||
if (!view) {
|
||||
// This method should only be called for items with views.
|
||||
return;
|
||||
converse.log("renderRosterItem called with item that doesn't have a view", "error");
|
||||
return this;
|
||||
}
|
||||
if ((converse.show_only_online_users) && (item.get('chat_status') !== 'online')) {
|
||||
view.$el.remove();
|
||||
view.delegateEvents();
|
||||
} else {
|
||||
view.render()
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
addRosterItem: function (item) {
|
||||
if ((converse.show_only_online_users) && (item.get('chat_status') !== 'online')) {
|
||||
return this;
|
||||
}
|
||||
// TODO: need to choose proper group
|
||||
// FIXME: DON'T SORT CONTINUOUSLY, SUPER SLOW
|
||||
// TODO: Insert the item in the correct order
|
||||
var view = this.get(item.id);
|
||||
if (!view) {
|
||||
converse.log("renderRosterItem called with item that doesn't have a view", "error");
|
||||
return this;
|
||||
}
|
||||
var $contact_requests = this.$('#xmpp-contact-requests'),
|
||||
$pending_contacts = this.$('#pending-xmpp-contacts'),
|
||||
$current_contacts = this.$el.find('.roster-group');
|
||||
view.render()
|
||||
// TODO: need to add group support
|
||||
if (view.$el.hasClass('current-xmpp-contact')) {
|
||||
$current_contacts.after(view.el);
|
||||
$current_contacts.after($current_contacts.siblings('dd.current-xmpp-contact').tsort(crit));
|
||||
} else if (view.$el.hasClass('pending-xmpp-contact')) {
|
||||
$pending_contacts.after(view.el);
|
||||
$pending_contacts.after($pending_contacts.siblings('dd.pending-xmpp-contact').tsort(crit));
|
||||
} else if (view.$el.hasClass('requesting-xmpp-contact')) {
|
||||
$contact_requests.after(view.render().el);
|
||||
$contact_requests.after($contact_requests.siblings('dd.requesting-xmpp-contact').tsort(crit));
|
||||
}
|
||||
return this;
|
||||
},
|
||||
@ -3399,31 +3414,34 @@
|
||||
}
|
||||
},
|
||||
|
||||
sortFunction: function (a, b) {
|
||||
var a_status = a.s[0],
|
||||
a_name =a.s[1],
|
||||
b_status = b.s[0],
|
||||
b_name =b.s[1];
|
||||
if (STATUS_WEIGHTS[a_status] === STATUS_WEIGHTS[b_status]) {
|
||||
return a_name < b_name ? -1 : (a_name > b_name ? 1 : 0);
|
||||
} else {
|
||||
return STATUS_WEIGHTS[a_status] < STATUS_WEIGHTS[b_status] ? -1 : 1;
|
||||
}
|
||||
},
|
||||
|
||||
sortRoster: function (chat_status) {
|
||||
var sortFunction = function (a, b) {
|
||||
var a_status = a.s[0],
|
||||
a_name =a.s[1],
|
||||
b_status = b.s[0],
|
||||
b_name =b.s[1],
|
||||
comp = {
|
||||
'offline': 6,
|
||||
'unavailable': 5,
|
||||
'xa': 4,
|
||||
'away': 3,
|
||||
'dnd': 2,
|
||||
'online': 1
|
||||
};
|
||||
if (comp[a_status] === comp[b_status]) {
|
||||
return a_name < b_name ? -1 : (a_name > b_name ? 1 : 0);
|
||||
} else {
|
||||
return comp[a_status] < comp[b_status] ? -1 : 1;
|
||||
}
|
||||
};
|
||||
this.$el.find('.roster-group').each(function (idx, group) {
|
||||
/* XXX
|
||||
* 1). See if the jquery detach method can be somehow used to avoid DOM reflows.
|
||||
* 2). Likewise see if documentFragment can be used.
|
||||
*/
|
||||
this.$el.find('.roster-group').each($.proxy(function (idx, group) {
|
||||
var $group = $(group);
|
||||
var $contacts = $group.nextUntil('dt', 'dd.current-xmpp-contact');
|
||||
$group.after($contacts.tsort({sortFunction: sortFunction, data: 'status'}, 'a'));
|
||||
});
|
||||
$group.after($contacts.tsort({sortFunction: this.sortFunction, data: 'status'}, 'a'));
|
||||
},this));
|
||||
// Also sort pending and requesting contacts
|
||||
var crit = {order:'asc'},
|
||||
$contact_requests = this.$('#xmpp-contact-requests'),
|
||||
$pending_contacts = this.$('#pending-xmpp-contacts');
|
||||
$pending_contacts.after($pending_contacts.siblings('dd.pending-xmpp-contact').tsort(crit));
|
||||
$contact_requests.after($contact_requests.siblings('dd.requesting-xmpp-contact').tsort(crit));
|
||||
return this;
|
||||
},
|
||||
|
||||
|
@ -215,10 +215,10 @@
|
||||
});
|
||||
expect(this.rosterview.updateRoster).toHaveBeenCalled();
|
||||
expect(converse.emit).toHaveBeenCalledWith('rosterViewUpdated');
|
||||
// Check that they are sorted alphabetically
|
||||
t = this.rosterview.$el.find('dt#pending-xmpp-contacts').siblings('dd.pending-xmpp-contact').find('span').text();
|
||||
expect(t).toEqual(mock.pend_names.slice(0,i+1).sort().join(''));
|
||||
}
|
||||
// Check that they are sorted alphabetically
|
||||
t = this.rosterview.$el.find('dt#pending-xmpp-contacts').siblings('dd.pending-xmpp-contact').find('span').text();
|
||||
expect(t).toEqual(mock.pend_names.slice(0,i+1).sort().join(''));
|
||||
}, converse));
|
||||
|
||||
}, converse));
|
||||
@ -478,16 +478,16 @@
|
||||
is_last: i===(mock.req_names.length-1)
|
||||
});
|
||||
expect(this.rosterview.updateRoster).toHaveBeenCalled();
|
||||
// Check that they are sorted alphabetically
|
||||
children = this.rosterview.$el.find('dt#xmpp-contact-requests').siblings('dd.requesting-xmpp-contact').children('span');
|
||||
names = [];
|
||||
children.each(addName);
|
||||
expect(names.join('')).toEqual(mock.req_names.slice(0,i+1).sort().join(''));
|
||||
// When a requesting contact is added, the controlbox must
|
||||
// be opened.
|
||||
expect(this.controlboxtoggle.showControlBox).toHaveBeenCalled();
|
||||
expect(converse.emit).toHaveBeenCalledWith('rosterViewUpdated');
|
||||
}
|
||||
// Check that they are sorted alphabetically
|
||||
children = this.rosterview.$el.find('dt#xmpp-contact-requests').siblings('dd.requesting-xmpp-contact').children('span');
|
||||
names = [];
|
||||
children.each(addName);
|
||||
expect(names.join('')).toEqual(mock.req_names.slice(0,i+1).sort().join(''));
|
||||
}, converse));
|
||||
|
||||
it("can be collapsed under their own header", $.proxy(function () {
|
||||
|
Loading…
Reference in New Issue
Block a user