From d52525f1f4a26b9cf7b69eef2c127d88a31a6588 Mon Sep 17 00:00:00 2001 From: benmcmahon100 Date: Sat, 1 Aug 2015 00:47:39 +0100 Subject: [PATCH 1/5] Non-tested slot machine challenges. Leaving out one challenge as it will require slot machine images to be created and hosted in a static location --- seed/challenges/basic-javascript.json | 34 +++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/seed/challenges/basic-javascript.json b/seed/challenges/basic-javascript.json index aea6a75989..cd6d3b60d0 100644 --- a/seed/challenges/basic-javascript.json +++ b/seed/challenges/basic-javascript.json @@ -448,7 +448,7 @@ "Let's now go create a nested array called myArray" ], "tests":[ - "assert((function(){if(typeof(myArray) !== 'undefined' && typeof(myArray) === 'object' && typeof(myArray[0]) !== 'undefined' && typeof(myArray) === 'object'){return(true);}else{return(false);}})(), 'myArray should contain at least one array');" + "assert((function(){if(typeof(myArray) !== 'undefined' && typeof(myArray) === 'object' && typeof(myArray[0]) !== 'undefined' && typeof(myArray[0]) === 'object' && editor.getValue().match(/[[]]/g).length >= 1){return(true);}else{return(false);}})(), 'myArray should contain at least one array');" ], "challengeSeed":[ "var myArray = [];", @@ -548,7 +548,7 @@ "//console.log(removed); //Gives 3", "", "var myArray = ['John', 23, ['cat', 2]];", - "var removed = _;//This should be ['cat', 2] and myArray should now be ['John', 23]", + "var removed = myArray;//This should be ['cat', 2] and myArray should now be ['John', 23]", "", "", "(function(y, z){return('myArray = ' + JSON.stringify(y) + ' & removed = ' + JSON.stringify(z));})(myArray, removed);" @@ -566,7 +566,7 @@ "Let's take the code we had last time and push this value to the end: ['dog', 3] " ], "tests": [ - "assert((function(d){if(d[2] != undefined && d[0] == 'John' && d[1] == 23 && d[2][0] == 'dog' && d[2][1] == 3){return(true);}else{return(false);}})(myArray), 'myArray should only have the first two values left([\"John\", 23, [\"dog\", 3]])');" + "assert((function(d){if(d[2] != undefined && d[0] == 'John' && d[1] == 23 && d[2][0] == 'dog' && d[2][1] == 3 && d[2].length == 2){return(true);}else{return(false);}})(myArray), 'myArray should only have the first two values left([\"John\", 23, [\"dog\", 3]])');" ], "challengeSeed": [ "var myArray = ['John', 23, ['cat', 2]];", @@ -595,7 +595,7 @@ ], "challengeSeed": [ "var myArray = ['John', 23, ['dog', 3]];", - "var removed = _;//This should be ['John'] and myArray should now be ['John', 23]", + "var removed = myArray;//This should be ['John'] and myArray should now be ['John', 23]", "", "", "(function(y, z){return('myArray = ' + JSON.stringify(y) + ' & removed = ' + JSON.stringify(z));})(myArray, removed);" @@ -644,7 +644,7 @@ "Let's try creating and calling a function now called myFunction" ], "tests":[ - "assert((function(){if(typeof(f) !== 'undefined' && typeof(f) === 'number' && f === 9){return(true);}else{return(false);}})(), 'Your function should return the value of a + b');" + "assert((function(){if(typeof(f) !== 'undefined' && typeof(f) === 'number' && f === a + b && editor.getValue().match(RegExp('return\\\\(a\\\\+b\\\\)', 'g')).length >= 1){return(true);}else{return(false);}})(), 'Your function should return the value of a + b');" ], "challengeSeed":[ "var a = 4;", @@ -726,7 +726,7 @@ "" ], "tests":[ - "assert(myDog.bark != undefined, 'The property tails should have been deleted');", + "assert(myDog.bark != undefined, 'You should have added the property bark to myDog');", "assert(myDog.tails == undefined, 'The property tails should have been deleted');" ], "challengeSeed":[ @@ -740,9 +740,9 @@ "//Re-create myDog", "", "var myDog = {", - " \"name\": _,", - " \"legs\": _,", - " \"tails\": _,", + " \"name\": 'Camper',", + " \"legs\": 4,", + " \"tails\": 1,", " \"friends\": []", "};", "", @@ -1021,7 +1021,7 @@ ], "tests":[ "assert(test === 2, 'Your RegEx should have found two numbers in the testString');", - "assert(editor.getValue().match(/\\/\\\\d\\+\\//gi), 'You should be using the following expression /\\d+/gi to find the numbers in the testString');" + "assert(editorValue.match(/\\/\\\\d\\+\\//gi), 'You should be using the following expression /\\d+/gi to find the numbers in the testString');" ], "challengeSeed":[ "var test = (function(){", @@ -1052,7 +1052,7 @@ ], "tests":[ "assert(test === 7, 'Your RegEx should have found seven spaces in the testString');", - "assert(editor.getValue().match(/\\/\\\\s\\+\\//gi), 'You should be using the following expression /\\s+/gi to find the spaces in the testString');" + "assert(editorValue.match(/\\/\\\\s\\+\\//gi), 'You should be using the following expression /\\s+/gi to find the spaces in the testString');" ], "challengeSeed":[ "var test = (function(){", @@ -1083,14 +1083,14 @@ " Math.floor(Math.random() * (5 - 1 + 1)) + 1; " ], "tests":[ - "assert(typeof(runSlots($(''))[0]) == 'number', 'SlotOne should be a random number');", - "assert(typeof(runSlots($(''))[1]) == 'number', 'SlotTwo should be a random number');", - "assert(typeof(runSlots($(''))[2]) == 'number', 'SlotThree should be a random number');", - "assert(editor.getValue().match(/Math.floor\\(Math.random\\(\\) \\* \\(5 \\- 1 \\+ 1\\)\\) \\+ 1/g).length === 3);" + "assert(typeof(runSlots($('.slot'))[0]) == 'number', 'SlotOne should be a random number');", + "assert(typeof(runSlots($('.slot'))[1]) == 'number', 'SlotTwo should be a random number');", + "assert(typeof(runSlots($('.slot'))[2]) == 'number', 'SlotThree should be a random number');", + "assert(editorValue.match(/Math.floor\\(Math.random\\(\\) \\* \\(5 \\- 1 \\+ 1\\)\\) \\+ 1/g).length === 3);" ], "challengeSeed":[ "fccss", - " function runSlots(slots){", + " function runSlots(){", " var slotOne;", " var slotTwo;", " var slotThree;", @@ -1111,7 +1111,7 @@ "", " $(document).ready(function(){", " $('.go').click(function(){", - " runSlots(slots);", + " runSlots();", " });", " });", "fcces", From ee8776feb3221b14fbf9f3809a5508c07cadc258 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Fri, 31 Jul 2015 19:51:21 -0700 Subject: [PATCH 2/5] removes comments moves upvote to main page add more info page closes #955 --- public/js/main_0.0.3.js | 56 ++---- server/boot/story.js | 213 +---------------------- server/views/stories/comments.jade | 164 ----------------- server/views/stories/hot-stories.jade | 27 ++- server/views/stories/index.jade | 4 +- server/views/stories/new-stories.jade | 55 ------ server/views/stories/news-nav.jade | 4 +- server/views/stories/search-stories.jade | 0 server/views/stories/show.jade | 42 +---- server/views/stories/submit-story.jade | 5 - 10 files changed, 48 insertions(+), 522 deletions(-) delete mode 100755 server/views/stories/comments.jade delete mode 100644 server/views/stories/new-stories.jade delete mode 100644 server/views/stories/search-stories.jade 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.author.username + '' + - '' + - '
' + - '
' + - '
' + - '

' + commentDetails.body + '

' + - '
' + - '
' + - "Reply · " + - editButton + - "commented " + moment(commentDetails.commentOn).fromNow() + " by " + - "@" + commentDetails.author.username + "" + - '
' + - '
' + - '
' + - '
' + - '
' - ) - .addClass('comment-wrapper positive-10') - .appendTo($(containerSelector)); - - sentinel += commentDetails.comments.length; - - renderComments(commentDetails.comments, '.comment_' + commentDetails.id, ++level); - - }, - complete: function () { - sentinel--; - if (!sentinel) { - $('.comment-a-comment').on('click', 'a', function() { - var editOrComment = 'comment'; - if ($(this).hasClass("edit-btn")){ - editOrComment = 'edit'; - } - if (!isLoggedIn) { - window.location.href = '/signin'; - return; - } - $(this).unbind('click'); - $('.comment-to-comment-formgroup').empty(); - $('#initial-comment-submit').addClass('hidden-element'); - var div = document.createElement('div'); - var commentId = $(this).attr('id'); - $(div).html( - "
" + - '
' + - "
" + - "" + - "" + - "" + - "" + - "
" + - "
" + - "
" + - "
" - ) - .addClass('row') - .appendTo($(this).closest('.media-body-wrapper')); - var text_max = 140; - $('#textarea-comment-feedback').html(text_max + ' characters remaining'); - $('#comment-to-comment-textinput').keyup(function (e) { - if (e.which === 13 || e === 13) { - $('#submit-comment-to-comment').click(); - $('#submit-comment-to-edit').click(); - } - var text_length = $('#comment-to-comment-textinput').val().length; - var text_remaining = text_max - text_length; - $('#textarea-comment-feedback').html(text_remaining + ' characters remaining'); - }); - var submitCommentToCommentHandler = function submitCommentToCommentHandler() { - $('#submit-comment-to-comment').unbind('click'); - $.post('/stories/comment/' + commentId + '/comment', - { - data: { - associatedPost: commentId, - originalStoryLink: originalStoryLink, - originalStoryAuthorEmail: originalStoryAuthorEmail, - body: $('#comment-to-comment-textinput').val(), - } - }) - .fail(function (xhr, textStatus, errorThrown) { - $('#submit-comment-to-comment').bind('click', submitCommentToCommentHandler); - }) - .done(function (data, textStatus, xhr) { - window.location.reload(); - }); - - }; - // todo - var submitCommentForEditToCommentHandler = function submitCommentForEditToCommentHandler() { - $('#submit-comment-to-edit').unbind('click'); - - $.ajax({ - type: "PUT", - url: '/stories/comment/' + commentId + '/edit', - data: { - associatedPost: commentId, - originalStoryLink: originalStoryLink, - body: $('#comment-to-comment-textinput').val() - }, - dataType: "json", - success: function (msg) { - window.location.reload(); - }, - error: function (err){ - $('#submit-comment-to-edit').bind('click', submitCommentForEditToCommentHandler); - } - }); - }; - - $('#submit-comment-to-edit').on('click', submitCommentForEditToCommentHandler) - $('#submit-comment-to-comment').on('click', submitCommentToCommentHandler); - }); - } - } - }) - - - }, comments); - } - sentinel += comments.length; - - - renderComments(comments, $('#comment-list'), 0); - - - - - diff --git a/server/views/stories/hot-stories.jade b/server/views/stories/hot-stories.jade index 425588dd05..0fe150ec54 100644 --- a/server/views/stories/hot-stories.jade +++ b/server/views/stories/hot-stories.jade @@ -9,7 +9,7 @@ return name.trim().toLowerCase().replace(/\s/g, '-'); } $.ajax({ - url: '/stories/hotStories', + url: '/news/hot', type: 'GET' }) .success( @@ -18,6 +18,12 @@ var div = document.createElement('div'); var linkedName = getLinkedName(data[i].storyLink); var rank = data[i].rank; + var alreadyUpvoted = false; + if (typeof username !== 'undefined') { + alreadyUpvoted = data[i].upVotes.some(function(vote) { + return vote.upVotedByUsername === username + }); + } $(div) .html( @@ -38,7 +44,11 @@ " by @" + data[i].author.username + " " + "" + "
" + - "
discuss" + + "
" + + (typeof username !== 'undefined' ? + "" : + "upvote") + + "more info..." + "
" + "" + "" + "" + "
" + "
" + - "discuss" + + "more info..." + "
" + "" + "" + @@ -103,7 +103,7 @@ script. "" + "" + "