edit/delete comment

This commit is contained in:
OldHawk
2017-04-23 23:51:11 +08:00
parent 2515c828c1
commit 82f4267028
9 changed files with 334 additions and 35 deletions

View File

@@ -142,13 +142,24 @@
TORRENT_SEED_USERS: '做种用户列表',
TORRENT_LEECHER_USERS: '下载用户列表',
TORRENT_FINISHED_USERS: '完成用户列表',
//comment
USER_COMMENT_LIST: '用户评论',
POST_NEW_COMMENT: '发表新评论',
EDIT_COMMENT: '编辑评论',
SUBMIT_COMMENT: '提交评论',
SUBMIT_CANCEL: '取消',
MARKDOWN_LINK: '排版支持 Markdown 全部格式',
COMMENT_REPLY_BUTTON: '@ 楼主并回复',
COMMENT_REPLY_DELETE: '删除回复',
COMMENT_REPLY_EDIT: '编辑回复',
COMMENT_REPLY_DELETE: '删除',
COMMENT_REPLY_EDIT: '编辑',
COMMENT_EDITED_INFO: '编辑于',
COMMENT_CONFIRM_OK: '删除',
COMMENT_CONFIRM_CANCEL: '取消',
COMMENT_CONFIRM_HEADER_TEXT: '删除确认',
COMMENT_CONFIRM_BODY_TEXT: '你确定要删除这条评论吗?',
COMMENT_EDIT_ICON_TITLE: '编辑回复',
COMMENT_DELETE_ICON_TITLE: '删除回复',
//TorrentsUploadsController
TORRENTS_UPLOAD_SUCCESSFULLY: '文件上传成功',

View File

@@ -142,13 +142,25 @@
TORRENT_SEED_USERS: 'Seed Users',
TORRENT_LEECHER_USERS: 'Leecher Users',
TORRENT_FINISHED_USERS: 'Finished Users',
//comment
USER_COMMENT_LIST: 'User Comments List',
POST_NEW_COMMENT: 'Post New Comment',
EDIT_COMMENT: 'Edit Comment',
SUBMIT_COMMENT: 'Submit Comment',
SUBMIT_CANCEL: 'Cancel',
MARKDOWN_LINK: 'Styling with Markdown is supported',
COMMENT_REPLY_BUTTON: '@ & reply',
COMMENT_REPLY_DELETE: 'Delete reply',
COMMENT_REPLY_EDIT: 'Edit reply',
COMMENT_REPLY_DELETE: 'Delete',
COMMENT_REPLY_EDIT: 'Edit',
COMMENT_EDITED_INFO: 'Edit at',
COMMENT_CONFIRM_OK: 'Delete',
COMMENT_CONFIRM_CANCEL: 'Cancel',
COMMENT_CONFIRM_HEADER_TEXT: 'Delete Confirm',
COMMENT_CONFIRM_BODY_TEXT: 'Are you sure want to delete this comment?',
COMMENT_CONFIRM_BODY_TEXT_REPLY: 'Are you sure want to delete this comment reply?',
COMMENT_EDIT_ICON_TITLE: 'Edit this reply',
COMMENT_DELETE_ICON_TITLE: 'Delete this reply',
//TorrentsUploadsController & views
TORRENTS_UPLOAD_SUCCESSFULLY: 'Successfully uploads file',

View File

@@ -19,7 +19,7 @@
if (value) {
//element[0].scrollIntoView({block: 'end', behavior: 'smooth'});
//$uiViewScroll(element);
window.scrollTo(0, element[0].offsetTop - 60)
window.scrollTo(0, element[0].offsetTop - 60);
}
});
}

View File

