diff --git a/src/redux/preview.js b/src/redux/preview.js
index e115cdd3c..a151fe41c 100644
--- a/src/redux/preview.js
+++ b/src/redux/preview.js
@@ -87,6 +87,19 @@ module.exports.previewReducer = (state, action) => {
comments: [...state.comments, ...action.items] // TODO: consider a different way of doing this?
});
case 'SET_COMMENT_DELETED':
+ if (action.topLevelCommentId) {
+ return Object.assign({}, state, {
+ replies: Object.assign({}, state.replies, {
+ [action.topLevelCommentId]: state.replies[action.topLevelCommentId].map(comment => {
+ if (comment.id === action.commentId) {
+ return Object.assign({}, comment, {deleted: true});
+ }
+ return comment;
+ })
+ })
+ });
+ }
+
return Object.assign({}, state, {
comments: state.comments.map(comment => {
if (comment.id === action.commentId) {
@@ -96,30 +109,13 @@ module.exports.previewReducer = (state, action) => {
})
});
case 'ADD_NEW_COMMENT':
- if (action.comment.parent_id) {
- let topLevelParent = action.comment.parent_id;
-
- // If this is a nested reply, we need to look up which top level comment
- // to put this new reply under.
- if (!state.replies[topLevelParent]) {
- Object.keys(state.replies).forEach(topLevelCommentId => {
- state.replies[topLevelCommentId].forEach(reply => {
- if (reply.id === action.comment.parent_id) {
- topLevelParent = topLevelCommentId;
- }
- });
- });
- }
-
- if (state.replies[topLevelParent]) {
- const replies = JSON.parse(JSON.stringify(state.replies));
- // Replies to comments go at the end of the thread
- replies[topLevelParent] = replies[topLevelParent].concat(action.comment);
- return Object.assign({}, state, {replies: replies});
- }
-
- log.error('Could not find top level parent to put reply in');
- return state;
+ if (action.topLevelCommentId) {
+ return Object.assign({}, state, {
+ replies: Object.assign({}, state.replies, {
+ // Replies to comments go at the end of the thread
+ [action.topLevelCommentId]: state.replies[action.topLevelCommentId].concat(action.comment)
+ })
+ });
}
// Reply to the top level project, put the reply at the beginning
@@ -232,14 +228,16 @@ module.exports.setStudioFetchStatus = (studioId, status) => ({
status: status
});
-module.exports.setCommentDeleted = commentId => ({
+module.exports.setCommentDeleted = (commentId, topLevelCommentId) => ({
type: 'SET_COMMENT_DELETED',
- commentId: commentId
+ commentId: commentId,
+ topLevelCommentId: topLevelCommentId
});
-module.exports.addNewComment = comment => ({
+module.exports.addNewComment = (comment, topLevelCommentId) => ({
type: 'ADD_NEW_COMMENT',
- comment: comment
+ comment: comment,
+ topLevelCommentId: topLevelCommentId
});
module.exports.getProjectInfo = (id, token) => (dispatch => {
diff --git a/src/views/preview/comment/comment.jsx b/src/views/preview/comment/comment.jsx
index 25b0a9f94..378a76b24 100644
--- a/src/views/preview/comment/comment.jsx
+++ b/src/views/preview/comment/comment.jsx
@@ -15,6 +15,7 @@ class Comment extends React.Component {
super(props);
bindAll(this, [
+ 'handleDelete',
'handlePostReply',
'handleToggleReplying'
]);
@@ -33,6 +34,10 @@ class Comment extends React.Component {
this.setState({replying: !this.state.replying});
}
+ handleDelete () {
+ this.props.onDelete(this.props.id);
+ }
+
render () {
const {
author,
@@ -41,7 +46,6 @@ class Comment extends React.Component {
canReply,
content,
datetimeCreated,
- onDelete,
id,
projectId
} = this.props;
@@ -64,7 +68,7 @@ class Comment extends React.Component {
{deletable ? (
Delete {/* TODO internationalize */}
diff --git a/src/views/preview/comment/top-level-comment.jsx b/src/views/preview/comment/top-level-comment.jsx
index 77a2bed28..1f0899970 100644
--- a/src/views/preview/comment/top-level-comment.jsx
+++ b/src/views/preview/comment/top-level-comment.jsx
@@ -13,7 +13,8 @@ class TopLevelComment extends React.Component {
super(props);
bindAll(this, [
'handleExpandThread',
- 'handleDelete'
+ 'handleAddComment',
+ 'handleDeleteComment'
]);
this.state = {
expanded: false
@@ -26,8 +27,14 @@ class TopLevelComment extends React.Component {
});
}
- handleDelete () {
- this.props.onDelete(this.props.id);
+ handleDeleteReply (commentId) {
+ // Only apply topLevelCommentId for deleting replies
+ // The top level comment itself just gets passed onDelete directly
+ this.props.onDelete(commentId, this.props.id);
+ }
+
+ handleAddComment (comment) {
+ this.props.onAddComment(comment, this.props.id);
}
render () {
@@ -39,18 +46,17 @@ class TopLevelComment extends React.Component {
deletable,
deleted,
id,
+ onDelete,
replies,
- projectId,
- onAddComment
+ projectId
} = this.props;
return (
{replies.length > 0 &&
))}
diff --git a/src/views/preview/preview.jsx b/src/views/preview/preview.jsx
index a4ea7d051..76ed08b89 100644
--- a/src/views/preview/preview.jsx
+++ b/src/views/preview/preview.jsx
@@ -167,11 +167,11 @@ class Preview extends React.Component {
});
});
}
- handleAddComment (comment) {
- this.props.handleAddComment(comment);
+ handleAddComment (comment, topLevelCommentId) {
+ this.props.handleAddComment(comment, topLevelCommentId);
}
- handleDeleteComment (id) {
- this.props.handleDeleteComment(this.state.projectId, id, this.props.user.token);
+ handleDeleteComment (id, topLevelCommentId) {
+ this.props.handleDeleteComment(this.state.projectId, id, topLevelCommentId, this.props.user.token);
}
handleReportClick () {
this.setState({reportOpen: true});
@@ -532,11 +532,11 @@ const mapStateToProps = state => {
};
const mapDispatchToProps = dispatch => ({
- handleAddComment: comment => {
- dispatch(previewActions.addNewComment(comment));
+ handleAddComment: (comment, topLevelCommentId) => {
+ dispatch(previewActions.addNewComment(comment, topLevelCommentId));
},
- handleDeleteComment: (projectId, commentId, token) => {
- dispatch(previewActions.deleteComment(projectId, commentId, token));
+ handleDeleteComment: (projectId, commentId, topLevelCommentId, token) => {
+ dispatch(previewActions.deleteComment(projectId, commentId, topLevelCommentId, token));
},
handleOpenRegistration: event => {
event.preventDefault();