mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-02-28 09:31:17 +01:00
closes #2595
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
"profile_views": "Profile views",
|
||||
"reputation": "Reputation",
|
||||
"favourites":"Favourites",
|
||||
"watched": "Watched",
|
||||
"followers": "Followers",
|
||||
"following": "Following",
|
||||
"signature": "Signature",
|
||||
@@ -68,6 +69,7 @@
|
||||
"follows_no_one": "This user isn't following anyone :(",
|
||||
"has_no_posts": "This user didn't post anything yet.",
|
||||
"has_no_topics": "This user didn't post any topics yet.",
|
||||
"has_no_watched_topics": "This user didn't watch any topics yet.",
|
||||
|
||||
"email_hidden": "Email Hidden",
|
||||
"hidden": "hidden",
|
||||
|
||||
@@ -3,16 +3,6 @@ define('forum/account/followers', ['forum/account/header'], function(header) {
|
||||
|
||||
Followers.init = function() {
|
||||
header.init();
|
||||
|
||||
var yourid = ajaxify.variables.get('yourid'),
|
||||
theirid = ajaxify.variables.get('theirid'),
|
||||
followersCount = ajaxify.variables.get('followersCount');
|
||||
|
||||
|
||||
if (parseInt(followersCount, 10) === 0) {
|
||||
$('#no-followers-notice').removeClass('hide');
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return Followers;
|
||||
|
||||
@@ -7,17 +7,10 @@ define('forum/account/header', function() {
|
||||
};
|
||||
|
||||
function displayAccountMenus() {
|
||||
var yourid = ajaxify.variables.get('yourid'),
|
||||
theirid = ajaxify.variables.get('theirid');
|
||||
|
||||
if (parseInt(yourid, 10) !== 0 && parseInt(yourid, 10) === parseInt(theirid, 10)) {
|
||||
$('#editLink, #settingsLink, #favouritesLink').removeClass('hide');
|
||||
} else {
|
||||
$('.account-sub-links .plugin-link').each(function() {
|
||||
var $this = $(this);
|
||||
$this.toggleClass('hide', $this.hasClass('private'));
|
||||
});
|
||||
}
|
||||
$('.account-sub-links .plugin-link').each(function() {
|
||||
var $this = $(this);
|
||||
$this.toggleClass('hide', $this.hasClass('private'));
|
||||
});
|
||||
}
|
||||
|
||||
function selectActivePill() {
|
||||
|
||||
45
public/src/client/account/watched.js
Normal file
45
public/src/client/account/watched.js
Normal file
@@ -0,0 +1,45 @@
|
||||
'use strict';
|
||||
|
||||
/* globals define, app, socket, utils */
|
||||
define('forum/account/watched', ['forum/account/header', 'forum/infinitescroll'], function(header, infinitescroll) {
|
||||
var AccountTopics = {};
|
||||
|
||||
AccountTopics.init = function() {
|
||||
header.init();
|
||||
|
||||
infinitescroll.init(loadMore);
|
||||
};
|
||||
|
||||
function loadMore(direction) {
|
||||
console.log(direction);
|
||||
if (direction < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
infinitescroll.loadMore('topics.loadMoreFromSet', {
|
||||
set: 'uid:' + $('.account-username-box').attr('data-uid') + ':followed_tids',
|
||||
after: $('.user-topics').attr('data-nextstart')
|
||||
}, function(data, done) {
|
||||
console.log(data);
|
||||
if (data.topics && data.topics.length) {
|
||||
onTopicsLoaded(data.topics, done);
|
||||
$('.user-topics').attr('data-nextstart', data.nextStart);
|
||||
} else {
|
||||
done();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onTopicsLoaded(topics, callback) {
|
||||
infinitescroll.parseAndTranslate('account/watched', 'topics', {topics: topics}, function(html) {
|
||||
$('#topics-container').append(html);
|
||||
html.find('span.timeago').timeago();
|
||||
app.createUserTooltips();
|
||||
utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
|
||||
$(window).trigger('action:topics.loaded');
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
return AccountTopics;
|
||||
});
|
||||
@@ -89,7 +89,7 @@ function getUserDataByUserSlug(userslug, callerUID, callback) {
|
||||
userData.yourid = callerUID;
|
||||
userData.theirid = userData.uid;
|
||||
userData.isSelf = self;
|
||||
userData.showSettings = self || isAdmin;
|
||||
userData.showHidden = self || isAdmin;
|
||||
userData.groups = Array.isArray(results.groups) && results.groups.length ? results.groups[0] : [];
|
||||
userData.disableSignatures = meta.config.disableSignatures !== undefined && parseInt(meta.config.disableSignatures, 10) === 1;
|
||||
userData['email:confirmed'] = !!parseInt(userData['email:confirmed'], 10);
|
||||
@@ -192,7 +192,7 @@ accountsController.getFollowers = function(req, res, next) {
|
||||
getFollow('account/followers', 'followers', req, res, next);
|
||||
};
|
||||
|
||||
function getFollow(route, name, req, res, next) {
|
||||
function getFollow(tpl, name, req, res, next) {
|
||||
var callerUID = req.user ? parseInt(req.user.uid, 10) : 0;
|
||||
var userData;
|
||||
|
||||
@@ -215,40 +215,28 @@ function getFollow(route, name, req, res, next) {
|
||||
userData[name] = users;
|
||||
userData[name + 'Count'] = users.length;
|
||||
|
||||
res.render(route, userData);
|
||||
res.render(tpl, userData);
|
||||
});
|
||||
}
|
||||
|
||||
accountsController.getFavourites = function(req, res, next) {
|
||||
var callerUID = req.user ? parseInt(req.user.uid, 10) : 0;
|
||||
|
||||
getBaseUser(req.params.userslug, callerUID, function(err, userData) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
if (!userData) {
|
||||
return helpers.notFound(req, res);
|
||||
}
|
||||
|
||||
if (parseInt(userData.uid, 10) !== callerUID) {
|
||||
return helpers.notAllowed(req, res);
|
||||
}
|
||||
|
||||
posts.getPostsFromSet('uid:' + userData.uid + ':favourites', callerUID, 0, 9, function(err, favourites) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
userData.posts = favourites.posts;
|
||||
userData.nextStart = favourites.nextStart;
|
||||
|
||||
res.render('account/favourites', userData);
|
||||
});
|
||||
});
|
||||
getFromUserSet('account/favourites', 'favourites', posts.getPostsFromSet, 'posts', req, res, next);
|
||||
};
|
||||
|
||||
accountsController.getPosts = function(req, res, next) {
|
||||
getFromUserSet('account/posts', 'posts', posts.getPostsFromSet, 'posts', req, res, next);
|
||||
};
|
||||
|
||||
accountsController.getWatchedTopics = function(req, res, next) {
|
||||
getFromUserSet('account/watched', 'followed_tids', topics.getTopicsFromSet, 'topics', req, res, next);
|
||||
};
|
||||
|
||||
accountsController.getTopics = function(req, res, next) {
|
||||
getFromUserSet('account/topics', 'topics', topics.getTopicsFromSet, 'topics', req, res, next);
|
||||
};
|
||||
|
||||
|
||||
function getFromUserSet(tpl, set, method, type, req, res, next) {
|
||||
var callerUID = req.user ? parseInt(req.user.uid, 10) : 0;
|
||||
|
||||
getBaseUser(req.params.userslug, callerUID, function(err, userData) {
|
||||
@@ -259,44 +247,19 @@ accountsController.getPosts = function(req, res, next) {
|
||||
if (!userData) {
|
||||
return helpers.notFound(req, res);
|
||||
}
|
||||
posts.getPostsFromSet('uid:' + userData.uid + ':posts', callerUID, 0, 19, function(err, userPosts) {
|
||||
|
||||
method('uid:' + userData.uid + ':' + set, callerUID, 0, 19, function(err, data) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
userData.posts = userPosts.posts;
|
||||
userData.nextStart = userPosts.nextStart;
|
||||
userData[type] = data[type];
|
||||
userData.nextStart = data.nextStart;
|
||||
|
||||
res.render('account/posts', userData);
|
||||
res.render(tpl, userData);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
accountsController.getTopics = function(req, res, next) {
|
||||
var callerUID = req.user ? parseInt(req.user.uid, 10) : 0;
|
||||
|
||||
getBaseUser(req.params.userslug, callerUID, function(err, userData) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
if (!userData) {
|
||||
return helpers.notFound(req, res);
|
||||
}
|
||||
|
||||
var set = 'uid:' + userData.uid + ':topics';
|
||||
topics.getTopicsFromSet(set, callerUID, 0, 19, function(err, userTopics) {
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
userData.topics = userTopics.topics;
|
||||
userData.nextStart = userTopics.nextStart;
|
||||
|
||||
res.render('account/topics', userData);
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function getBaseUser(userslug, callerUID, callback) {
|
||||
user.getUidByUserslug(userslug, function (err, uid) {
|
||||
@@ -326,7 +289,7 @@ function getBaseUser(userslug, callerUID, callback) {
|
||||
results.user.yourid = callerUID;
|
||||
results.user.theirid = uid;
|
||||
results.user.isSelf = parseInt(callerUID, 10) === parseInt(uid, 10);
|
||||
results.user.showSettings = results.user.isSelf || results.isAdmin;
|
||||
results.user.showHidden = results.user.isSelf || results.isAdmin;
|
||||
results.user.profile_links = results.profile_links;
|
||||
callback(null, results.user);
|
||||
});
|
||||
|
||||
@@ -70,6 +70,7 @@ function accountRoutes(app, middleware, controllers) {
|
||||
setupPageRoute(app, '/user/:userslug/topics', middleware, middlewares, controllers.accounts.getTopics);
|
||||
|
||||
setupPageRoute(app, '/user/:userslug/favourites', middleware, accountMiddlewares, controllers.accounts.getFavourites);
|
||||
setupPageRoute(app, '/user/:userslug/watched', middleware, accountMiddlewares, controllers.accounts.getWatchedTopics);
|
||||
setupPageRoute(app, '/user/:userslug/edit', middleware, accountMiddlewares, controllers.accounts.accountEdit);
|
||||
setupPageRoute(app, '/user/:userslug/settings', middleware, accountMiddlewares, controllers.accounts.accountSettings);
|
||||
|
||||
|
||||
@@ -214,7 +214,7 @@ function addRedisAdapter(io) {
|
||||
}
|
||||
|
||||
function callMethod(method, socket, params, callback) {
|
||||
method(socket, params || {}, function(err, result) {
|
||||
method(socket, params, function(err, result) {
|
||||
callback(err ? {message: err.message} : null, result);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -83,6 +83,7 @@ SocketModules.composer.editCheck = function(socket, pid, callback) {
|
||||
};
|
||||
|
||||
SocketModules.composer.renderPreview = function(socket, content, callback) {
|
||||
console.log(content);
|
||||
plugins.fireHook('filter:parse.raw', content, callback);
|
||||
};
|
||||
|
||||
|
||||
@@ -172,7 +172,7 @@ SocketTopics.markAsUnreadForAll = function(socket, tids, callback) {
|
||||
async.each(tids, function(tid, next) {
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
threadTools.exists(tid, next);
|
||||
topics.exists(tid, next);
|
||||
},
|
||||
function(exists, next) {
|
||||
if (!exists) {
|
||||
@@ -409,7 +409,7 @@ SocketTopics.follow = function(socket, tid, callback) {
|
||||
return callback(new Error('[[error:not-logged-in]]'));
|
||||
}
|
||||
|
||||
threadTools.toggleFollow(tid, socket.uid, callback);
|
||||
topics.toggleFollow(tid, socket.uid, callback);
|
||||
};
|
||||
|
||||
SocketTopics.loadMore = function(socket, data, callback) {
|
||||
|
||||
@@ -19,10 +19,6 @@ var winston = require('winston'),
|
||||
|
||||
(function(ThreadTools) {
|
||||
|
||||
ThreadTools.exists = function(tid, callback) {
|
||||
db.isSortedSetMember('topics:tid', tid, callback);
|
||||
};
|
||||
|
||||
ThreadTools.delete = function(tid, uid, callback) {
|
||||
toggleDelete(tid, uid, true, callback);
|
||||
};
|
||||
@@ -75,7 +71,7 @@ var winston = require('winston'),
|
||||
ThreadTools.purge = function(tid, uid, callback) {
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
ThreadTools.exists(tid, next);
|
||||
topics.exists(tid, next);
|
||||
},
|
||||
function(exists, next) {
|
||||
if (!exists) {
|
||||
@@ -229,39 +225,5 @@ var winston = require('winston'),
|
||||
});
|
||||
};
|
||||
|
||||
ThreadTools.toggleFollow = function(tid, uid, callback) {
|
||||
callback = callback || function() {};
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
ThreadTools.exists(tid, next);
|
||||
},
|
||||
function (exists, next) {
|
||||
if (!exists) {
|
||||
return next(new Error('[[error:no-topic]]'));
|
||||
}
|
||||
topics.isFollowing([tid], uid, next);
|
||||
},
|
||||
function (isFollowing, next) {
|
||||
db[isFollowing[0] ? 'setRemove' : 'setAdd']('tid:' + tid + ':followers', uid, function(err) {
|
||||
next(err, !isFollowing[0]);
|
||||
});
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
ThreadTools.follow = function(tid, uid, callback) {
|
||||
callback = callback || function() {};
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
ThreadTools.exists(tid, next);
|
||||
},
|
||||
function (exists, next) {
|
||||
if (!exists) {
|
||||
return next(new Error('[[error:no-topic]]'));
|
||||
}
|
||||
db.setAdd('tid:' + tid + ':followers', uid, next);
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
}(exports));
|
||||
|
||||
@@ -26,6 +26,10 @@ var async = require('async'),
|
||||
require('./topics/tags')(Topics);
|
||||
require('./topics/teaser')(Topics);
|
||||
|
||||
Topics.exists = function(tid, callback) {
|
||||
db.isSortedSetMember('topics:tid', tid, callback);
|
||||
};
|
||||
|
||||
Topics.getTopicData = function(tid, callback) {
|
||||
db.getObject('topic:' + tid, function(err, topic) {
|
||||
if (err || !topic) {
|
||||
|
||||
@@ -148,7 +148,7 @@ module.exports = function(Topics) {
|
||||
return next(err);
|
||||
}
|
||||
if (settings.followTopicsOnCreate) {
|
||||
threadTools.follow(postData.tid, uid, next);
|
||||
Topics.follow(postData.tid, uid, next);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
@@ -193,7 +193,7 @@ module.exports = function(Topics) {
|
||||
function(next) {
|
||||
async.parallel({
|
||||
exists: function(next) {
|
||||
threadTools.exists(tid, next);
|
||||
Topics.exists(tid, next);
|
||||
},
|
||||
locked: function(next) {
|
||||
Topics.isLocked(tid, next);
|
||||
@@ -266,7 +266,7 @@ module.exports = function(Topics) {
|
||||
}
|
||||
|
||||
if (results.settings.followTopicsOnReply) {
|
||||
threadTools.follow(postData.tid, uid);
|
||||
Topics.follow(postData.tid, uid);
|
||||
}
|
||||
postData.index = results.postIndex - 1;
|
||||
postData.favourited = false;
|
||||
|
||||
@@ -13,6 +13,68 @@ var async = require('async'),
|
||||
|
||||
module.exports = function(Topics) {
|
||||
|
||||
Topics.toggleFollow = function(tid, uid, callback) {
|
||||
callback = callback || function() {};
|
||||
var isFollowing;
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
Topics.exists(tid, next);
|
||||
},
|
||||
function (exists, next) {
|
||||
if (!exists) {
|
||||
return next(new Error('[[error:no-topic]]'));
|
||||
}
|
||||
Topics.isFollowing([tid], uid, next);
|
||||
},
|
||||
function (_isFollowing, next) {
|
||||
isFollowing = _isFollowing[0];
|
||||
if (isFollowing) {
|
||||
Topics.unfollow(tid, uid, next);
|
||||
} else {
|
||||
Topics.follow(tid, uid, next);
|
||||
}
|
||||
},
|
||||
function(next) {
|
||||
next(null, !isFollowing);
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
Topics.follow = function(tid, uid, callback) {
|
||||
callback = callback || function() {};
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
Topics.exists(tid, next);
|
||||
},
|
||||
function (exists, next) {
|
||||
if (!exists) {
|
||||
return next(new Error('[[error:no-topic]]'));
|
||||
}
|
||||
db.setAdd('tid:' + tid + ':followers', uid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetAdd('uid:' + uid + ':followed_tids', Date.now(), tid, next);
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
Topics.unfollow = function(tid, uid, callback) {
|
||||
callback = callback || function() {};
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
Topics.exists(tid, next);
|
||||
},
|
||||
function (exists, next) {
|
||||
if (!exists) {
|
||||
return next(new Error('[[error:no-topic]]'));
|
||||
}
|
||||
db.setRemove('tid:' + tid + ':followers', uid, next);
|
||||
},
|
||||
function(next) {
|
||||
db.sortedSetRemove('uid:' + uid + ':followed_tids', tid, next);
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
Topics.isFollowing = function(tids, uid, callback) {
|
||||
if (!Array.isArray(tids)) {
|
||||
@@ -23,7 +85,7 @@ module.exports = function(Topics) {
|
||||
}
|
||||
var keys = tids.map(function(tid) {
|
||||
return 'tid:' + tid + ':followers';
|
||||
})
|
||||
});
|
||||
db.isMemberOfSets(keys, uid, callback);
|
||||
};
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ module.exports = function(Topics) {
|
||||
var postData;
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
threadTools.exists(tid, next);
|
||||
Topics.exists(tid, next);
|
||||
},
|
||||
function(exists, next) {
|
||||
if (!exists) {
|
||||
|
||||
@@ -21,7 +21,7 @@ var db = require('./database'),
|
||||
schemaDate, thisSchemaDate,
|
||||
|
||||
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema
|
||||
latestSchema = Date.UTC(2015, 0, 9);
|
||||
latestSchema = Date.UTC(2015, 0, 13);
|
||||
|
||||
Upgrade.check = function(callback) {
|
||||
db.get('schemaDate', function(err, value) {
|
||||
@@ -525,8 +525,48 @@ Upgrade.upgrade = function(callback) {
|
||||
winston.info('[2015/01/09] Creating fullname:uid hash skipped');
|
||||
next();
|
||||
}
|
||||
}
|
||||
},
|
||||
function(next) {
|
||||
thisSchemaDate = Date.UTC(2015, 0, 13);
|
||||
if (schemaDate < thisSchemaDate) {
|
||||
winston.info('[2015/01/13] Creating uid:followed_tids sorted set');
|
||||
|
||||
db.getSortedSetRange('topics:tid', 0, -1, function(err, tids) {
|
||||
if (err) {
|
||||
winston.error('[2014/01/13] Error encountered while Creating uid:followed_tids sorted set');
|
||||
return next(err);
|
||||
}
|
||||
|
||||
var now = Date.now();
|
||||
|
||||
async.eachLimit(tids, 50, function(tid, next) {
|
||||
db.getSetMembers('tid:' + tid + ':followers', function(err, uids) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
async.eachLimit(uids, 50, function(uid, next) {
|
||||
if (parseInt(uid, 10)) {
|
||||
db.sortedSetAdd('uid:' + uid + ':followed_tids', now, tid, next);
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}, next);
|
||||
});
|
||||
}, function(err) {
|
||||
if (err) {
|
||||
winston.error('[2015/01/13] Error encountered while Creating uid:followed_tids sorted set');
|
||||
return next(err);
|
||||
}
|
||||
winston.info('[2015/01/13] Creating uid:followed_tids sorted set done');
|
||||
Upgrade.update(thisSchemaDate, next);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
winston.info('[2015/01/13] Creating uid:followed_tids sorted set skipped');
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
// Add new schema updates here
|
||||
// IMPORTANT: REMEMBER TO UPDATE VALUE OF latestSchema IN LINE 22!!!
|
||||
|
||||
@@ -76,7 +76,7 @@ module.exports = function(User) {
|
||||
function(next) {
|
||||
var keys = [
|
||||
'uid:' + uid + ':notifications:read', 'uid:' + uid + ':notifications:unread',
|
||||
'uid:' + uid + ':favourites', 'user:' + uid + ':settings',
|
||||
'uid:' + uid + ':favourites', 'uid:' + uid + ':followed_tids', 'user:' + uid + ':settings',
|
||||
'uid:' + uid + ':topics', 'uid:' + uid + ':posts',
|
||||
'uid:' + uid + ':chats', 'uid:' + uid + ':chats:unread',
|
||||
'uid:' + uid + ':ip', 'uid:' + uid + ':upvote', 'uid:' + uid + ':downvote',
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"^user/.*/followers": "account/followers",
|
||||
"^user/.*/settings": "account/settings",
|
||||
"^user/.*/favourites": "account/favourites",
|
||||
"^user/.*/watched": "account/watched",
|
||||
"^user/.*/posts": "account/posts",
|
||||
"^user/.*/topics": "account/topics",
|
||||
"^user/[^\/]+": "account/profile",
|
||||
|
||||
Reference in New Issue
Block a user