@@ -101,7 +101,11 @@
min-height: 42px;
.timeline-comment-body-text {
padding-top: 10px;
padding-bottom: 10px;
}
.timeline-comment-body-edited-text {
font-size: 12px;
color: lighten(@gray-base, 60%);
margin-right: 15px;
}
.timeline-comment-sub-list {
border-top: 1px solid #d1d5da;
@@ -114,6 +118,24 @@
p {
margin: 5px 0;
}
.edit-button {
font-size: 12px;
margin-left: 10px;
cursor: pointer;
color: @brand-primary;
&:hover {
color: @brand-danger;
}
}
.delete-button {
font-size: 12px;
margin-left: 5px;
cursor: pointer;
color: @brand-primary;
&:hover {
color: @brand-danger;
}
}
}
.timeline-comment-sub-avatar {
img {

View File

@@ -6,10 +6,10 @@
.controller('TorrentsInfoController', TorrentsInfoController);
TorrentsInfoController.$inject = ['$scope', '$state', '$stateParams', '$translate', 'Authentication', 'Notification', 'TorrentsService',
'MeanTorrentConfig', 'DownloadService', '$sce', '$filter', 'CommentsService'];
'MeanTorrentConfig', 'DownloadService', '$sce', '$filter', 'CommentsService', 'ModalConfirmService'];
function TorrentsInfoController($scope, $state, $stateParams, $translate, Authentication, Notification, TorrentsService, MeanTorrentConfig,
DownloadService, $sce, $filter, CommentsService) {
DownloadService, $sce, $filter, CommentsService, ModalConfirmService) {
var vm = this;
vm.user = Authentication.user;
vm.announce = MeanTorrentConfig.meanTorrentConfig.announce;
@@ -191,6 +191,11 @@
* submitComment
*/
vm.submitComment = function () {
if (vm.reply_action === 'edit') {
vm.submitEditComment();
return;
}
var comment = new CommentsService({
_torrentId: vm.torrentLocalInfo._id,
_commentId: vm.comment_to_id,
@@ -209,17 +214,60 @@
if (vm.comment_to_id) {
vm.scrollToId = vm.comment_to_id;
}
vm.new_comment_content = '';
vm.comment_to_id = undefined;
vm.comment_to_at = undefined;
vm.submitInit();
vm.torrentLocalInfo = res;
}
function errorCallback(res) {
vm.submitInit();
vm.error_msg = res.data.message;
Notification.error({message: res.data.message, title: '<i class="glyphicon glyphicon-remove"></i> Comment created error!'});
}
};
/**
* submitEditComment
*/
vm.submitEditComment = function () {
var comment = new CommentsService({
_torrentId: vm.torrentLocalInfo._id,
_commentId: vm.comment_to_id,
_subCommentId: vm.comment_to_sub_id,
comment: vm.new_comment_content
});
comment.$update(function (response) {
successCallback(response);
}, function (errorResponse) {
errorCallback(errorResponse);
});
function successCallback(res) {
Notification.success({message: '<i class="glyphicon glyphicon-ok"></i> Comment edited successfully!'});
if (vm.comment_to_id) {
vm.scrollToId = vm.comment_to_id;
}
vm.submitInit();
vm.torrentLocalInfo = res;
}
function errorCallback(res) {
vm.submitInit();
vm.error_msg = res.data.message;
Notification.error({message: res.data.message, title: '<i class="glyphicon glyphicon-remove"></i> Comment edited error!'});
}
};
/**
* submitCancel
*/
vm.submitInit = function () {
vm.new_comment_content = '';
vm.comment_to_id = undefined;
vm.comment_to_sub_id = undefined;
vm.comment_to_at = undefined;
vm.reply_action = undefined;
};
/**
@@ -251,11 +299,18 @@
*/
vm.getSubMarkdown = function (sitem) {
var mk = ' <span style="font-size: 12px;">' + '- [@' + sitem.user.displayName + '](@' + sitem.user.displayName + ')</span> ';
mk += '<span style="font-size: 12px; color: #999999;">' + $filter('date')(sitem.createdat, 'yyyy-MM-dd hh:mm:ss') + '</span>';
mk += '<span style="font-size: 12px; color: #999999;">' + $filter('date')(sitem.createdat, 'yyyy-MM-dd HH:mm:ss') + '</span>';
mk += '<span class="glyphicon glyphicon-edit edit-button" title="{{ \'COMMENT_EDIT_ICON_TITLE\' | translate}}" ng-click="vm.editSubComment(item,sitem);"></span>';
mk += '<span class="glyphicon glyphicon-remove-circle delete-button" title="{{ \'COMMENT_DELETE_ICON_TITLE\' | translate}}" ng-click="vm.deleteSubComment(item,sitem);"></span>';
return mk;
};
/**
* markLinkClick
* @param evt
* @param citem
*/
vm.markLinkClick = function (evt, citem) {
if (evt.originalEvent.srcElement.innerText[0] === '@') {
evt.preventDefault();
@@ -267,5 +322,110 @@
}
};
/**
* editComment
* @param citem
*/
vm.editComment = function (citem) {
vm.comment_to_id = citem._id;
vm.reply_action = 'edit';
vm.new_comment_content = citem.comment;
angular.element('.new_comment_textarea').trigger('focus');
};
/**
* editSubComment
* @param citem
* @param sitem
*/
vm.editSubComment = function (citem, sitem) {
vm.comment_to_id = citem._id;
vm.comment_to_sub_id = sitem._id;
vm.reply_action = 'edit';
vm.new_comment_content = sitem.comment;
angular.element('.new_comment_textarea').trigger('focus');
};
/**
* deleteComment
* @param citem
*/
vm.deleteComment = function (citem) {
var modalOptions = {
closeButtonText: $translate.instant('COMMENT_CONFIRM_CANCEL'),
actionButtonText: $translate.instant('COMMENT_CONFIRM_OK'),
headerText: $translate.instant('COMMENT_CONFIRM_HEADER_TEXT'),
bodyText: $translate.instant('COMMENT_CONFIRM_BODY_TEXT')
};
ModalConfirmService.showModal({}, modalOptions)
.then(function (result) {
var comment = new CommentsService({
_torrentId: vm.torrentLocalInfo._id,
_commentId: citem._id
});
comment.$remove(function (response) {
successCallback(response);
}, function (errorResponse) {
errorCallback(errorResponse);
});
function successCallback(res) {
Notification.success({message: '<i class="glyphicon glyphicon-ok"></i> Comment deleted successfully!'});
vm.submitInit();
vm.torrentLocalInfo = res;
}
function errorCallback(res) {
vm.error_msg = res.data.message;
Notification.error({message: res.data.message, title: '<i class="glyphicon glyphicon-remove"></i> Comment deleted error!'});
}
});
};
/**
* deleteSubComment
* @param citem
*/
vm.deleteSubComment = function (citem, sitem) {
var modalOptions = {
closeButtonText: $translate.instant('COMMENT_CONFIRM_CANCEL'),
actionButtonText: $translate.instant('COMMENT_CONFIRM_OK'),
headerText: $translate.instant('COMMENT_CONFIRM_HEADER_TEXT'),
bodyText: $translate.instant('COMMENT_CONFIRM_BODY_TEXT_REPLY')
};
ModalConfirmService.showModal({}, modalOptions)
.then(function (result) {
var comment = new CommentsService({
_torrentId: vm.torrentLocalInfo._id,
_commentId: citem._id,
_subCommentId: sitem._id
});
comment.$remove(function (response) {
successCallback(response);
}, function (errorResponse) {
errorCallback(errorResponse);
});
function successCallback(res) {
Notification.success({message: '<i class="glyphicon glyphicon-ok"></i> Comment reply deleted successfully!'});
vm.submitInit();
vm.torrentLocalInfo = res;
}
function errorCallback(res) {
vm.error_msg = res.data.message;
Notification.error({message: res.data.message, title: '<i class="glyphicon glyphicon-remove"></i> Comment reply deleted error!'});
}
});
};
}
}());

