diff --git a/wax-prosemirror-components/src/components/comments/Comment.js b/wax-prosemirror-components/src/components/comments/Comment.js index 81e9076e06db7730dc62c2405e7df3b98f3167fb..b8e257ea25c5784dc5069c7fb6c34aa69b474d61 100644 --- a/wax-prosemirror-components/src/components/comments/Comment.js +++ b/wax-prosemirror-components/src/components/comments/Comment.js @@ -1,8 +1,7 @@ import React, { useState, useRef } from 'react'; import { v4 as uuidv4 } from 'uuid'; - +import { last } from 'lodash'; import styled from 'styled-components'; -import { WaxContext } from 'wax-prosemirror-core'; import { DocumentHelpers } from 'wax-prosemirror-utilities'; const SinlgeCommentRow = styled.div` @@ -15,6 +14,7 @@ export default ({ comment, activeView, user }) => { const [commentAnnotation, setCommentAnnotation] = useState(comment); const [commentInputValue, setcommentInputValue] = useState(''); const { state, dispatch } = activeView; + const allCommentsWithSameId = DocumentHelpers.findAllMarksWithSameId(state, comment); const { attrs: { conversation }, } = comment; @@ -26,7 +26,9 @@ export default ({ comment, activeView, user }) => { } }; - const saveComment = () => { + const saveComment = event => { + event.stopPropagation(); + const { current: { value }, } = commentInput; @@ -34,8 +36,8 @@ export default ({ comment, activeView, user }) => { const obj = { [user.username]: value }; commentAnnotation.attrs.conversation.push(obj); - const allComments = DocumentHelpers.findAllCommentsWithSameId(state); - allComments.forEach(singleComment => { + + allCommentsWithSameId.forEach(singleComment => { dispatch( tr.addMark( singleComment.pos, @@ -67,14 +69,24 @@ export default ({ comment, activeView, user }) => { } if (conversation.length === 0 && value === '') { - const commentPosition = DocumentHelpers.findMarkPosition(activeView, comment.pos, 'comment'); - dispatch(state.tr.removeMark(commentPosition.from, commentPosition.to, commentMark)); + resolveComment(); } }; - const resolveComment = () => { - const commentPosition = DocumentHelpers.findMarkPosition(activeView, comment.pos, 'comment'); - dispatch(state.tr.removeMark(commentPosition.from, commentPosition.to, commentMark)); + const resolveComment = event => { + event.stopPropagation(); + let maxPos = comment.pos; + let minPos = comment.pos; + + allCommentsWithSameId.forEach(singleComment => { + const markPosition = DocumentHelpers.findMarkPosition(activeView, singleComment.pos, 'comment'); + if (markPosition.from < minPos) minPos = markPosition.from; + if (markPosition.to > maxPos) maxPos = markPosition.to; + }); + + if (allCommentsWithSameId.length > 1) maxPos += last(allCommentsWithSameId).node.nodeSize; + dispatch(state.tr.removeMark(minPos, maxPos, commentMark)); + activeView.focus(); }; const commentInputReply = () => { @@ -93,10 +105,10 @@ export default ({ comment, activeView, user }) => { autoFocus value={commentInputValue} /> - <button type="button" onClick={saveComment}> + <button type="button" onClick={event => saveComment(event)}> Post </button> - <button type="button" onClick={resolveComment}> + <button type="button" onClick={event => resolveComment(event)}> Resolve </button> </> diff --git a/wax-prosemirror-components/src/components/comments/CommentBox.js b/wax-prosemirror-components/src/components/comments/CommentBox.js index 610bb3da8ce566b5d0cfe33ad884d7b88c31bb8c..9cb81a741efcb90cb37c870c1c6d759f5474b362 100644 --- a/wax-prosemirror-components/src/components/comments/CommentBox.js +++ b/wax-prosemirror-components/src/components/comments/CommentBox.js @@ -1,11 +1,12 @@ import React, { useState, useEffect, useContext } from 'react'; import { TextSelection } from 'prosemirror-state'; +import { last } from 'lodash'; import { Transition } from 'react-transition-group'; import styled from 'styled-components'; +import { DocumentHelpers } from 'wax-prosemirror-utilities'; import { WaxContext } from 'wax-prosemirror-core'; import Comment from './Comment'; -import { DocumentHelpers } from 'wax-prosemirror-utilities'; const CommentBoxStyled = styled.div` display: flex; @@ -57,13 +58,19 @@ export default ({ comment, top, dataBox }) => { }, []); const setCommentActive = () => { - let commentPos = comment.pos; const viewId = comment.attrs.viewid; + let maxPos = comment.pos; + const allCommentsWithSameId = DocumentHelpers.findAllMarksWithSameId(view[viewId].state, comment); + + allCommentsWithSameId.forEach(singleComment => { + const markPosition = DocumentHelpers.findMarkPosition(view[viewId], singleComment.pos, 'comment'); + if (markPosition.to > maxPos) maxPos = markPosition.to; + }); + + if (!active && allCommentsWithSameId.length > 1) maxPos += last(allCommentsWithSameId).node.nodeSize; view[viewId].dispatch( - view[viewId].state.tr.setSelection( - new TextSelection(view[viewId].state.tr.doc.resolve(commentPos + 1, commentPos + 1)), - ), + view[viewId].state.tr.setSelection(new TextSelection(view[viewId].state.tr.doc.resolve(maxPos, maxPos))), ); view[viewId].focus(); diff --git a/wax-prosemirror-components/src/components/rightArea/RightArea.js b/wax-prosemirror-components/src/components/rightArea/RightArea.js index 1be82ff3a65fe48ca0dfd1f68d46f0d16a40b11f..7fa39ec99bbed1b1c2820688cdbe3a8ab6c5baba 100644 --- a/wax-prosemirror-components/src/components/rightArea/RightArea.js +++ b/wax-prosemirror-components/src/components/rightArea/RightArea.js @@ -1,6 +1,6 @@ import { Mark } from 'prosemirror-model'; import React, { useContext, useState, useEffect, useMemo, useCallback } from 'react'; -import { each, uniqBy, sortBy, throttle } from 'lodash'; +import { each, uniqBy, sortBy } from 'lodash'; import { WaxContext } from 'wax-prosemirror-core'; import { DocumentHelpers } from 'wax-prosemirror-utilities'; import BoxList from './BoxList'; diff --git a/wax-prosemirror-plugins/src/comments/CommentPlugin.js b/wax-prosemirror-plugins/src/comments/CommentPlugin.js index 41b62258d2d1f86a31bf3a79abefe7e7d3f6c8c7..03b77b01f0c4f4a85d9740fa1f0142a87d85991b 100644 --- a/wax-prosemirror-plugins/src/comments/CommentPlugin.js +++ b/wax-prosemirror-plugins/src/comments/CommentPlugin.js @@ -7,10 +7,7 @@ const commentPlugin = new PluginKey('commentPlugin'); const getComment = state => { const commentMark = state.schema.marks.comment; - const commentOnSelection = DocumentHelpers.findFragmentedMark( - state, - commentMark, - ); + const commentOnSelection = DocumentHelpers.findFragmentedMark(state, commentMark); // Don't allow Active comment if selection is not collapsed if ( @@ -22,19 +19,12 @@ const getComment = state => { } if (commentOnSelection) { - const commentNodes = DocumentHelpers.findChildrenByMark( - state.doc, - commentMark, - true, - ); + const commentNodes = DocumentHelpers.findChildrenByMark(state.doc, commentMark, true); const allCommentsWithSameId = []; commentNodes.map(node => { node.node.marks.filter(mark => { - if ( - mark.type.name === 'comment' && - commentOnSelection.attrs.id === mark.attrs.id - ) { + if (mark.type.name === 'comment' && commentOnSelection.attrs.id === mark.attrs.id) { allCommentsWithSameId.push(node); } }); diff --git a/wax-prosemirror-utilities/src/document/DocumentHelpers.js b/wax-prosemirror-utilities/src/document/DocumentHelpers.js index 3f1e2d59d23c977f46079507e922172c86854d37..ef355be3d26f8d5f998617be6a10434db349c98c 100644 --- a/wax-prosemirror-utilities/src/document/DocumentHelpers.js +++ b/wax-prosemirror-utilities/src/document/DocumentHelpers.js @@ -48,7 +48,7 @@ const getSelectionMark = (state, PMmark) => { }; /* this is a workaround for now to find marks - that are pm will break them + that are pm will break them. */ const findFragmentedMark = (state, PMmark) => { const { @@ -79,21 +79,21 @@ const findFragmentedMark = (state, PMmark) => { return markFound; }; -const findAllCommentsWithSameId = state => { - const commentMark = state.schema.marks.comment; - const commentOnSelection = findFragmentedMark(state, commentMark); +const findAllMarksWithSameId = (state, mark) => { + const type = mark.type.name; + const markType = state.schema.marks[type]; - const commentNodes = findChildrenByMark(state.doc, commentMark, true); + const allNodes = findChildrenByMark(state.doc, markType, true); - const allCommentsWithSameId = []; - commentNodes.map(node => { - node.node.marks.filter(mark => { - if (mark.type.name === 'comment' && commentOnSelection.attrs.id === mark.attrs.id) { - allCommentsWithSameId.push(node); + const allMarksWithSameId = []; + allNodes.map(node => { + node.node.marks.filter(value => { + if (mark.type.name === type && mark.attrs.id === value.attrs.id) { + allMarksWithSameId.push(node); } }); }); - return allCommentsWithSameId; + return allMarksWithSameId; }; // TODO Also find fragmented marks @@ -166,6 +166,6 @@ export default { findChildrenByAttr, getSelectionMark, findFragmentedMark, - findAllCommentsWithSameId, + findAllMarksWithSameId, findMarkPosition, };