diff --git a/app/ui-flextab/client/tabs/membersList.html b/app/ui-flextab/client/tabs/membersList.html
index e9f0fc82874..6a1ada15a98 100644
--- a/app/ui-flextab/client/tabs/membersList.html
+++ b/app/ui-flextab/client/tabs/membersList.html
@@ -22,30 +22,30 @@
{{#unless loading}}
-
-
{{{_ "Showing_online_users" total_showing=totalShowing online=totalOnline total=total}}}
-
+
+
{{{_ "Showing_online_users" total_showing=totalShowing online=totalOnline total=total}}}
+
{{/unless}}
- {{#if loading}}
- {{> loading}}
- {{else}}
-
- {{#each users}}
- -
- {{> avatar username=user.username}}
-
-
- {{ignored}} {{displayName}} {{utcOffset}}
-
- {{> icon user=. block="rc-member-list__menu js-more" icon="menu" }}
-
- {{/each}}
-
- {{/if}}
+ {{#if loading}}
+ {{> loading}}
+ {{else}}
+
+ {{#each users}}
+ -
+ {{> avatar username=user.username}}
+
+
+ {{ignored}} {{displayName}} {{utcOffset}}
+
+ {{> icon user=. block="rc-member-list__menu js-more" icon="menu" }}
+
+ {{/each}}
+
+ {{/if}}
{{#if hasMore}}
-
+
{{/if}}
diff --git a/app/ui-flextab/client/tabs/membersList.js b/app/ui-flextab/client/tabs/membersList.js
index 82d3e7ff599..d3f667cb830 100644
--- a/app/ui-flextab/client/tabs/membersList.js
+++ b/app/ui-flextab/client/tabs/membersList.js
@@ -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);
diff --git a/server/methods/getUsersOfRoom.js b/server/methods/getUsersOfRoom.js
index e999182c455..02d4524f3e7 100644
--- a/server/methods/getUsersOfRoom.js
+++ b/server/methods/getUsersOfRoom.js
@@ -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,
};
},
});