mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-30 10:35:55 +01:00
closes #2594
This commit is contained in:
@@ -1,9 +1,43 @@
|
|||||||
define('forum/account/followers', ['forum/account/header'], function(header) {
|
'use strict';
|
||||||
|
|
||||||
|
/* globals define, socket, utils */
|
||||||
|
|
||||||
|
define('forum/account/followers', ['forum/account/header', 'forum/infinitescroll'], function(header, infinitescroll) {
|
||||||
var Followers = {};
|
var Followers = {};
|
||||||
|
|
||||||
Followers.init = function() {
|
Followers.init = function() {
|
||||||
header.init();
|
header.init();
|
||||||
|
|
||||||
|
infinitescroll.init(function(direction) {
|
||||||
|
Followers.loadMore(direction, 'account/followers', 'followers:' + $('.account-username-box').attr('data-uid'));
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Followers.loadMore = function(direction, tpl, set) {
|
||||||
|
if (direction < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
infinitescroll.loadMore('user.loadMore', {
|
||||||
|
set: set,
|
||||||
|
after: $('#users-container').attr('data-nextstart')
|
||||||
|
}, function(data, done) {
|
||||||
|
if (data.users && data.users.length) {
|
||||||
|
onUsersLoaded(tpl, data.users, done);
|
||||||
|
$('#users-container').attr('data-nextstart', data.nextStart);
|
||||||
|
} else {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function onUsersLoaded(tpl, users, callback) {
|
||||||
|
infinitescroll.parseAndTranslate(tpl, 'users', {users: users}, function(html) {
|
||||||
|
$('#users-container').append(html);
|
||||||
|
utils.addCommasToNumbers(html.find('.formatted-number'));
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return Followers;
|
return Followers;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,8 +1,16 @@
|
|||||||
define('forum/account/following', ['forum/account/header'], function(header) {
|
'use strict';
|
||||||
|
|
||||||
|
/* globals define */
|
||||||
|
|
||||||
|
define('forum/account/following', ['forum/account/header', 'forum/infinitescroll', 'forum/account/followers'], function(header, infinitescroll, followers) {
|
||||||
var Following = {};
|
var Following = {};
|
||||||
|
|
||||||
Following.init = function() {
|
Following.init = function() {
|
||||||
header.init();
|
header.init();
|
||||||
|
|
||||||
|
infinitescroll.init(function(direction) {
|
||||||
|
followers.loadMore(direction, 'account/following', 'following:' + $('.account-username-box').attr('data-uid'));
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return Following;
|
return Following;
|
||||||
|
|||||||
@@ -45,9 +45,6 @@ function getUserDataByUserSlug(userslug, callerUID, callback) {
|
|||||||
isAdmin : function(next) {
|
isAdmin : function(next) {
|
||||||
user.isAdministrator(callerUID, next);
|
user.isAdministrator(callerUID, next);
|
||||||
},
|
},
|
||||||
followStats: function(next) {
|
|
||||||
user.getFollowStats(uid, next);
|
|
||||||
},
|
|
||||||
ips: function(next) {
|
ips: function(next) {
|
||||||
user.getIPs(uid, 4, next);
|
user.getIPs(uid, 4, next);
|
||||||
},
|
},
|
||||||
@@ -97,8 +94,8 @@ function getUserDataByUserSlug(userslug, callerUID, callback) {
|
|||||||
userData.status = websockets.isUserOnline(userData.uid) ? (userData.status || 'online') : 'offline';
|
userData.status = websockets.isUserOnline(userData.uid) ? (userData.status || 'online') : 'offline';
|
||||||
userData.banned = parseInt(userData.banned, 10) === 1;
|
userData.banned = parseInt(userData.banned, 10) === 1;
|
||||||
userData.websiteName = userData.website.replace(validator.escape('http://'), '').replace(validator.escape('https://'), '');
|
userData.websiteName = userData.website.replace(validator.escape('http://'), '').replace(validator.escape('https://'), '');
|
||||||
userData.followingCount = results.followStats.followingCount;
|
userData.followingCount = parseInt(userData.followingCount, 10) || 0;
|
||||||
userData.followerCount = results.followStats.followerCount;
|
userData.followerCount = parseInt(userData.followerCount, 10) || 0;
|
||||||
|
|
||||||
callback(null, userData);
|
callback(null, userData);
|
||||||
});
|
});
|
||||||
@@ -206,14 +203,15 @@ function getFollow(tpl, name, req, res, next) {
|
|||||||
return helpers.notFound(req, res);
|
return helpers.notFound(req, res);
|
||||||
}
|
}
|
||||||
var method = name === 'following' ? 'getFollowing' : 'getFollowers';
|
var method = name === 'following' ? 'getFollowing' : 'getFollowers';
|
||||||
user[method](userData.uid, next);
|
user[method](userData.uid, 0, 49, next);
|
||||||
}
|
}
|
||||||
], function(err, users) {
|
], function(err, users) {
|
||||||
if(err) {
|
if(err) {
|
||||||
return next(err);
|
return next(err);
|
||||||
}
|
}
|
||||||
userData[name] = users;
|
|
||||||
userData[name + 'Count'] = users.length;
|
userData.users = users;
|
||||||
|
userData.nextStart = 50;
|
||||||
|
|
||||||
res.render(tpl, userData);
|
res.render(tpl, userData);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -329,27 +329,28 @@ SocketUser.loadMore = function(socket, data, callback) {
|
|||||||
return callback(new Error('[[error:no-privileges]]'));
|
return callback(new Error('[[error:no-privileges]]'));
|
||||||
}
|
}
|
||||||
|
|
||||||
var start = data.after,
|
var start = parseInt(data.after, 10),
|
||||||
end = start + 19;
|
end = start + 19;
|
||||||
|
|
||||||
user.getUsersFromSet(data.set, start, end, function(err, userData) {
|
user.getUsersFromSet(data.set, start, end, function(err, userData) {
|
||||||
if(err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
user.isAdministrator(socket.uid, function (err, isAdministrator) {
|
user.isAdministrator(socket.uid, function (err, isAdministrator) {
|
||||||
if(err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isAdministrator && data.set === 'users:online') {
|
if (!isAdministrator && data.set === 'users:online') {
|
||||||
userData = userData.filter(function(item) {
|
userData = userData.filter(function(item) {
|
||||||
return item.status !== 'offline';
|
return item.status !== 'offline';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(null, {
|
callback(null, {
|
||||||
users: userData
|
users: userData,
|
||||||
|
nextStart: end + 1
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ var db = require('./database'),
|
|||||||
schemaDate, thisSchemaDate,
|
schemaDate, thisSchemaDate,
|
||||||
|
|
||||||
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema
|
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema
|
||||||
latestSchema = Date.UTC(2015, 0, 13);
|
latestSchema = Date.UTC(2015, 0, 14);
|
||||||
|
|
||||||
Upgrade.check = function(callback) {
|
Upgrade.check = function(callback) {
|
||||||
db.get('schemaDate', function(err, value) {
|
db.get('schemaDate', function(err, value) {
|
||||||
@@ -566,6 +566,70 @@ Upgrade.upgrade = function(callback) {
|
|||||||
winston.info('[2015/01/13] Creating uid:followed_tids sorted set skipped');
|
winston.info('[2015/01/13] Creating uid:followed_tids sorted set skipped');
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
function(next) {
|
||||||
|
thisSchemaDate = Date.UTC(2015, 0, 14);
|
||||||
|
if (schemaDate < thisSchemaDate) {
|
||||||
|
winston.info('[2015/01/14] Upgrading follow sets to sorted sets');
|
||||||
|
|
||||||
|
db.getSortedSetRange('users:joindate', 0, -1, function(err, uids) {
|
||||||
|
if (err) {
|
||||||
|
winston.error('[2014/01/14] Error encountered while Upgrading follow sets to sorted sets');
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
var now = Date.now();
|
||||||
|
|
||||||
|
async.eachLimit(uids, 50, function(uid, next) {
|
||||||
|
async.parallel({
|
||||||
|
following: function(next) {
|
||||||
|
db.getSetMembers('following:' + uid, next);
|
||||||
|
},
|
||||||
|
followers: function(next) {
|
||||||
|
db.getSetMembers('followers:' + uid, next);
|
||||||
|
}
|
||||||
|
}, function(err, results) {
|
||||||
|
function updateToSortedSet(set, uids, callback) {
|
||||||
|
async.eachLimit(uids, 50, function(uid, next) {
|
||||||
|
if (parseInt(uid, 10)) {
|
||||||
|
db.sortedSetAdd(set, now, uid, next);
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
}, callback);
|
||||||
|
}
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
async.parallel([
|
||||||
|
async.apply(db.delete, 'following:' + uid),
|
||||||
|
async.apply(db.delete, 'followers:' + uid)
|
||||||
|
], function(err) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
async.parallel([
|
||||||
|
async.apply(updateToSortedSet, 'following:' + uid, results.following),
|
||||||
|
async.apply(updateToSortedSet, 'followers:' + uid, results.followers),
|
||||||
|
async.apply(db.setObjectField, 'user:' + uid, 'followingCount', results.following.length),
|
||||||
|
async.apply(db.setObjectField, 'user:' + uid, 'followerCount', results.followers.length),
|
||||||
|
], next);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, function(err) {
|
||||||
|
if (err) {
|
||||||
|
winston.error('[2015/01/14] Error encountered while Upgrading follow sets to sorted sets');
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
winston.info('[2015/01/14] Upgrading follow sets to sorted sets done');
|
||||||
|
Upgrade.update(thisSchemaDate, next);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
winston.info('[2015/01/14] Upgrading follow sets to sorted sets skipped');
|
||||||
|
next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add new schema updates here
|
// Add new schema updates here
|
||||||
|
|||||||
@@ -23,29 +23,40 @@ module.exports = function(User) {
|
|||||||
return callback(new Error('[[error:you-cant-follow-yourself]]'));
|
return callback(new Error('[[error:you-cant-follow-yourself]]'));
|
||||||
}
|
}
|
||||||
|
|
||||||
var command = type === 'follow' ? 'setAdd' : 'setRemove';
|
var now = Date.now();
|
||||||
db[command]('following:' + uid, theiruid, function(err) {
|
|
||||||
if(err) {
|
if (type === 'follow') {
|
||||||
return callback(err);
|
async.parallel([
|
||||||
}
|
async.apply(db.sortedSetAdd, 'following:' + uid, now, theiruid),
|
||||||
db[command]('followers:' + theiruid, uid, callback);
|
async.apply(db.sortedSetAdd, 'followers:' + theiruid, now, uid),
|
||||||
});
|
async.apply(User.incrementUserFieldBy, uid, 'followingCount', 1),
|
||||||
|
async.apply(User.incrementUserFieldBy, theiruid, 'followerCount', 1)
|
||||||
|
], callback);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
async.parallel([
|
||||||
|
async.apply(db.sortedSetRemove, 'following:' + uid, theiruid),
|
||||||
|
async.apply(db.sortedSetRemove, 'followers:' + theiruid, uid),
|
||||||
|
async.apply(User.decrementUserFieldBy, uid, 'followingCount', 1),
|
||||||
|
async.apply(User.decrementUserFieldBy, theiruid, 'followerCount', 1)
|
||||||
|
], callback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
User.getFollowing = function(uid, callback) {
|
User.getFollowing = function(uid, start, end, callback) {
|
||||||
getFollow(uid, 'following:' + uid, callback);
|
getFollow(uid, 'following:' + uid, start, end, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
User.getFollowers = function(uid, callback) {
|
User.getFollowers = function(uid, start, end, callback) {
|
||||||
getFollow(uid, 'followers:' + uid, callback);
|
getFollow(uid, 'followers:' + uid, start, end, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
function getFollow(uid, set, callback) {
|
function getFollow(uid, set, start, end, callback) {
|
||||||
if (!parseInt(uid, 10)) {
|
if (!parseInt(uid, 10)) {
|
||||||
return callback(null, []);
|
return callback(null, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
db.getSetMembers(set, function(err, uids) {
|
db.getSortedSetRevRange(set, start, end, function(err, uids) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
@@ -54,36 +65,11 @@ module.exports = function(User) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
User.getFollowingCount = function(uid, callback) {
|
|
||||||
if (!parseInt(uid, 10)) {
|
|
||||||
return callback(null, 0);
|
|
||||||
}
|
|
||||||
db.setCount('following:' + uid, callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
User.getFollowerCount = function(uid, callback) {
|
|
||||||
if (!parseInt(uid, 10)) {
|
|
||||||
return callback(null, 0);
|
|
||||||
}
|
|
||||||
db.setCount('followers:' + uid, callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
User.getFollowStats = function (uid, callback) {
|
|
||||||
async.parallel({
|
|
||||||
followingCount: function(next) {
|
|
||||||
User.getFollowingCount(uid, next);
|
|
||||||
},
|
|
||||||
followerCount : function(next) {
|
|
||||||
User.getFollowerCount(uid, next);
|
|
||||||
}
|
|
||||||
}, callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
User.isFollowing = function(uid, theirid, callback) {
|
User.isFollowing = function(uid, theirid, callback) {
|
||||||
if (!parseInt(uid, 10) || !parseInt(theirid, 10)) {
|
if (!parseInt(uid, 10) || !parseInt(theirid, 10)) {
|
||||||
return callback(null, false);
|
return callback(null, false);
|
||||||
}
|
}
|
||||||
db.isSetMember('following:' + uid, theirid, callback);
|
db.isSortedSetMember('following:' + uid, theirid, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user