Skip to content

Add comments to post #25

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions api/blog.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var routes = {};
routes.posts = require('./route/posts.js');
routes.users = require('./route/users.js');
routes.rss = require('./route/rss.js');
routes.comments = require('./route/comments.js');


app.all('*', function(req, res, next) {
Expand All @@ -33,7 +34,7 @@ app.get('/post', routes.posts.list);
app.get('/post/all', jwt({secret: secret.secretToken}), tokenManager.verifyToken, routes.posts.listAll);

//Get the post id
app.get('/post/:id', routes.posts.read);
app.get('/post/:id', routes.posts.read);

//Like the post id
app.post('/post/like', routes.posts.like);
Expand All @@ -42,27 +43,33 @@ app.post('/post/like', routes.posts.like);
app.post('/post/unlike', routes.posts.unlike);

//Get posts by tag
app.get('/tag/:tagName', routes.posts.listByTag);
app.get('/tag/:tagName', routes.posts.listByTag);

//Create a new user
app.post('/user/register', routes.users.register);
app.post('/user/register', routes.users.register);

//Login
app.post('/user/signin', routes.users.signin);
app.post('/user/signin', routes.users.signin);

//Logout
app.get('/user/logout', jwt({secret: secret.secretToken}), routes.users.logout);
app.get('/user/logout', jwt({secret: secret.secretToken}), routes.users.logout);

//Create a new post
app.post('/post', jwt({secret: secret.secretToken}), tokenManager.verifyToken , routes.posts.create);
app.post('/post', jwt({secret: secret.secretToken}), tokenManager.verifyToken , routes.posts.create);

//Edit the post id
app.put('/post', jwt({secret: secret.secretToken}), tokenManager.verifyToken, routes.posts.update);
app.put('/post', jwt({secret: secret.secretToken}), tokenManager.verifyToken, routes.posts.update);

//Delete the post id
app.delete('/post/:id', jwt({secret: secret.secretToken}), tokenManager.verifyToken, routes.posts.delete);
app.delete('/post/:id', jwt({secret: secret.secretToken}), tokenManager.verifyToken, routes.posts.delete);

//Serve the rss feed
app.get('/rss', routes.rss.index);

//Add comment
app.post('/comment', jwt({secret: secret.secretToken}), tokenManager.verifyToken, routes.comments.create);

//Get comment of a post
app.get('/comment/:postid', routes.comments.list);

console.log('Blog API is starting on port 3001');
16 changes: 14 additions & 2 deletions api/config/mongo_database.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ var mongodbURL = 'mongodb://localhost/blog';
var mongodbOptions = { };

mongoose.connect(mongodbURL, mongodbOptions, function (err, res) {
if (err) {
if (err) {
console.log('Connection refused to ' + mongodbURL);
console.log(err);
} else {
Expand Down Expand Up @@ -34,6 +34,13 @@ var Post = new Schema({
likes: { type: Number, default: 0 }
});

// Comment schema
var Comment = new Schema({
uid: { type: String, required: true },
pid: { type: String, required: true },
content: { type: String, required: true },
created: { type: Date, default: Date.now }
});

// Bcrypt middleware on UserSchema
User.pre('save', function(next) {
Expand Down Expand Up @@ -64,8 +71,13 @@ User.methods.comparePassword = function(password, cb) {
//Define Models
var userModel = mongoose.model('User', User);
var postModel = mongoose.model('Post', Post);
var comtModel = mongoose.model('Comment', Comment);


// Export Models
exports.userModel = userModel;
exports.postModel = postModel;
exports.postModel = postModel;
exports.comtModel = comtModel;

// Export ObjectId
exports.ObjectId = Schema.ObjectId;
92 changes: 92 additions & 0 deletions api/route/comments.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Post comments. Support pagination.
*/
var db = require('../config/mongo_database.js');
var redis = require('../config/redis_database').redisClient;
var users = require('./users');

var toInt = function(v) {
if (v === null || v === undefined) { return null; }
return parseInt(v) || null;
};

exports.list = function(req, res) {
var postid = req.params.postid || '',
page = toInt(req.query.page) || 1;

if (!postid) { return res.send(400); }

var query = db.comtModel.find({pid: postid}, {_id: 0});
query.sort('-created');
if (page > 1) {
query.skip( (page - 1) * pageSize );
}
query.limit(10);

query.exec(function(err, results) {
if (err) {
console.log(err);
return res.send(500, err.message);
}
if (results.length === 0) {
return res.send(200);
}

// get distinct user id list
var i, j = [], ids = [];
for (i=0; i<results.length; i++) {
var uid = results[i].uid;
if (j.indexOf(uid) === -1) {
j.push( uid );
ids.push( new db.ObjectId(uid) );
}
}
// search user names and return
db.userModel.find({
_id: {$in: uids}
}, {
username: 1
}, function(err, users) {
return res.json(200, {
comments: results,
users: users
});
});
});
};

exports.create = function(req, res) {
if (!req.user) {
return res.send(401);
}
var postid = req.body.postid,
content = req.body.content;
if (!postid || !content) {
return res.send(400, 'Invalid comment');
}

db.userModel.findById(req.user.id, function (err, user) {
if (err || !user) {
err && console.log(err);
return res.send(400, err ? err.message : 'Invalid user');
}
db.postModel.findById(postid, function (err, post) {
if (err || !post) {
err && console.log(err);
return res.send(404, 'Invalid post');
}

var comtEntry = new db.comtModel();
comtEntry.uid = req.user.id;
comtEntry.pid = postid;
comtEntry.content = content;
comtEntry.save(function(err) {
if (err) {
console.log(err);
return res.send(500, err.message);
}
return res.send(200);
});
});
});
}
21 changes: 21 additions & 0 deletions app/css/style.less
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,25 @@ a, a:focus, a:hover {
.btn-primary {
background-color: #235A9F;
border-color: rgb(16, 76, 128);
}

/*Comment Partial*/
.comments {
margin-top: 30px;
margin-bottom: 20px;
}
.comment-form > textarea {
width: 100%;
}
.comment-form > div {
margin-top: 8px;
margin-left: 20px;
}
.comment {
margin: 10px auto;
padding: 4px;
background-color: #fff;
}
.comment-main {
margin-top: 4px;
}
68 changes: 61 additions & 7 deletions app/js/controllers.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ appControllers.controller('PostListCtrl', ['$scope', '$sce', 'PostService',
data[postKey].content = $sce.trustAsHtml(data[postKey].content);
}

$scope.posts = data;
$scope.posts = data;
}).error(function(data, status) {
console.log(status);
console.log(data);
Expand Down Expand Up @@ -64,7 +64,7 @@ appControllers.controller('PostViewCtrl', ['$scope', '$routeParams', '$location'
]);


appControllers.controller('AdminPostListCtrl', ['$scope', 'PostService',
appControllers.controller('AdminPostListCtrl', ['$scope', 'PostService',
function AdminPostListCtrl($scope, PostService) {
$scope.posts = [];

Expand Down Expand Up @@ -116,7 +116,7 @@ appControllers.controller('AdminPostCreateCtrl', ['$scope', '$location', 'PostSe
$('#textareaContent').wysihtml5({"font-styles": false});

$scope.save = function save(post, shouldPublish) {
if (post != undefined
if (post != undefined
&& post.title != undefined
&& post.tags != undefined) {

Expand Down Expand Up @@ -156,7 +156,7 @@ appControllers.controller('AdminPostEditCtrl', ['$scope', '$routeParams', '$loca
});

$scope.save = function save(post, shouldPublish) {
if (post !== undefined
if (post !== undefined
&& post.title !== undefined && post.title != "") {

var content = $('#textareaContent').val();
Expand All @@ -173,7 +173,7 @@ appControllers.controller('AdminPostEditCtrl', ['$scope', '$routeParams', '$loca
if (Object.prototype.toString.call(post.tags) !== '[object Array]') {
post.tags = post.tags.split(',');
}

PostService.update(post).success(function(data) {
$location.path("/admin");
}).error(function(status, data) {
Expand All @@ -186,7 +186,7 @@ appControllers.controller('AdminPostEditCtrl', ['$scope', '$routeParams', '$loca
}
]);

appControllers.controller('AdminUserCtrl', ['$scope', '$location', '$window', 'UserService', 'AuthenticationService',
appControllers.controller('AdminUserCtrl', ['$scope', '$location', '$window', 'UserService', 'AuthenticationService',
function AdminUserCtrl($scope, $location, $window, UserService, AuthenticationService) {

//Admin User Controller (signIn, logOut)
Expand All @@ -206,7 +206,7 @@ appControllers.controller('AdminUserCtrl', ['$scope', '$location', '$window', 'U

$scope.logOut = function logOut() {
if (AuthenticationService.isAuthenticated) {

UserService.logOut().success(function(data) {
AuthenticationService.isAuthenticated = false;
delete $window.sessionStorage.token;
Expand Down Expand Up @@ -257,3 +257,57 @@ appControllers.controller('PostListTagCtrl', ['$scope', '$routeParams', '$sce',
}
]);

appControllers.controller('CommentCtrl' , ['$scope', '$location', 'CommentService',
function ($scope, $location, CommentService) {
var postid = $location.$$path.split('/').slice(-1)[0];
$scope.user = []; // users list that commented
$scope.comments = []; // comments list
$scope.page = 1; // current page number

$scope.$on('evtUserStatus', function (event, data) {
// user can comment when logged
$scope.isLogged = !!data.isLogged;
});

var getComments = function(query) {
CommentService.find(query).success(function(data) {
if (!data.comments) { return; }
var users = {};
for (var i=0; i<data.users.length; i++) {
var u = data.users[i];
users[u._id] = u.username;
}
$scope.users = users;
$scope.comments = data.comments;
}).error(function(data, status) {
console.log(status);
console.log(data);
});
};

$scope.goto = function (n) {
if (n < 1) {
return false;
}
$scope.page = n;
getComments({id: postid, page: n});
};

$scope.add = function () {
if (!$scope.comment) {return;}
var c = $scope.comment.trim();
if (c.length < 6 || c.length > 200) {
return false;
}
CommentService.add(postid, c).success(function(data) {
$scope.comment = '';
getComments({id: postid, page: 1});
}).error(function(data, status) {
console.log(status);
console.log(data);
});
};
// fetch comments
getComments({id: postid, page: 1});
}
]);
26 changes: 22 additions & 4 deletions app/js/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ appServices.factory('PostService', function($http) {
read: function(id) {
return $http.get(options.api.base_url + '/post/' + id);
},

findAll: function() {
return $http.get(options.api.base_url + '/post/all');
},
Expand All @@ -81,7 +81,7 @@ appServices.factory('PostService', function($http) {
},

unlike: function(id) {
return $http.post(options.api.base_url + '/post/unlike', {'id': id});
return $http.post(options.api.base_url + '/post/unlike', {'id': id});
}
};
});
Expand Down Expand Up @@ -139,11 +139,29 @@ appServices.factory('LikeService', function ($window) {
if (postLiked[i] == id) {
postLiked.splice(i, 1);
$window.sessionStorage.postLiked = postLiked;

break;
}
}
}
}
}
});
});

appServices.factory('CommentService', function ($http) {
return {
find: function (query) {
var url = options.api.base_url + '/comment/' + query.id;
if (query.page) {
url += '?page=' + query.page;
}
return $http.get(url);
},
add: function (id, content) {
return $http.post(options.api.base_url + '/comment', {
postid: id,
content: content
});
}
}
});
Loading