Add pagination to getUsersOfRoom (#12834)

* [IMPROVE] method getUsersOfRoom

* Update getUsersOfRoom.js

* Update getUsersOfRoom.js

* Update getUsersOfRoom.js

* Use $replaceRoot

* Fix lint

* Update getUsersOfRoom.js

* Add pagination to getUsersOfRoom

* Fix sorting with status

* Update membersList.js
pull/13815/head^2
Guilherme Gazzo 6 years ago committed by Rodrigo Nascimento
parent 338e4da204
commit 7d18278613
  1. 40
      app/ui-flextab/client/tabs/membersList.html
  2. 84
      app/ui-flextab/client/tabs/membersList.js
  3. 89
      server/methods/getUsersOfRoom.js

@ -22,30 +22,30 @@
</form>
{{#unless loading}}
<div class="rc-user-info__row rc-user-info__row--separator">
<div class="rc-member-list__counter">{{{_ "Showing_online_users" total_showing=totalShowing online=totalOnline total=total}}}</div>
</div>
<div class="rc-user-info__row rc-user-info__row--separator">
<div class="rc-member-list__counter">{{{_ "Showing_online_users" total_showing=totalShowing online=totalOnline total=total}}}</div>
</div>
{{/unless}}
</div>
<div class="flex-tab__result list-view">
{{#if loading}}
{{> loading}}
{{else}}
<ul class='list clearfix lines'>
{{#each users}}
<li class='rc-member-list__user'>
{{> avatar username=user.username}}
<div class="rc-member-list__username">
<div class="rc-member-list__status rc-member-list__status--{{status}}"></div>
{{ignored}} {{displayName}} {{utcOffset}}
</div>
{{> icon user=. block="rc-member-list__menu js-more" icon="menu" }}
</li>
{{/each}}
</ul>
{{/if}}
{{#if loading}}
{{> loading}}
{{else}}
<ul class='list clearfix lines'>
{{#each users}}
<li class='rc-member-list__user'>
{{> avatar username=user.username}}
<div class="rc-member-list__username">
<div class="rc-member-list__status rc-member-list__status--{{status}}"></div>
{{ignored}} {{displayName}} {{utcOffset}}
</div>
{{> icon user=. block="rc-member-list__menu js-more" icon="menu" }}
</li>
{{/each}}
</ul>
{{/if}}
{{#if hasMore}}
<button class="rc-button rc-button--secondary show-more-users">{{_ "Show_more"}}</button>
<button class="rc-button rc-button--secondary show-more-users {{#if loadingMore}}loading{{/if}}">{{_ "Show_more"}}</button>
{{/if}}
</div>

@ -8,7 +8,6 @@ import { ChatRoom, Subscriptions } from '../../../models';
import { settings } from '../../../settings';
import { t, isRtl, handleError, roomTypes } from '../../../utils';
import { WebRTC } from '../../../webrtc/client';
import _ from 'underscore';
import { getActions } from './userActions';
Template.membersList.helpers({
@ -30,14 +29,6 @@ Template.membersList.helpers({
return ChatRoom.findOne(this.rid, { reactive: false }).t === 'd';
},
seeAll() {
if (Template.instance().showAllUsers.get()) {
return t('Show_only_online');
} else {
return t('Show_all');
}
},
roomUsers() {
const onlineUsers = RoomManager.onlineUsers.get();
const roomUsers = Template.instance().users.get();
@ -83,33 +74,21 @@ Template.membersList.helpers({
};
});
if (settings.get('UI_Use_Real_Name')) {
users = _.sortBy(users, (u) => u.user.name);
} else {
users = _.sortBy(users, (u) => u.user.username);
}
// show online users first.
// sortBy is stable, so we can do this
users = _.sortBy(users, (u) => u.status === 'offline');
let hasMore = undefined;
const usersLimit = Template.instance().usersLimit.get();
if (usersLimit) {
hasMore = users.length > usersLimit;
users = _.first(users, usersLimit) || [];
}
const totalShowing = users.length;
const usersTotal = users.length;
const { total, loading, usersLimit, loadingMore } = Template.instance();
const hasMore = loadingMore.get() || (usersTotal < total.get() && usersLimit.get() <= usersTotal);
const totalShowing = usersTotal;
const ret = {
return {
_id: this.rid,
total: Template.instance().total.get(),
total: total.get(),
totalShowing,
loading: Template.instance().loading.get(),
loading: loading.get(),
totalOnline,
users,
hasMore,
rid: this.rid,
};
return ret;
},
canAddUser() {
@ -171,7 +150,12 @@ Template.membersList.helpers({
}
return this.user.username;
} });
},
loadingMore() {
return Template.instance().loadingMore.get();
},
});
Template.membersList.events({
'click .js-add'() {
@ -189,15 +173,7 @@ Template.membersList.events({
'change .js-type'(e, instance) {
const seeAll = instance.showAllUsers.get();
instance.showAllUsers.set(!seeAll);
},
'click .see-all'(e, instance) {
const seeAll = instance.showAllUsers.get();
instance.showAllUsers.set(!seeAll);
if (!seeAll) {
return instance.usersLimit.set(100);
}
instance.usersLimit.set(100);
},
'click .js-more'(e, instance) {
e.currentTarget.parentElement.classList.add('active');
@ -269,7 +245,21 @@ Template.membersList.events({
},
'click .show-more-users'(e, instance) {
return instance.usersLimit.set(instance.usersLimit.get() + 100);
const { showAllUsers, usersLimit, users, total, loadingMore } = instance;
loadingMore.set(true);
Meteor.call('getUsersOfRoom', this.rid, showAllUsers.get(), { limit: usersLimit.get() + 100, skip: 0 }, (error, result) => {
if (error) {
console.error(error);
loadingMore.set(false);
return;
}
users.set(result.records);
total.set(result.total);
loadingMore.set(false);
});
usersLimit.set(usersLimit.get() + 100);
},
});
@ -284,20 +274,24 @@ Template.membersList.onCreated(function() {
this.users = new ReactiveVar([]);
this.total = new ReactiveVar;
this.loading = new ReactiveVar(true);
this.loadingMore = new ReactiveVar(false);
this.tabBar = Template.instance().tabBar;
Tracker.autorun(() => {
if (this.data.rid == null) { return; }
this.loading.set(true);
return Meteor.call('getUsersOfRoom', this.data.rid, this.showAllUsers.get(), (error, users) => {
return Meteor.call('getUsersOfRoom', this.data.rid, this.showAllUsers.get(), { limit: 100, skip: 0 }, (error, users) => {
if (error) {
console.error(error);
return this.loading.set(false);
}
this.users.set(users.records);
this.total.set(users.total);
return this.loading.set(false);
}
);
}
);
});
});
this.clearUserDetail = () => {
this.showDetail.set(false);

@ -1,9 +1,48 @@
import { Meteor } from 'meteor/meteor';
import { Subscriptions } from '../../app/models';
import { hasPermission } from '../../app/authorization';
import { settings } from '../../app/settings';
function findUsers({ rid, status, skip, limit }) {
return Subscriptions.model.rawCollection().aggregate([
{ $match: { rid } },
{
$lookup:
{
from: 'users',
localField: 'u._id',
foreignField: '_id',
as: 'u',
},
},
{
$project: {
'u._id': 1,
'u.name': 1,
'u.username': 1,
'u.status': 1,
},
},
...(status ? [{ $match: { 'u.status': status } }] : []),
{
$sort: {
[settings.get('UI_Use_Real_Name') ? 'u.name' : 'u.username']: 1,
},
},
...(skip > 0 ? [{ $skip: skip }] : []),
...(limit > 0 ? [{ $limit: limit }] : []),
{
$project: {
_id: { $arrayElemAt: ['$u._id', 0] },
name: { $arrayElemAt: ['$u.name', 0] },
username: { $arrayElemAt: ['$u.username', 0] },
},
},
]).toArray();
}
Meteor.methods({
async getUsersOfRoom(rid, showAll) {
async getUsersOfRoom(rid, showAll, { limit, skip } = {}) {
const userId = Meteor.userId();
if (!userId) {
throw new Meteor.Error('error-invalid-user', 'Invalid user', { method: 'getUsersOfRoom' });
@ -18,38 +57,26 @@ Meteor.methods({
throw new Meteor.Error('error-not-allowed', 'Not allowed', { method: 'getUsersOfRoom' });
}
const subscriptions = Subscriptions.findByRoomIdWhenUsernameExists(rid);
const total = Subscriptions.findByRoomIdWhenUsernameExists(rid).count();
const users = await findUsers({ rid, status: { $ne: 'offline' }, limit, skip });
if (showAll && users.length < limit) {
const offlineUsers = await findUsers({
rid,
status: { $eq: 'offline' },
limit: limit - users.length,
skip,
});
return {
total,
records: users.concat(offlineUsers),
};
}
return {
total: subscriptions.count(),
records: await Subscriptions.model.rawCollection().aggregate([
{ $match: { rid } },
{
$lookup:
{
from: 'users',
localField: 'u._id',
foreignField: '_id',
as: 'u',
},
},
{
$project: {
'u._id': 1,
'u.name': 1,
'u.username': 1,
'u.status': 1,
},
},
...(showAll ? [] : [{ $match: { 'u.status': { $in: ['online', 'away', 'busy'] } } }]),
{
$project: {
_id: { $arrayElemAt: ['$u._id', 0] },
name: { $arrayElemAt: ['$u.name', 0] },
username: { $arrayElemAt: ['$u.username', 0] },
},
},
]).toArray(),
total,
records: users,
};
},
});

Loading…
Cancel
Save