Improve users list scrolling performance
- fixed JS error when avatar mode is disabled - added spinner at the bottom of the table - scroll detection now happens earlier - single/multiselect init is deferred so that the new rows are first appended into the list (more responsive) and initialized afterwards - disabled users sorting after add (assuming they are always sorted on the server side)
This commit is contained in:
parent
14d1abf63f
commit
c732764eb5
|
@ -48,7 +48,7 @@ ul.multiselectoptions > li input[type='checkbox']:checked+label {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.multiselect {
|
div.multiselect, select.multiselect {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
min-width: 150px;
|
min-width: 150px;
|
||||||
|
@ -58,6 +58,12 @@ div.multiselect {
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* To make a select look like a multiselect until it's initialized */
|
||||||
|
select.multiselect {
|
||||||
|
height: 30px;
|
||||||
|
min-width: 113px;
|
||||||
|
}
|
||||||
|
|
||||||
div.multiselect.active {
|
div.multiselect.active {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
@ -933,3 +933,15 @@ div.crumb:active {
|
||||||
opacity:.7;
|
opacity:.7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.appear {
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 500ms ease 0s;
|
||||||
|
-moz-transition: opacity 500ms ease 0s;
|
||||||
|
-ms-transition: opacity 500ms ease 0s;
|
||||||
|
-o-transition: opacity 500ms ease 0s;
|
||||||
|
-webkit-transition: opacity 500ms ease 0s;
|
||||||
|
}
|
||||||
|
.appear.transparent {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,19 +85,24 @@ var UserList = {
|
||||||
|
|
||||||
add: function (username, displayname, groups, subadmin, quota, sort) {
|
add: function (username, displayname, groups, subadmin, quota, sort) {
|
||||||
var tr = $('tbody tr').first().clone();
|
var tr = $('tbody tr').first().clone();
|
||||||
if (tr.find('div.avatardiv')){
|
var subadminsEl;
|
||||||
|
var subadminSelect;
|
||||||
|
var groupsSelect;
|
||||||
|
if (tr.find('div.avatardiv').length){
|
||||||
$('div.avatardiv', tr).avatar(username, 32);
|
$('div.avatardiv', tr).avatar(username, 32);
|
||||||
}
|
}
|
||||||
tr.attr('data-uid', username);
|
tr.attr('data-uid', username);
|
||||||
tr.attr('data-displayName', displayname);
|
tr.attr('data-displayName', displayname);
|
||||||
tr.find('td.name').text(username);
|
tr.find('td.name').text(username);
|
||||||
tr.find('td.displayName > span').text(displayname);
|
tr.find('td.displayName > span').text(displayname);
|
||||||
var groupsSelect = $('<select multiple="multiple" class="groupsselect" data-placehoder="Groups" title="' + t('settings', 'Groups') + '"></select>')
|
|
||||||
|
// make them look like the multiselect buttons
|
||||||
|
// until they get time to really get initialized
|
||||||
|
groupsSelect = $('<select multiple="multiple" class="groupsselect multiselect button" data-placehoder="Groups" title="' + t('settings', 'Groups') + '"></select>')
|
||||||
.attr('data-username', username)
|
.attr('data-username', username)
|
||||||
.data('user-groups', groups);
|
.data('user-groups', groups);
|
||||||
tr.find('td.groups').empty();
|
|
||||||
if (tr.find('td.subadmins').length > 0) {
|
if (tr.find('td.subadmins').length > 0) {
|
||||||
var subadminSelect = $('<select multiple="multiple" class="subadminsselect" data-placehoder="subadmins" title="' + t('settings', 'Group Admin') + '">')
|
subadminSelect = $('<select multiple="multiple" class="subadminsselect multiselect button" data-placehoder="subadmins" title="' + t('settings', 'Group Admin') + '">')
|
||||||
.attr('data-username', username)
|
.attr('data-username', username)
|
||||||
.data('user-groups', groups)
|
.data('user-groups', groups)
|
||||||
.data('subadmin', subadmin);
|
.data('subadmin', subadmin);
|
||||||
|
@ -109,11 +114,10 @@ var UserList = {
|
||||||
subadminSelect.append($('<option value="' + escapeHTML(group) + '">' + escapeHTML(group) + '</option>'));
|
subadminSelect.append($('<option value="' + escapeHTML(group) + '">' + escapeHTML(group) + '</option>'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
tr.find('td.groups').append(groupsSelect);
|
tr.find('td.groups').empty().append(groupsSelect);
|
||||||
UserList.applyMultiplySelect(groupsSelect);
|
subadminsEl = tr.find('td.subadmins');
|
||||||
if (tr.find('td.subadmins').length > 0) {
|
if (subadminsEl.length > 0) {
|
||||||
tr.find('td.subadmins').append(subadminSelect);
|
subadminsEl.append(subadminSelect);
|
||||||
UserList.applyMultiplySelect(subadminSelect);
|
|
||||||
}
|
}
|
||||||
if (tr.find('td.remove img').length === 0 && OC.currentUser !== username) {
|
if (tr.find('td.remove img').length === 0 && OC.currentUser !== username) {
|
||||||
var rm_img = $('<img class="svg action">').attr({
|
var rm_img = $('<img class="svg action">').attr({
|
||||||
|
@ -139,11 +143,11 @@ var UserList = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$(tr).appendTo('tbody');
|
$(tr).appendTo('tbody');
|
||||||
|
|
||||||
if (sort) {
|
if (sort) {
|
||||||
UserList.doSort();
|
UserList.doSort();
|
||||||
}
|
}
|
||||||
|
|
||||||
quotaSelect.singleSelect();
|
|
||||||
quotaSelect.on('change', function () {
|
quotaSelect.on('change', function () {
|
||||||
var uid = $(this).parent().parent().attr('data-uid');
|
var uid = $(this).parent().parent().attr('data-uid');
|
||||||
var quota = $(this).val();
|
var quota = $(this).val();
|
||||||
|
@ -153,6 +157,16 @@ var UserList = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// defer init so the user first sees the list appear more quickly
|
||||||
|
window.setTimeout(function(){
|
||||||
|
quotaSelect.singleSelect();
|
||||||
|
UserList.applyMultiplySelect(groupsSelect);
|
||||||
|
if (subadminSelect) {
|
||||||
|
UserList.applyMultiplySelect(subadminSelect);
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
return tr;
|
||||||
},
|
},
|
||||||
// From http://my.opera.com/GreyWyvern/blog/show.dml/1671288
|
// From http://my.opera.com/GreyWyvern/blog/show.dml/1671288
|
||||||
alphanum: function(a, b) {
|
alphanum: function(a, b) {
|
||||||
|
@ -211,26 +225,34 @@ var UserList = {
|
||||||
}
|
}
|
||||||
UserList.updating = true;
|
UserList.updating = true;
|
||||||
$.get(OC.Router.generate('settings_ajax_userlist', { offset: UserList.offset, limit: UserList.usersToLoad }), function (result) {
|
$.get(OC.Router.generate('settings_ajax_userlist', { offset: UserList.offset, limit: UserList.usersToLoad }), function (result) {
|
||||||
|
var loadedUsers = 0;
|
||||||
|
var trs = [];
|
||||||
if (result.status === 'success') {
|
if (result.status === 'success') {
|
||||||
//The offset does not mirror the amount of users available,
|
//The offset does not mirror the amount of users available,
|
||||||
//because it is backend-dependent. For correct retrieval,
|
//because it is backend-dependent. For correct retrieval,
|
||||||
//always the limit(requested amount of users) needs to be added.
|
//always the limit(requested amount of users) needs to be added.
|
||||||
UserList.offset += UserList.usersToLoad;
|
|
||||||
$.each(result.data, function (index, user) {
|
$.each(result.data, function (index, user) {
|
||||||
if($('tr[data-uid="' + user.name + '"]').length > 0) {
|
if($('tr[data-uid="' + user.name + '"]').length > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
var tr = UserList.add(user.name, user.displayname, user.groups, user.subadmin, user.quota, false);
|
var tr = UserList.add(user.name, user.displayname, user.groups, user.subadmin, user.quota, false);
|
||||||
if (index === 9) {
|
tr.addClass('appear transparent');
|
||||||
$(tr).bind('inview', function (event, isInView, visiblePartX, visiblePartY) {
|
trs.push(tr);
|
||||||
$(this).unbind(event);
|
loadedUsers++;
|
||||||
UserList.update();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
if (result.data.length > 0) {
|
if (result.data.length > 0) {
|
||||||
UserList.doSort();
|
UserList.doSort();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
UserList.noMoreEntries = true;
|
||||||
|
}
|
||||||
|
UserList.offset += loadedUsers;
|
||||||
|
// animate
|
||||||
|
setTimeout(function() {
|
||||||
|
for (var i = 0; i < trs.length; i++) {
|
||||||
|
trs[i].removeClass('transparent');
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
}
|
}
|
||||||
UserList.updating = false;
|
UserList.updating = false;
|
||||||
});
|
});
|
||||||
|
@ -239,7 +261,7 @@ var UserList = {
|
||||||
applyMultiplySelect: function (element) {
|
applyMultiplySelect: function (element) {
|
||||||
var checked = [];
|
var checked = [];
|
||||||
var user = element.attr('data-username');
|
var user = element.attr('data-username');
|
||||||
if ($(element).attr('class') === 'groupsselect') {
|
if ($(element).hasClass('groupsselect')) {
|
||||||
if (element.data('userGroups')) {
|
if (element.data('userGroups')) {
|
||||||
checked = element.data('userGroups');
|
checked = element.data('userGroups');
|
||||||
}
|
}
|
||||||
|
@ -295,7 +317,7 @@ var UserList = {
|
||||||
minWidth: 100
|
minWidth: 100
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if ($(element).attr('class') === 'subadminsselect') {
|
if ($(element).hasClass('subadminsselect')) {
|
||||||
if (element.data('subadmin')) {
|
if (element.data('subadmin')) {
|
||||||
checked = element.data('subadmin');
|
checked = element.data('subadmin');
|
||||||
}
|
}
|
||||||
|
@ -330,17 +352,24 @@ var UserList = {
|
||||||
minWidth: 100
|
minWidth: 100
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
_onScroll: function(e) {
|
||||||
|
if (!!UserList.noMoreEntries) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($(window).scrollTop() + $(window).height() > $(document).height() - 500) {
|
||||||
|
UserList.update(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
|
||||||
UserList.doSort();
|
UserList.doSort();
|
||||||
UserList.availableGroups = $('#content table').data('groups');
|
UserList.availableGroups = $('#content table').data('groups');
|
||||||
$('tbody tr:last').bind('inview', function (event, isInView, visiblePartX, visiblePartY) {
|
OC.Router.registerLoadedCallback(function() {
|
||||||
OC.Router.registerLoadedCallback(function () {
|
$(window).scroll(function(e) {UserList._onScroll(e);});
|
||||||
UserList.update();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$('select[multiple]').each(function (index, element) {
|
$('select[multiple]').each(function (index, element) {
|
||||||
|
|
Loading…
Reference in New Issue