View File

@@ -169,10 +169,13 @@
)
</span>
</div>
<span class="timeline-comment-header-time-text">{{item.createdat | date:'yyyy-MM-dd hh:mm:ss'}}</span>
<span class="timeline-comment-header-time-text">{{item.createdat | date:'yyyy-MM-dd HH:mm:ss'}}</span>
</div>
<div class="timeline-comment-body">
<div class="timeline-comment-body-text" marked="item.comment"></div>
<div class="row text-right" ng-show="item.editedat">
<p class="timeline-comment-body-edited-text">[ {{item.editedby}} {{ 'COMMENT_EDITED_INFO' | translate}} {{item.editedat | date:'yyyy-MM-dd HH:mm:ss'}} ]</p>
</div>
<div class="row" ng-show="item._replies.length>0">
<div class="col-sm-10 col-sm-offset-2 timeline-comment-sub-list">
<div class="timeline-comment-sub-item" ng-repeat="sitem in item._replies">
@@ -206,7 +209,7 @@
<div class="timeline-comment timeline-new-comment">
<div class="timeline-comment-header">
<div class="timeline-comment-header-text">{{ 'POST_NEW_COMMENT' | translate}}</div>
<div class="timeline-comment-header-text">{{ vm.reply_action == 'edit' ? 'EDIT_COMMENT' : 'POST_NEW_COMMENT' | translate}}</div>
</div>
<div class="timeline-comment-body">
<textarea class="form-control new_comment_textarea" ng-model="vm.new_comment_content"></textarea>
@@ -224,6 +227,7 @@
</a>
</div>
<div class="col-sm-3 text-right">
<button class="btn btn-info" translate="SUBMIT_CANCEL" ng-click="vm.submitInit();"></button>
<button class="btn btn-success" translate="SUBMIT_COMMENT" ng-click="vm.submitComment();"
ng-disabled="!vm.new_comment_content"></button>
</div>

