refactoring comment submit method

This commit is contained in:
Sacha Greif 2014-12-24 10:13:48 +09:00
parent a39569e883
commit f2760f9168
4 changed files with 169 additions and 70 deletions

View file

@ -6,39 +6,72 @@ Template[getTemplate('comment_form')].helpers({
Template[getTemplate('comment_form')].events({
'submit form': function(e, instance){
var $commentForm = instance.$('#comment');
e.preventDefault();
$(e.target).addClass('disabled');
clearSeenMessages();
var content = $commentForm.val();
var comment = {};
var $commentForm = instance.$('#comment');
var body = $commentForm.val();
if(getCurrentTemplate() == 'comment_reply'){
// child comment
comment = {
postId: parentComment.postId,
parentCommentId: parentComment._id,
body: body
};
var parentComment = this.comment;
Meteor.call('comment', parentComment.postId, parentComment._id, content, function(error, newComment){
if(error){
Meteor.call('submitComment', comment, function(error, newComment){
if (error) {
console.log(error);
flashMessage(error.reason, "error");
}else{
} else {
trackEvent("newComment", newComment);
Router.go('post_page_comment', {
_id: parentComment.postId,
commentId: newComment._id
});
}
});
}else{
// root comment
var post = postObject;
Meteor.call('comment', post._id, null, content, function(error, newComment){
comment = {
postId: post._id,
body: body
}
Meteor.call('submitComment', comment, function(error, newComment){
if(error){
console.log(error);
flashMessage(error.reason, "error");
}else{
trackEvent("newComment", newComment);
Session.set('scrollToCommentId', newComment._id);
$commentForm.val('');
}
});
}
}

View file

@ -87,6 +87,10 @@ Comments.allow({
remove: canEditById
});
// ------------------------------------------------------------------------------------------- //
// ------------------------------------------ Hooks ------------------------------------------ //
// ------------------------------------------------------------------------------------------- //
Comments.before.insert(function (userId, doc) {
if(Meteor.isServer)
doc.htmlBody = sanitize(marked(doc.body));
@ -100,76 +104,133 @@ Comments.before.update(function (userId, doc, fieldNames, modifier, options) {
}
});
commentAfterSubmitMethodCallbacks.push(function (comment) {
var userId = comment.userId,
commentAuthor = Meteor.users.findOne(userId);
// increment comment count
Meteor.users.update({_id: userId}, {
$inc: {'commentCount': 1}
});
// update post
Posts.update(comment.postId, {
$inc: {commentCount: 1},
$set: {lastCommentedAt: new Date()},
$addToSet: {commenters: userId}
});
// upvote comment
Meteor.call('upvoteComment', comment);
});
// ------------------------------------------------------------------------------------------- //
// -------------------------------------- Submit Comment ------------------------------------- //
// ------------------------------------------------------------------------------------------- //
submitComment = function (comment) {
var userId = comment.userId; // at this stage, a userId is expected
// ------------------------------ Checks ------------------------------ //
// Don't allow empty comments
if (!comment.body)
throw new Meteor.Error(704,i18n.t('your_comment_is_empty'));
// ------------------------------ Properties ------------------------------ //
var defaultProperties = {
createdAt: new Date(),
postedAt: new Date(),
upvotes: 0,
downvotes: 0,
baseScore: 0,
score: 0,
author: getDisplayNameById(userId)
};
comment = _.extend(defaultProperties, comment);
// ------------------------------ Callbacks ------------------------------ //
// run all post submit server callbacks on comment object successively
comment = commentSubmitMethodCallbacks.reduce(function(result, currentFunction) {
return currentFunction(result);
}, comment);
// -------------------------------- Insert -------------------------------- //
comment._id = Comments.insert(comment);
// --------------------- Server-side Async Callbacks --------------------- //
// run all post submit server callbacks on comment object successively
if (Meteor.isServer) {
Meteor.setTimeout(function () { // use setTimeout to avoid holding up client
comment = commentAfterSubmitMethodCallbacks.reduce(function(result, currentFunction) {
return currentFunction(result);
}, comment);
}, 1);
}
return comment;
}
// ------------------------------------------------------------------------------------------- //
// ----------------------------------------- Methods ----------------------------------------- //
// ------------------------------------------------------------------------------------------- //
Meteor.methods({
comment: function(postId, parentCommentId, text){
submitComment: function(comment){
// required properties:
// postId
// content
// optional properties:
// parentCommentId
var user = Meteor.user(),
post = Posts.findOne(postId),
postUser = Meteor.users.findOne(post.userId),
timeSinceLastComment = timeSinceLast(user, Comments),
commentInterval = Math.abs(parseInt(getSetting('commentInterval',15))),
now = new Date();
hasAdminRights = isAdmin(user);
// ------------------------------ Checks ------------------------------ //
// check that user can comment
if (!user || !canComment(user))
throw new Meteor.Error(i18n.t('you_need_to_login_or_be_invited_to_post_new_comments'));
// check that user waits more than 15 seconds between comments
if(!this.isSimulation && (timeSinceLastComment < commentInterval))
throw new Meteor.Error(704, i18n.t('please_wait')+(commentInterval-timeSinceLastComment)+i18n.t('seconds_before_commenting_again'));
// Don't allow empty comments
if (!text)
throw new Meteor.Error(704,i18n.t('your_comment_is_empty'));
var comment = {
postId: postId,
body: text,
userId: user._id,
createdAt: now,
postedAt: now,
upvotes: 0,
downvotes: 0,
baseScore: 0,
score: 0,
author: getDisplayName(user)
};
// ------------------------------ Rate Limiting ------------------------------ //
if(parentCommentId)
comment.parentCommentId = parentCommentId;
if (!hasAdminRights) {
var timeSinceLastComment = timeSinceLast(user, Comments),
commentInterval = Math.abs(parseInt(getSetting('commentInterval',15)));
// check that user waits more than 15 seconds between comments
if((timeSinceLastComment < commentInterval))
throw new Meteor.Error(704, i18n.t('please_wait')+(commentInterval-timeSinceLastComment)+i18n.t('seconds_before_commenting_again'));
}
// ------------------------------ Callbacks ------------------------------ //
// ------------------------------ Properties ------------------------------ //
// run all post submit server callbacks on comment object successively
comment = commentSubmitMethodCallbacks.reduce(function(result, currentFunction) {
return currentFunction(result);
}, comment);
// admin-only properties
// userId
// -------------------------------- Insert ------------------------------- //
// if user is not admin, clear restricted properties
if (!hasAdminRights) {
delete post.userId;
}
comment._id = Comments.insert(comment);
// if no userId has been set, default to current user id
if (!comment.userId) {
comment.userId = user._id
}
// ------------------------------ Callbacks ------------------------------ //
// run all post submit server callbacks on comment object successively
comment = commentAfterSubmitMethodCallbacks.reduce(function(result, currentFunction) {
return currentFunction(result);
}, comment);
// increment comment count
Meteor.users.update({_id: user._id}, {
$inc: {'commentCount': 1}
});
Posts.update(postId, {
$inc: {commentCount: 1},
$set: {lastCommentedAt: now},
$addToSet: {commenters: user._id}
});
Meteor.call('upvoteComment', comment);
return comment;
return submitComment(comment);
},
removeComment: function(commentId){
var comment = Comments.findOne(commentId);

View file

@ -291,6 +291,7 @@ checkForPostsWithSameUrl = function (url) {
currentPost = function () {
return Posts.findOne(Router.current().data()._id);
}
// ------------------------------------------------------------------------------------------- //
// ------------------------------------------ Hooks ------------------------------------------ //
// ------------------------------------------------------------------------------------------- //
@ -329,6 +330,7 @@ submitPost = function (post) {
var userId = post.userId, // at this stage, a userId is expected
user = Meteor.users.findOne(userId);
// ------------------------------ Checks ------------------------------ //
// check that a title was provided
@ -369,12 +371,12 @@ submitPost = function (post) {
return currentFunction(result);
}, post);
// ------------------------------ Insert ------------------------------ //
// -------------------------------- Insert ------------------------------- //
// console.log(post)
post._id = Posts.insert(post);
// ------------------------------ Server-Side Callbacks ------------------------------ //
// --------------------- Server-Side Async Callbacks --------------------- //
if (Meteor.isServer) {
Meteor.setTimeout(function () { // use setTimeout to avoid holding up client
@ -382,7 +384,8 @@ submitPost = function (post) {
post = postAfterSubmitMethodCallbacks.reduce(function(result, currentFunction) {
return currentFunction(result);
}, post);
}, 1);}
}, 1);
}
return post;
}
@ -419,19 +422,21 @@ Meteor.methods({
// --------------------------- Rate Limiting -------------------------- //
var timeSinceLastPost=timeSinceLast(user, Posts),
if(!hasAdminRights){
var timeSinceLastPost=timeSinceLast(user, Posts),
numberOfPostsInPast24Hours=numberOfItemsInPast24Hours(user, Posts),
postInterval = Math.abs(parseInt(getSetting('postInterval', 30))),
maxPostsPer24Hours = Math.abs(parseInt(getSetting('maxPostsPerDay', 30)));
if(!hasAdminRights){
// check that user waits more than X seconds between posts
if(!this.isSimulation && timeSinceLastPost < postInterval)
if(timeSinceLastPost < postInterval)
throw new Meteor.Error(604, i18n.t('please_wait')+(postInterval-timeSinceLastPost)+i18n.t('seconds_before_posting_again'));
// check that the user doesn't post more than Y posts per day
if(!this.isSimulation && numberOfPostsInPast24Hours > maxPostsPer24Hours)
if(numberOfPostsInPast24Hours > maxPostsPer24Hours)
throw new Meteor.Error(605, i18n.t('sorry_you_cannot_submit_more_than')+maxPostsPer24Hours+i18n.t('posts_per_day'));
}
// ------------------------------ Properties ------------------------------ //

View file

@ -14,7 +14,7 @@ commentAfterSubmitMethodCallbacks.push(function (comment) {
if(Meteor.isServer){
var parentCommentId = comment.parentCommentId;
var user = Meteor.user();
var user = Meteor.users.findOne(comment.userId);
var post = Posts.findOne(comment.postId);
var postUser = Meteor.users.findOne(post.userId);