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";
|
"use strict";
|
||||||
/* globals define, socket, ajaxify, app, bootbox, RELATIVE_PATH, utils */
|
/* 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 = {
|
var Details = {
|
||||||
cover: {}
|
cover: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var searchInterval;
|
||||||
|
|
||||||
Details.init = function() {
|
Details.init = function() {
|
||||||
var detailsPage = components.get('groups/container'),
|
var detailsPage = components.get('groups/container'),
|
||||||
settingsFormEl = detailsPage.find('form');
|
settingsFormEl = detailsPage.find('form');
|
||||||
@@ -15,6 +17,9 @@ define('forum/groups/details', ['iconSelect', 'components', 'vendor/colorpicker/
|
|||||||
Details.initialiseCover();
|
Details.initialiseCover();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleMemberSearch();
|
||||||
|
handleMemberInfiniteScroll();
|
||||||
|
|
||||||
components.get('groups/activity').find('.content img').addClass('img-responsive');
|
components.get('groups/activity').find('.content img').addClass('img-responsive');
|
||||||
|
|
||||||
detailsPage.on('click', '[data-action]', function() {
|
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;
|
return Details;
|
||||||
});
|
});
|
||||||
@@ -79,7 +79,9 @@ groupsController.details = function(req, res, next) {
|
|||||||
async.parallel({
|
async.parallel({
|
||||||
group: function(next) {
|
group: function(next) {
|
||||||
groups.get(res.locals.groupName, {
|
groups.get(res.locals.groupName, {
|
||||||
uid: req.uid
|
uid: req.uid,
|
||||||
|
truncateUserList: true,
|
||||||
|
userListCount: 20
|
||||||
}, next);
|
}, next);
|
||||||
},
|
},
|
||||||
posts: function(next) {
|
posts: function(next) {
|
||||||
|
|||||||
@@ -115,27 +115,18 @@ var async = require('async'),
|
|||||||
}
|
}
|
||||||
|
|
||||||
options.escape = options.hasOwnProperty('escape') ? options.escape : true;
|
options.escape = options.hasOwnProperty('escape') ? options.escape : true;
|
||||||
|
var stop = -1;
|
||||||
|
|
||||||
async.parallel({
|
async.parallel({
|
||||||
base: function (next) {
|
base: function (next) {
|
||||||
db.getObject('group:' + groupName, 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) {
|
members: function (next) {
|
||||||
var stop = -1;
|
|
||||||
if (options.truncateUserList) {
|
if (options.truncateUserList) {
|
||||||
stop = (parseInt(options.userListCount, 10) || 4) - 1;
|
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) {
|
pending: function (next) {
|
||||||
async.waterfall([
|
async.waterfall([
|
||||||
@@ -164,19 +155,6 @@ var async = require('async'),
|
|||||||
results.base['cover:position'] = '50% 50%';
|
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) {
|
plugins.fireHook('filter:parse.raw', results.base.description, function(err, descriptionParsed) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(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.userTitleEnabled = results.base.userTitleEnabled ? !!parseInt(results.base.userTitleEnabled, 10) : true;
|
||||||
results.base.createtimeISO = utils.toISOString(results.base.createtime);
|
results.base.createtimeISO = utils.toISOString(results.base.createtime);
|
||||||
results.base.members = results.members;
|
results.base.members = results.members;
|
||||||
|
results.base.membersNextStart = stop + 1;
|
||||||
results.base.pending = results.pending.filter(Boolean);
|
results.base.pending = results.pending.filter(Boolean);
|
||||||
results.base.deleted = !!parseInt(results.base.deleted, 10);
|
results.base.deleted = !!parseInt(results.base.deleted, 10);
|
||||||
results.base.hidden = !!parseInt(results.base.hidden, 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) {
|
Groups.escapeGroupData = function(group) {
|
||||||
if (group) {
|
if (group) {
|
||||||
group.nameEncoded = encodeURIComponent(group.name);
|
group.nameEncoded = encodeURIComponent(group.name);
|
||||||
|
|||||||
@@ -13,6 +13,14 @@ module.exports = function(Groups) {
|
|||||||
db.isSetMember('group:' + groupName + ':owners', uid, callback);
|
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) {
|
Groups.ownership.grant = function(toUid, groupName, callback) {
|
||||||
// Note: No ownership checking is done here on purpose!
|
// Note: No ownership checking is done here on purpose!
|
||||||
db.setAdd('group:' + groupName + ':owners', toUid, callback);
|
db.setAdd('group:' + groupName + ':owners', toUid, callback);
|
||||||
|
|||||||
@@ -87,7 +87,48 @@ module.exports = function(Groups) {
|
|||||||
], callback);
|
], 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;
|
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);
|
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) {
|
SocketGroups.kick = function(socket, data, callback) {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return callback(new Error('[[error:invalid-data]]'));
|
return callback(new Error('[[error:invalid-data]]'));
|
||||||
|
|||||||
Reference in New Issue
Block a user