View File

@@ -54,7 +54,25 @@ exports.create = function (req, res) {
* @param res
*/
exports.update = function (req, res) {
var torrent = req.torrent;
torrent._replies.forEach(function (r) {
if (r._id.equals(req.params.commentId)) {
r.comment = req.body.comment;
r.editedat = Date.now();
r.editedby = req.user.displayName;
torrent.save(function (err) {
if (err) {
return res.status(422).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.json(torrent);
}
});
}
});
};
/**
@@ -63,16 +81,22 @@ exports.update = function (req, res) {
* @param res
*/
exports.delete = function (req, res) {
var torrent = req.torrent;
};
/**
* list all comment of torrent
* @param req
* @param res
*/
exports.list = function (req, res) {
torrent._replies.forEach(function (r) {
if (r._id.equals(req.params.commentId)) {
torrent._replies.pull(r);
torrent.save(function (err) {
if (err) {
return res.status(422).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.json(torrent);
}
});
}
});
};
/**
@@ -122,7 +146,29 @@ exports.SubCreate = function (req, res) {
* @param res
*/
exports.SubUpdate = function (req, res) {
var torrent = req.torrent;
torrent._replies.forEach(function (r) {
if (r._id.equals(req.params.commentId)) {
r._replies.forEach(function (s) {
if (s._id.equals(req.params.subCommentId)) {
s.comment = req.body.comment;
s.editedat = Date.now();
s.editedby = req.user.displayName;
torrent.save(function (err) {
if (err) {
return res.status(422).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.json(torrent);
}
});
}
});
}
});
};
/**
@@ -131,15 +177,52 @@ exports.SubUpdate = function (req, res) {
* @param res
*/
exports.SubDelete = function (req, res) {
var torrent = req.torrent;
for (var i = 0; i < torrent._replies.length; i++) {
var c = torrent._replies[i];
if (c._id.equals(req.params.commentId)) {
for (var j = 0; j < c._replies.length; j++) {
var s = c._replies[j];
if (s._id.equals(req.params.subCommentId)) {
torrent._replies[i]._replies.pull(s);
torrent.save(function (err) {
if (err) {
console.log('save err');
return res.status(422).send({
message: errorHandler.getErrorMessage(err)
});
} else {
console.log('save ok');
res.json(torrent);
}
});
}
}
}
}
//torrent._replies.forEach(function (r) {
// if (r._id.equals(req.params.commentId)) {
// r._replies.forEach(function (s) {
// if (s._id.equals(req.params.subCommentId)) {
// console.log(r._id + '-' + s._id);
// r._replies.pull(s);
//
// torrent.save(function (err) {
// if (err) {
// console.log('save err');
// return res.status(422).send({
// message: errorHandler.getErrorMessage(err)
// });
// } else {
// console.log('save ok');
// res.json(torrent);
// }
// });
// }
// });
// }
//});
};
/**
* list all sub comment of comment
* @param req
* @param res
*/
exports.SubList = function (req, res) {
};

View File

@@ -23,6 +23,15 @@ var CommentSchema = new Schema({
createdat: {
type: Date,
default: Date.now
},
editedby: {
type: String,
default: '',
trim: true
},
editedat: {
type: Date,
default: ''
}
});

View File

@@ -7,10 +7,8 @@ var comments = require('../controllers/comments.server.controller');
module.exports = function (app) {
app.route('/api/comments/:torrentId')
.get(comments.list)
.post(comments.create);
app.route('/api/comments/:torrentId/:commentId')
.get(comments.SubList)
.post(comments.SubCreate)
.put(comments.update)
.delete(comments.delete);