Skip to content
Snippets Groups Projects
Comment.js 3.17 KiB
Newer Older
chris's avatar
chris committed
import React, { useState, useRef } from 'react';
import { v4 as uuidv4 } from 'uuid';
chris's avatar
chris committed

chris's avatar
chris committed
import styled from 'styled-components';
import { WaxContext } from 'wax-prosemirror-core';
import { DocumentHelpers } from 'wax-prosemirror-utilities';
chris's avatar
chris committed

chris's avatar
chris committed
const SinlgeCommentRow = styled.div`
  padding: 4px;
  border-bottom: 1px solid #ffab20;
`;

chris's avatar
chris committed
export default ({ comment, activeView, user }) => {
  const commentInput = useRef(null);
  const [commentAnnotation, setCommentAnnotation] = useState(comment);
chris's avatar
chris committed
  const [commentInputValue, setcommentInputValue] = useState('');
chris's avatar
chris committed
  const { state, dispatch } = activeView;
chris's avatar
chris committed
  const {
    attrs: { conversation },
  } = comment;
  const commentMark = state.schema.marks.comment;
chris's avatar
chris committed

  const handleKeyDown = event => {
chris's avatar
chris committed
    if (event.key === 'Enter' || event.which === 13) {
chris's avatar
chris committed
      saveComment();
    }
  };

  const saveComment = () => {
chris's avatar
chris committed
    const {
      current: { value },
    } = commentInput;
chris's avatar
chris committed
    const { tr, doc } = state;

    const obj = { [user.username]: value };
    commentAnnotation.attrs.conversation.push(obj);
chris's avatar
chris committed
    const allComments = DocumentHelpers.findAllCommentsWithSameId(state);
    allComments.forEach(singleComment => {
      dispatch(
        tr.addMark(
          singleComment.pos,
          singleComment.pos + singleComment.nodeSize,
          commentMark.create({
            ...((commentAnnotation && commentAnnotation.attrs) || {}),
chris's avatar
chris committed
            conversation: commentAnnotation.attrs.conversation,
          }),
        ),
chris's avatar
chris committed
      );
    });

chris's avatar
chris committed
    setcommentInputValue('');
chris's avatar
chris committed
  };

  const updateCommentInputValue = () => {
chris's avatar
chris committed
    const {
      current: { value },
    } = commentInput;
chris's avatar
chris committed
    setcommentInputValue(value);
  };

  const onBlur = () => {
    const {
      current: { value },
    } = commentInput;
    if (value !== '') {
chris's avatar
chris committed
      // saveComment();
    }

    if (conversation.length === 0 && value === '') {
chris's avatar
chris committed
      const commentPosition = DocumentHelpers.findMarkPosition(activeView, comment.pos, 'comment');
      dispatch(state.tr.removeMark(commentPosition.from, commentPosition.to, commentMark));
    }
  };

  const resolveComment = () => {
    const commentPosition = DocumentHelpers.findMarkPosition(activeView, comment.pos, 'comment');
chris's avatar
chris committed
    dispatch(state.tr.removeMark(commentPosition.from, commentPosition.to, commentMark));
chris's avatar
chris committed
  const commentInputReply = () => {
    return (
chris's avatar
chris committed
      <>
chris's avatar
chris committed
        <input
          type="text"
          ref={commentInput}
          placeholder="add a new comment"
          onChange={updateCommentInputValue}
          onKeyPress={handleKeyDown}
          onBlur={onBlur}
          onClick={event => {
            event.stopPropagation();
          }}
chris's avatar
chris committed
          autoFocus
          value={commentInputValue}
        />
chris's avatar
chris committed
        <button type="button" onClick={saveComment}>
          Post
        </button>
        <button type="button" onClick={resolveComment}>
          Resolve
        </button>
chris's avatar
chris committed
      </>
chris's avatar
chris committed
    );
chris's avatar
chris committed
  };

chris's avatar
chris committed
  return conversation.length === 0 ? (
chris's avatar
chris committed
    <>{commentInputReply()}</>
chris's avatar
chris committed
  ) : (
chris's avatar
chris committed
    <>
chris's avatar
chris committed
      {conversation.map((singleComment, index) => {
        return (
          <SinlgeCommentRow key={uuidv4()}>{`${user.username} : ${singleComment[user.username]}`}</SinlgeCommentRow>
chris's avatar
chris committed
        );
      })}
      {commentInputReply()}
chris's avatar
chris committed
    </>
chris's avatar
chris committed
  );
};