diff --git a/common/models/bonfire.json b/common/models/bonfire.json deleted file mode 100644 index 859f0196ed..0000000000 --- a/common/models/bonfire.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "bonfire", - "base": "PersistedModel", - "idInjection": true, - "trackChanges": false, - "properties": { - "name": { - "type": "string", - "unique": true - }, - "difficulty": { - "type": "string" - }, - "description": { - "type": "array" - }, - "tests": { - "type": "array" - }, - "challengeSeed": { - "type": "array" - }, - "MDNlinks": { - "type": "array" - } - }, - "validations": [], - "relations": {}, - "acls": [ - { - "accessType": "*", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "DENY" - }, - { - "accessType": "READ", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - } - ], - "methods": [] -} diff --git a/common/models/comment.json b/common/models/comment.json deleted file mode 100644 index ec29a05c98..0000000000 --- a/common/models/comment.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "comment", - "base": "PersistedModel", - "idInjection": true, - "trackChanges": false, - "properties": { - "associatedPost": { - "type": "string", - "required": true - }, - "originalStoryLink": { - "type": "string", - "default": "" - }, - "originalStoryAuthorEmail": { - "type": "string", - "default": "" - }, - "body": { - "type": "string", - "default": "" - }, - "rank": { - "type": "number", - "default": 0 - }, - "upvotes": { - "type": "array", - "default": [] - }, - "author": { - "type": {}, - "default": {} - }, - "comments": { - "type": "array", - "default": [] - }, - "commentOn": { - "type": "number", - "defaultFn": "now" - } - }, - "validations": [], - "relations": {}, - "acls": [ - { - "accessType": "*", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "DENY" - }, - { - "accessType": "READ", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - }, - { - "accessType": "EXECUTE", - "principalType": "ROLE", - "principalId": "$authenticated", - "permission": "ALLOW", - "property": "create" - } - ], - "methods": [] -} diff --git a/common/models/story.json b/common/models/story.json index 4b50e3eed4..8aab09964b 100644 --- a/common/models/story.json +++ b/common/models/story.json @@ -44,10 +44,6 @@ "author": { "type": {} }, - "comments": { - "type": "array", - "default": [] - }, "image": { "type": "string", "default": "" diff --git a/gulpfile.js b/gulpfile.js index b8aa6ff0fb..c55daf01da 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -126,7 +126,7 @@ gulp.task('serve', function(cb) { script: paths.server, ext: '.js .json', ignore: paths.serverIgnore, - exec: './node_modules/.bin/babel-node', + exec: path.join(__dirname, 'node_modules/.bin/babel-node'), env: { 'NODE_ENV': 'development', 'DEBUG': process.env.DEBUG || 'freecc:*' 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/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", diff --git a/seed/challenges/get-set-for-free-code-camp.json b/seed/challenges/get-set-for-free-code-camp.json index b1360711ed..7acf8b3ca4 100644 --- a/seed/challenges/get-set-for-free-code-camp.json +++ b/seed/challenges/get-set-for-free-code-camp.json @@ -254,9 +254,8 @@ "Click \"News\" in the upper right hand corner.", "You'll see a variety of links that have been submitted. Click on the \"Discuss\" button under one of them.", "You can upvote links. This will push the link up the rankings of hot links.", - "You can also comment on a link. If someone responds to your comment, you'll get an email notification so you can come back and respond to them.", - "You can also submit links. You can modify the link's headline and also leave an initial comment about the link.", - "You can view the portfolio pages of any camper who has posted links or comments on Camper News. Just click on their photo.", + "You can also submit links.", + "You can view the portfolio pages of any camper who has posted links on Camper News. Just click on their photo.", "When you submit a link, you'll get a point. You will also get a point each time someone upvotes your link.", "Now that you've learned how to use Camper News, let's move on to your next challenge." ], diff --git a/seed/challenges/intermediate-ziplines.json b/seed/challenges/intermediate-ziplines.json index e7d3e5e38d..4104cc5b0a 100644 --- a/seed/challenges/intermediate-ziplines.json +++ b/seed/challenges/intermediate-ziplines.json @@ -18,7 +18,7 @@ "User Story: As a user, I can click on a post to be taken to the story's original URL.", "User Story: As a user, I can click a link to go directly to the post's discussion page.", "Bonus User Story: As a user, I can see how many upvotes each story has.", - "Hint: Here's the Camper News Hot Stories API endpoint: http://www.freecodecamp.com/stories/hotStories.", + "Hint: Here's the Camper News Hot Stories API endpoint: http://www.freecodecamp.com/news/hot.", "Remember to use RSAP if you get stuck.", "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. If you pair programmed, you should also include the Free Code Camp username of your pair.", "If you'd like immediate feedback on your project, click this button and paste in a link to your CodePen project. Otherwise, we'll review it before you start your nonprofit projects.

Click here then add your link to your tweet's text" diff --git a/server/boot/story.js b/server/boot/story.js index 9b7e40fe15..1f93fb8c12 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,8 @@ 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('/news/hot', hotJSON); 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('/stories/submit', submitNew); router.get('/stories/submit/new-story', preSubmit); router.post('/stories/preliminary', newStory); @@ -194,7 +169,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 +198,6 @@ module.exports = function(app) { rank: 1, upVotes: 1, author: 1, - comments: 1, image: 1, storyLink: 1, metaDescription: 1, @@ -250,7 +223,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 +257,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 +370,6 @@ module.exports = function(app) { username: req.user.username, email: req.user.email }, - comments: [], image: data.image, storyLink: storyLink, metaDescription: data.storyMetaDescription, @@ -428,174 +390,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/boot/user.js b/server/boot/user.js index 2a6c37d882..1d9327ded2 100644 --- a/server/boot/user.js +++ b/server/boot/user.js @@ -12,7 +12,6 @@ module.exports = function(app) { var router = app.loopback.Router(); var User = app.models.User; var Story = app.models.Story; - var Comment = app.models.Comment; router.get('/login', function(req, res) { res.redirect(301, '/signin'); @@ -623,55 +622,23 @@ module.exports = function(app) { } function updateUserStoryPictures(userId, picture, username, cb) { - - var counter = 0, - foundStories, - foundComments; - Story.find({ 'author.userId': userId }, function(err, stories) { - if (err) { - return cb(err); - } - foundStories = stories; - counter++; - saveStoriesAndComments(); - }); + if (err) { return cb(err); } - Comment.find({ 'author.userId': userId }, function(err, comments) { - if (err) { - return cb(err); - } - foundComments = comments; - counter++; - saveStoriesAndComments(); - }); - - function saveStoriesAndComments() { - if (counter !== 2) { - return; - } - var tasks = []; - R.forEach(function(comment) { - comment.author.picture = picture; - comment.author.username = username; - tasks.push(function(cb) { - comment.save(cb); - }); - }, foundComments); - - R.forEach(function(story) { + const tasks = []; + stories.forEach(function(story) { story.author.picture = picture; story.author.username = username; tasks.push(function(cb) { story.save(cb); }); - }, foundStories); + }); async.parallel(tasks, function(err) { if (err) { return cb(err); } cb(); }); - } + }); } }; diff --git a/server/model-config.json b/server/model-config.json index 56cd5a317d..5ebf445e9a 100644 --- a/server/model-config.json +++ b/server/model-config.json @@ -31,18 +31,10 @@ "dataSource": "mail", "public": false }, - "bonfire": { - "dataSource": "db", - "public": true - }, "challenge": { "dataSource": "db", "public": true }, - "comment": { - "dataSource": "db", - "public": true - }, "fieldGuide": { "dataSource": "db", "public": true diff --git a/server/server.js b/server/server.js index 796c23a1ff..224aade88d 100755 --- a/server/server.js +++ b/server/server.js @@ -208,7 +208,7 @@ app.use(function(req, res, next) { var path = req.path.split('/')[1]; if (/auth|login|logout|signin|signup|fonts|favicon/i.test(path)) { return next(); - } else if (/\/stories\/comments\/\w+/i.test(req.path)) { + } else if (/\/stories\/\w+/i.test(req.path)) { return next(); } req.session.returnTo = req.path; 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 · " + + (typeof username !== 'undefined' ? + "" : + "upvote") + + " · more info... · " + rank + (rank > 1 ? " points" : " point") + " · posted " + moment(data[i].timePosted).fromNow() + " by @" + data[i].author.username + " " + @@ -68,5 +81,13 @@ ); $(div).addClass('story-list news-box') $(div).appendTo($('#story-list')); + $(div).find('.btn-upvote').each(function(idx, btn) { + var $btn = $(btn); + if (alreadyUpvoted) { + $btn.addClass('disabled'); + $btn.text('upvoted!'); + } + $btn.data('upVotes', data[i].upVotes); + }); } }); diff --git a/server/views/stories/index.jade b/server/views/stories/index.jade index 0204840763..196c1bcd3d 100644 --- a/server/views/stories/index.jade +++ b/server/views/stories/index.jade @@ -3,8 +3,8 @@ block content if (user) script. var isLoggedIn = true; - var B3BA669EC5C1DD70FB478221E067A7E1B686929C569F5E73561B69C8F42129B = !{JSON.stringify(user.id)}; - var DF105CFA89562196E702912B3818C6A5B46E80D262442FDF29976621E5AF0D23 = !{JSON.stringify(user.username)}; + var userId = !{JSON.stringify(user.id)}; + var username = !{JSON.stringify(user.username)}; else script. var isLoggedIn = false; diff --git a/server/views/stories/new-stories.jade b/server/views/stories/new-stories.jade deleted file mode 100644 index 97a6aa02d6..0000000000 --- a/server/views/stories/new-stories.jade +++ /dev/null @@ -1,55 +0,0 @@ -.spacer -.col-xs-12 - #story-list.story-list - - script(src="https://cdn.jsdelivr.net/ramda/0.10.0/ramda.min.js") - script. - - var getLinkedName = function getLinkedName(name) { - return name.trim().toLowerCase().replace(/\s/g, '-'); - } - $.ajax({ - url: '/stories/recentStories', - type: 'GET' - }) - .success( - function(data) { - for (var i = 0; i < data.length; i++) { - var div = document.createElement('div'); - var linkedName = getLinkedName(data[i].storyLink); - var rank = data[i].rank; - - $(div) - .html( - "
" + - "

" + - (i + 1) + - "

" + - "
" + - "" + - "" + - "" + - "
" + - "
" + - "
" + - "
" + - "" + - data[i].headline + - "" + - "
" + - "
" + - "" + - "discuss · " + - rank + (rank > 1 ? " points" : " point") + " · posted " + - moment(data[i].timePosted).fromNow() + - " by @" + data[i].author.username + " " +" " + - "" + - "
" + - "
" + - "
" + - "
" - ); - $(div).addClass('story-list') - $(div).appendTo($('#story-list')); - } - }); \ No newline at end of file diff --git a/server/views/stories/news-nav.jade b/server/views/stories/news-nav.jade index 52ddf6c9f5..f28f1788f1 100644 --- a/server/views/stories/news-nav.jade +++ b/server/views/stories/news-nav.jade @@ -84,7 +84,7 @@ script. "
" + "
" + "
" + - "discuss" + + "more info..." + "
" + "" + "" + @@ -103,7 +103,7 @@ script. "" + "" + "
" + - "discuss · " + + "more info.more info... · " + rank + (rank > 1 ? " points" : " point") + " · posted " + moment(data[i].timePosted).fromNow() + " by @" + data[i].author.username + diff --git a/server/views/stories/search-stories.jade b/server/views/stories/search-stories.jade deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/server/views/stories/show.jade b/server/views/stories/show.jade index b96559b264..7d9ddbeb7f 100644 --- a/server/views/stories/show.jade +++ b/server/views/stories/show.jade @@ -2,7 +2,6 @@ script. var storyId = !{JSON.stringify(id)}; var originalStoryLink = !{JSON.stringify(originalStoryLink)}; var originalStoryAuthorEmail = !{JSON.stringify(originalStoryAuthorEmail)}; - var comments = !{JSON.stringify(comments)}; var upVotes = !{JSON.stringify(upVotes)}; var image = !{JSON.stringify(image)}; var hasUserVoted = !{JSON.stringify(hasUserVoted)}; @@ -26,52 +25,19 @@ h3.row .col-xs-12 h4= description .negative-5 - if !user - a#upvote.btn.signup-btn.btn-xs(href='/signin') Sign in to reply or upvote + if !hasUserVoted + a#upvote.btn.btn-no-shadow.btn-primary.btn-xs.btn-primary-ghost Upvote |  ·  else - a#reply-to-main-post.btn.btn-no-shadow.btn-primary.btn-xs.btn-primary-ghost Reply - |  ·   - if !hasUserVoted - a#upvote.btn.btn-no-shadow.btn-primary.btn-xs.btn-primary-ghost Upvote - |  ·  - else - a#upvote.btn.disabled.btn-no-shadow.btn-primary.btn-xs.btn-primary-ghost Upvoted! - |  ·  + a#upvote.btn.disabled.btn-no-shadow.btn-primary.btn-xs.btn-primary-ghost Upvoted! + |  ·  span#storyRank= rank + (rank > 1 ? " points" : " point") |  ·  span Posted #{timeAgo} span  by  a(href="/" + author.username) @#{author.username} -if (user !== null) - .col-xs-12#reply-area - .hidden-element#initial-comment-submit - form.form-horizontal.control-label-story-submission - .col-xs-12 - .input-group - input#comment-box.big-text-field.field-responsive.form-control(type='text', placeholder='Enter your reply', autofocus) - span.input-group-btn - button#comment-button.btn.btn-big.btn-primary.btn-responsive(type='button') Send - span.spacer.pull-left#textarea_feedback - script. if (image) { $('#image-display').removeClass('hidden-element') } - $('#reply-to-main-post').on('click', function() { - $('#initial-comment-submit').removeClass('hidden-element'); - $(this).unbind('click'); - $('.comment-to-comment-formgroup').empty(); - }); - var text_max = 140; - $('#textarea_feedback').html(text_max + ' characters remaining'); - $('#comment-box').keyup(function (e) { - if (e.which === 13 || e === 13) { - $('#comment-button').click(); - } - var text_length = $('#comment-box').val().length; - var text_remaining = text_max - text_length; - $('#textarea_feedback').html(text_remaining + ' characters remaining'); - }); -include comments diff --git a/server/views/stories/submit-story.jade b/server/views/stories/submit-story.jade index dbe42dd1e7..dda1aa63ea 100644 --- a/server/views/stories/submit-story.jade +++ b/server/views/stories/submit-story.jade @@ -22,11 +22,6 @@ alert(type='danger') span.ion-close-circled | A headline is required to submit. - .form-group - .col-xs-12.col-md-1 - label.control-label.control-label-story-submission(for='name') Comment - .col-xs-12.col-md-11 - input#description-box.form-control(name="comment-box", placeholder="Kick off the discussion with an optional comment about this link" maxlength='140') .form-group .col-xs-12.col-md-offset-1 span.pull-left#textarea_feedback