mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-31 19:15:58 +01:00
closes #2605
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
"use strict";
|
||||
/* globals define, socket, ajaxify, app, bootbox, RELATIVE_PATH, utils */
|
||||
|
||||
define('forum/groups/details', ['iconSelect', 'components', 'vendor/colorpicker/colorpicker', 'vendor/jquery/draggable-background/backgroundDraggable'], function(iconSelect, components) {
|
||||
define('forum/groups/details', ['iconSelect', 'components', 'forum/infinitescroll', 'vendor/colorpicker/colorpicker', 'vendor/jquery/draggable-background/backgroundDraggable'], function(iconSelect, components, infinitescroll) {
|
||||
var Details = {
|
||||
cover: {}
|
||||
};
|
||||
|
||||
var searchInterval;
|
||||
|
||||
Details.init = function() {
|
||||
var detailsPage = components.get('groups/container'),
|
||||
settingsFormEl = detailsPage.find('form');
|
||||
@@ -15,6 +17,9 @@ define('forum/groups/details', ['iconSelect', 'components', 'vendor/colorpicker/
|
||||
Details.initialiseCover();
|
||||
}
|
||||
|
||||
handleMemberSearch();
|
||||
handleMemberInfiniteScroll();
|
||||
|
||||
components.get('groups/activity').find('.content img').addClass('img-responsive');
|
||||
|
||||
detailsPage.on('click', '[data-action]', function() {
|
||||
@@ -280,5 +285,83 @@ define('forum/groups/details', ['iconSelect', 'components', 'vendor/colorpicker/
|
||||
});
|
||||
};
|
||||
|
||||
function handleMemberSearch() {
|
||||
$('[component="groups/members/search"]').on('keyup', function() {
|
||||
var query = $(this).val();
|
||||
if (searchInterval) {
|
||||
clearInterval(searchInterval);
|
||||
searchInterval = 0;
|
||||
}
|
||||
|
||||
searchInterval = setTimeout(function() {
|
||||
socket.emit('groups.searchMembers', {groupName: ajaxify.variables.get('group_name'), query: query}, function(err, results) {
|
||||
if (err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
infinitescroll.parseAndTranslate('groups/details', 'members', {
|
||||
group: {
|
||||
members: results.users,
|
||||
isOwner: ajaxify.variables.get('is_owner') === 'true'
|
||||
}
|
||||
}, function(html) {
|
||||
$('[component="groups/members"] tbody').html(html);
|
||||
});
|
||||
});
|
||||
}, 250);
|
||||
})
|
||||
}
|
||||
|
||||
function handleMemberInfiniteScroll() {
|
||||
$('[component="groups/members"] tbody').on('scroll', function() {
|
||||
var $this = $(this);
|
||||
var bottom = ($this[0].scrollHeight - $this.height()) * 0.9;
|
||||
if ($this.scrollTop() > bottom) {
|
||||
loadMoreMembers();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function loadMoreMembers() {
|
||||
var members = $('[component="groups/members"]');
|
||||
if (members.attr('loading')) {
|
||||
return;
|
||||
}
|
||||
members.attr('loading', 1);
|
||||
socket.emit('groups.loadMoreMembers', {
|
||||
groupName: ajaxify.variables.get('group_name'),
|
||||
after: members.attr('data-nextstart')
|
||||
}, function(err, data) {
|
||||
if (err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
if (data && data.users.length) {
|
||||
onMembersLoaded(data.users, function() {
|
||||
members.removeAttr('loading');
|
||||
members.attr('data-nextstart', data.nextStart);
|
||||
});
|
||||
} else {
|
||||
members.removeAttr('loading');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onMembersLoaded(users, callback) {
|
||||
users = users.filter(function(user) {
|
||||
return !$('[component="groups/members"] [data-uid="' + user.uid + '"]').length;
|
||||
});
|
||||
|
||||
infinitescroll.parseAndTranslate('groups/details', 'members', {
|
||||
group: {
|
||||
members: users,
|
||||
isOwner: ajaxify.variables.get('is_owner') === 'true'
|
||||
}
|
||||
}, function(html) {
|
||||
$('[component="groups/members"] tbody').append(html);
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
return Details;
|
||||
});
|
||||
@@ -79,7 +79,9 @@ groupsController.details = function(req, res, next) {
|
||||
async.parallel({
|
||||
group: function(next) {
|
||||
groups.get(res.locals.groupName, {
|
||||
uid: req.uid
|
||||
uid: req.uid,
|
||||
truncateUserList: true,
|
||||
userListCount: 20
|
||||
}, next);
|
||||
},
|
||||
posts: function(next) {
|
||||
|
||||
@@ -115,27 +115,18 @@ var async = require('async'),
|
||||
}
|
||||
|
||||
options.escape = options.hasOwnProperty('escape') ? options.escape : true;
|
||||
var stop = -1;
|
||||
|
||||
async.parallel({
|
||||
base: function (next) {
|
||||
db.getObject('group:' + groupName, next);
|
||||
},
|
||||
owners: function (next) {
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
db.getSetMembers('group:' + groupName + ':owners', next);
|
||||
},
|
||||
function(uids, next) {
|
||||
user.getUsers(uids, options.uid, next);
|
||||
}
|
||||
], next);
|
||||
},
|
||||
members: function (next) {
|
||||
var stop = -1;
|
||||
if (options.truncateUserList) {
|
||||
stop = (parseInt(options.userListCount, 10) || 4) - 1;
|
||||
}
|
||||
user.getUsersFromSet('group:' + groupName + ':members', options.uid, 0, stop, next);
|
||||
|
||||
Groups.getOwnersAndMembers(groupName, options.uid, 0, stop, next);
|
||||
},
|
||||
pending: function (next) {
|
||||
async.waterfall([
|
||||
@@ -164,19 +155,6 @@ var async = require('async'),
|
||||
results.base['cover:position'] = '50% 50%';
|
||||
}
|
||||
|
||||
var ownerUids = [];
|
||||
results.owners.forEach(function(user) {
|
||||
if (user) {
|
||||
user.isOwner = true;
|
||||
ownerUids.push(user.uid.toString());
|
||||
}
|
||||
});
|
||||
|
||||
results.members = results.members.filter(function(user, index, array) {
|
||||
return user && user.uid && ownerUids.indexOf(user.uid.toString()) === -1;
|
||||
});
|
||||
results.members = results.owners.concat(results.members);
|
||||
|
||||
plugins.fireHook('filter:parse.raw', results.base.description, function(err, descriptionParsed) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
@@ -190,6 +168,7 @@ var async = require('async'),
|
||||
results.base.userTitleEnabled = results.base.userTitleEnabled ? !!parseInt(results.base.userTitleEnabled, 10) : true;
|
||||
results.base.createtimeISO = utils.toISOString(results.base.createtime);
|
||||
results.base.members = results.members;
|
||||
results.base.membersNextStart = stop + 1;
|
||||
results.base.pending = results.pending.filter(Boolean);
|
||||
results.base.deleted = !!parseInt(results.base.deleted, 10);
|
||||
results.base.hidden = !!parseInt(results.base.hidden, 10);
|
||||
@@ -207,6 +186,43 @@ var async = require('async'),
|
||||
});
|
||||
};
|
||||
|
||||
Groups.getOwnersAndMembers = function(groupName, uid, start, stop, callback) {
|
||||
async.parallel({
|
||||
owners: function (next) {
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
db.getSetMembers('group:' + groupName + ':owners', next);
|
||||
},
|
||||
function(uids, next) {
|
||||
user.getUsers(uids, uid, next);
|
||||
}
|
||||
], next);
|
||||
},
|
||||
members: function (next) {
|
||||
user.getUsersFromSet('group:' + groupName + ':members', uid, start, stop, next);
|
||||
}
|
||||
}, function(err, results) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
var ownerUids = [];
|
||||
results.owners.forEach(function(user) {
|
||||
if (user) {
|
||||
user.isOwner = true;
|
||||
ownerUids.push(user.uid.toString());
|
||||
}
|
||||
});
|
||||
|
||||
results.members = results.members.filter(function(user, index, array) {
|
||||
return user && user.uid && ownerUids.indexOf(user.uid.toString()) === -1;
|
||||
});
|
||||
results.members = results.owners.concat(results.members);
|
||||
|
||||
callback(null, results.members);
|
||||
});
|
||||
};
|
||||
|
||||
Groups.escapeGroupData = function(group) {
|
||||
if (group) {
|
||||
group.nameEncoded = encodeURIComponent(group.name);
|
||||
|
||||
@@ -13,6 +13,14 @@ module.exports = function(Groups) {
|
||||
db.isSetMember('group:' + groupName + ':owners', uid, callback);
|
||||
};
|
||||
|
||||
Groups.ownership.isOwners = function(uids, groupName, callback) {
|
||||
if (!Array.isArray(uids)) {
|
||||
return callback(null, []);
|
||||
}
|
||||
|
||||
db.isSetMembers('group:' + groupName + ':owners', uids, callback);
|
||||
};
|
||||
|
||||
Groups.ownership.grant = function(toUid, groupName, callback) {
|
||||
// Note: No ownership checking is done here on purpose!
|
||||
db.setAdd('group:' + groupName + ':owners', toUid, callback);
|
||||
|
||||
@@ -87,7 +87,48 @@ module.exports = function(Groups) {
|
||||
], callback);
|
||||
}
|
||||
|
||||
if (!data.query) {
|
||||
Groups.getOwnersAndMembers(data.groupName, data.uid, 0, 19, function(err, users) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
callback(null, {users: users});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
data.findUids = findUids;
|
||||
user.search(data, callback);
|
||||
var results;
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
user.search(data, next);
|
||||
},
|
||||
function(_results, next) {
|
||||
results = _results;
|
||||
var uids = results.users.map(function(user) {
|
||||
return user && user.uid;
|
||||
});
|
||||
Groups.ownership.isOwners(uids, data.groupName, next);
|
||||
},
|
||||
function(isOwners, next) {
|
||||
|
||||
results.users.forEach(function(user, index) {
|
||||
if (user) {
|
||||
user.isOwner = isOwners[index];
|
||||
}
|
||||
});
|
||||
|
||||
results.users.sort(function(a,b) {
|
||||
if (a.isOwner && !b.isOwner) {
|
||||
return -1;
|
||||
} else if (!a.isOwner && b.isOwner) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
})
|
||||
next(null, results);
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -244,6 +244,20 @@ SocketGroups.searchMembers = function(socket, data, callback) {
|
||||
groups.searchMembers(data, callback);
|
||||
};
|
||||
|
||||
SocketGroups.loadMoreMembers = function(socket, data, callback) {
|
||||
if (!data || !data.groupName || !parseInt(data.after, 10)) {
|
||||
return callback(new Error('[[error:invalid-data]]'));
|
||||
}
|
||||
data.after = parseInt(data.after, 10);
|
||||
user.getUsersFromSet('group:' + data.groupName + ':members', socket.uid, data.after, data.after + 9, function(err, users) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
callback(null, {users: users, nextStart: data.after + 10});
|
||||
});
|
||||
};
|
||||
|
||||
SocketGroups.kick = function(socket, data, callback) {
|
||||
if (!data) {
|
||||
return callback(new Error('[[error:invalid-data]]'));
|
||||
|
||||
Reference in New Issue
Block a user