diff --git a/public/js/main_0.0.3.js b/public/js/main_0.0.3.js index 2519a4f66d..8db2d2769d 100644 --- a/public/js/main_0.0.3.js +++ b/public/js/main_0.0.3.js @@ -277,34 +277,32 @@ $(document).ready(function() { $('#long-instructions').hide(); }); - var upvoteHandler = function () { - var id = storyId; - $('#upvote').unbind('click'); + function upvoteHandler(e) { + e.preventDefault(); + var upvoteBtn = this; + var id = upvoteBtn.id; + var upVotes = $(upvoteBtn).data().upVotes; + var username = typeof username !== 'undefined' ? username : ''; var alreadyUpvoted = false; for (var i = 0; i < upVotes.length; i++) { - if (upVotes[i].upVotedBy === B3BA669EC5C1DD70FB478221E067A7E1B686929C569F5E73561B69C8F42129B) { + if (upVotes[i].upVotedBy === username) { alreadyUpvoted = true; break; } } if (!alreadyUpvoted) { - $.post('/stories/upvote', - { - data: { - id: id - } + $.post('/stories/upvote', { id: id }) + .fail(function(xhr, textStatus, errorThrown) { + $(upvoteBtn).bind('click', upvoteHandler); }) - .fail(function (xhr, textStatus, errorThrown) { - $('#upvote').bind('click', upvoteHandler); - }) - .done(function (data, textStatus, xhr) { - $('#upvote').text('Upvoted!').addClass('disabled'); + .done(function(data, textStatus, xhr) { + $(upvoteBtn).text('Upvoted!').addClass('disabled'); $('#storyRank').text(data.rank + " points"); }); } }; - $('#upvote').on('click', upvoteHandler); + $('#story-list').on('click', 'button.btn-upvote', upvoteHandler); var storySubmitButtonHandler = function storySubmitButtonHandler() { @@ -322,7 +320,6 @@ $(document).ready(function() { description: description, storyMetaDescription: storyMetaDescription, rank: 1, - comments: [], image: storyImage } }) @@ -336,29 +333,6 @@ $(document).ready(function() { $('#story-submit').on('click', storySubmitButtonHandler); - var commentSubmitButtonHandler = function commentSubmitButtonHandler() { - $('#comment-button').unbind('click'); - var data = $('#comment-box').val(); - - $('#comment-button').attr('disabled', 'disabled'); - $.post('/stories/comment/', - { - data: { - associatedPost: storyId, - originalStoryLink: originalStoryLink, - originalStoryAuthorEmail: originalStoryAuthorEmail, - body: data - } - }) - .fail(function (xhr, textStatus, errorThrown) { - $('#comment-button').attr('disabled', false); - $('#comment-button').bind('click', commentSubmitButtonHandler); - }) - .done(function (data, textStatus, xhr) { - window.location.reload(); - }); - }; - //fakeiphone positioning hotfix if($('.iphone-position').html() !==undefined || $('.iphone').html() !== undefined){ var startIphonePosition = parseInt($('.iphone-position').css('top').replace('px', '')); @@ -405,9 +379,7 @@ $(document).ready(function() { lockTop(initOff); }); } - } - - $('#comment-button').on('click', commentSubmitButtonHandler); + } }); var profileValidation = angular.module('profileValidation', diff --git a/server/boot/story.js b/server/boot/story.js index 9b7e40fe15..c90fbff4b1 100755 --- a/server/boot/story.js +++ b/server/boot/story.js @@ -1,5 +1,4 @@ var Rx = require('rx'), - nodemailer = require('nodemailer'), assign = require('object.assign'), sanitizeHtml = require('sanitize-html'), moment = require('moment'), @@ -19,23 +18,6 @@ var unDasherize = utils.unDasherize; var dasherize = utils.dasherize; var getURLTitle = utils.getURLTitle; -var transporter = nodemailer.createTransport({ - service: 'Mandrill', - auth: { - user: secrets.mandrill.user, - pass: secrets.mandrill.password - } -}); - -function sendMailWhillyNilly(mailOptions) { - transporter.sendMail(mailOptions, function(err) { - if (err) { - console.log('err sending mail whilly nilly', err); - console.log('logging err but not carring'); - } - }); -} - function hotRank(timeValue, rank) { /* * Hotness ranking algorithm: http://amix.dk/blog/post/19588 @@ -69,7 +51,6 @@ module.exports = function(app) { var router = app.loopback.Router(); var User = app.models.User; var findUserById = observeMethod(User, 'findById'); - var findOneUser = observeMethod(User, 'findOne'); var Story = app.models.Story; var findStory = observeMethod(Story, 'find'); @@ -77,14 +58,7 @@ module.exports = function(app) { var findStoryById = observeMethod(Story, 'findById'); var countStories = observeMethod(Story, 'count'); - var Comment = app.models.Comment; - var findCommentById = observeMethod(Comment, 'findById'); - - router.get('/stories/hotStories', hotJSON); - router.get('/stories/comments/:id', comments); - router.post('/stories/comment/', commentSubmit); - router.post('/stories/comment/:id/comment', commentOnCommentSubmit); - router.put('/stories/comment/:id/edit', commentEdit); + router.get('/news/hot', hotJSON); router.get('/stories/submit', submitNew); router.get('/stories/submit/new-story', preSubmit); router.post('/stories/preliminary', newStory); @@ -194,7 +168,6 @@ module.exports = function(app) { description: story.description, rank: story.upVotes.length, upVotes: story.upVotes, - comments: story.comments, id: story.id, timeAgo: moment(story.timePosted).fromNow(), image: story.image, @@ -224,7 +197,6 @@ module.exports = function(app) { rank: 1, upVotes: 1, author: 1, - comments: 1, image: 1, storyLink: 1, metaDescription: 1, @@ -250,7 +222,7 @@ module.exports = function(app) { } function upvote(req, res, next) { - var id = req.body.data.id; + const { id } = req.body; var story$ = findStoryById(id).shareReplay(); story$.flatMap(function(story) { @@ -284,16 +256,6 @@ module.exports = function(app) { ); } - function comments(req, res, next) { - var id = req.params.id; - findCommentById(id).subscribe( - function(comment) { - res.send(comment); - }, - next - ); - } - function newStory(req, res, next) { if (!req.user) { return next(new Error('Must be logged in')); @@ -407,7 +369,6 @@ module.exports = function(app) { username: req.user.username, email: req.user.email }, - comments: [], image: data.image, storyLink: storyLink, metaDescription: data.storyMetaDescription, @@ -428,174 +389,4 @@ module.exports = function(app) { next ); } - - function commentSubmit(req, res, next) { - var data = req.body.data; - if (!req.user) { - return next(new Error('Not authorized')); - } - var sanitizedBody = cleanData(data.body); - - if (data.body !== sanitizedBody) { - req.flash('errors', { - msg: 'HTML is not allowed' - }); - return res.send(true); - } - var comment = new Comment({ - associatedPost: data.associatedPost, - originalStoryLink: data.originalStoryLink, - originalStoryAuthorEmail: data.originalStoryAuthorEmail, - body: sanitizedBody, - rank: 0, - upvotes: 0, - author: { - picture: req.user.picture, - userId: req.user.id, - username: req.user.username, - email: req.user.email - }, - comments: [], - topLevel: true, - commentOn: Date.now() - }); - - commentSave(comment, findStoryById).subscribe( - function() {}, - next, - function() { - res.send(true); - } - ); - } - - function commentOnCommentSubmit(req, res, next) { - var data = req.body.data; - if (!req.user) { - return next(new Error('Not authorized')); - } - - var sanitizedBody = cleanData(data.body); - - if (data.body !== sanitizedBody) { - req.flash('errors', { - msg: 'HTML is not allowed' - }); - return res.send(true); - } - - var comment = new Comment({ - associatedPost: data.associatedPost, - body: sanitizedBody, - rank: 0, - upvotes: 0, - originalStoryLink: data.originalStoryLink, - originalStoryAuthorEmail: data.originalStoryAuthorEmail, - author: { - picture: req.user.picture, - userId: req.user.id, - username: req.user.username, - email: req.user.email - }, - comments: [], - topLevel: false, - commentOn: Date.now() - }); - commentSave(comment, findCommentById).subscribe( - function() {}, - next, - function() { - res.send(true); - } - ); - } - - function commentEdit(req, res, next) { - findCommentById(req.params.id) - .doOnNext(function(comment) { - if (!req.user && comment.author.userId !== req.user.id) { - throw new Error('Not authorized'); - } - }) - .flatMap(function(comment) { - var sanitizedBody = cleanData(req.body.body); - if (req.body.body !== sanitizedBody) { - req.flash('errors', { - msg: 'HTML is not allowed' - }); - } - comment.body = sanitizedBody; - comment.commentOn = Date.now(); - return saveInstance(comment); - }) - .subscribe( - function() { - res.send(true); - }, - next - ); - } - - function commentSave(comment, findContextById) { - return saveInstance(comment) - .flatMap(function(comment) { - // Based on the context retrieve the parent - // object of the comment (Story/Comment) - return findContextById(comment.associatedPost); - }) - .flatMap(function(associatedContext) { - if (associatedContext) { - associatedContext.comments.push(comment.id); - } - // NOTE(berks): saveInstance is safe - // it will automatically call onNext with null and onCompleted if - // argument is falsey or has no method save - return saveInstance(associatedContext); - }) - .flatMap(function(associatedContext) { - // Find the author of the parent object - // if no username - var username = associatedContext && associatedContext.author ? - associatedContext.author.username : - null; - - var query = { where: { username: username } }; - return findOneUser(query); - }) - // if no user is found we don't want to hit the doOnNext - // filter here will call onCompleted without running through the following - // steps - .filter(function(user) { - return !!user; - }) - // if this is called user is guarenteed to exits - // this is a side effect, hence we use do/tap observable methods - .doOnNext(function(user) { - // If the emails of both authors differ, - // only then proceed with email notification - if ( - comment.author && - comment.author.email && - user.email && - (comment.author.email !== user.email) - ) { - sendMailWhillyNilly({ - to: user.email, - from: 'Team@freecodecamp.com', - subject: comment.author.username + - ' replied to your post on Camper News', - text: [ - 'Just a quick heads-up: ', - comment.author.username, - ' replied to you on Camper News.', - 'You can keep this conversation going.', - 'Just head back to the discussion here: ', - 'http://freecodecamp.com/stories/', - comment.originalStoryLink, - '- the Free Code Camp Volunteer Team' - ].join('\n') - }); - } - }); - } }; diff --git a/server/views/stories/comments.jade b/server/views/stories/comments.jade deleted file mode 100755 index e8f1372df0..0000000000 --- a/server/views/stories/comments.jade +++ /dev/null @@ -1,164 +0,0 @@ -.text-left - div#comment-list - - script(src="https://cdn.jsdelivr.net/ramda/0.10.0/ramda.min.js") - script(src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.9.0/moment.min.js") - script. - var sentinel = 0; - var renderComments = function renderComments(comments, containerSelector, level) { - var commentDetails; - R.forEach(function displayComments(comment) { - - $.ajax({ - type: 'GET', - url: '/stories/comments/' + comment, - error: function (xhr, textStatus, errorThrown) { - commentDetails = { - error: true, - body: 'There seems to be a problem fetching this comment.' - } - }, - success: function (data, textStatus, xhr) { - commentDetails = data; - var div = document.createElement('div'); - var editButton = ""; - // todo - if (commentDetails.author.username === DF105CFA89562196E702912B3818C6A5B46E80D262442FDF29976621E5AF0D23) { - if ((Date.now() - commentDetails.commentOn) < 600000){ - editButton = "Edit · "; - } - } - $(div) - .html( - '
' + commentDetails.body + '
' + - '' + - '' +
- "Reply · " +
- editButton +
- "commented " + moment(commentDetails.commentOn).fromNow() + " by " +
- "@" + commentDetails.author.username + "" +
- ' ' +
- '
' + - '