import React from 'react'; import PropTypes from 'prop-types'; import { processor } from '../../utils/seafile-markdown2html'; import { Button, Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap'; import { seafileAPI } from '../../utils/seafile-api'; import { gettext, draftFilePath, draftRepoID } from '../../utils/constants'; import Loading from '../../components/loading.js'; import { username } from '../../utils/constants.js'; import '../../css/review-comments.css'; const commentPropTypes = { listComments: PropTypes.func.isRequired, inResizing: PropTypes.bool.isRequired, commentsList: PropTypes.array.isRequired, scrollToQuote: PropTypes.func.isRequired }; class ReviewComments extends React.Component { constructor(props) { super(props); this.state = { inResizing: false, commentFooterHeight: 25, showResolvedComment: true, comment: '', }; } handleCommentChange = (event) => { this.setState({ comment: event.target.value }); } submitComment = () => { let comment = this.state.comment.trim(); if (comment.length > 0) { seafileAPI.postComment(draftRepoID, draftFilePath, comment).then(() => { this.props.listComments(); }); this.setState({ comment: '' }); } } resolveComment = (event) => { seafileAPI.updateComment(draftRepoID, event.target.id, 'true').then((res) => { this.props.listComments(); }); } editComment = (commentID, newComment) => { seafileAPI.updateComment(draftRepoID, commentID, null, null, newComment).then((res) => { this.props.listComments(); }); } toggleResolvedComment = () => { this.setState({ showResolvedComment: !this.state.showResolvedComment }); } deleteComment = (event) => { seafileAPI.deleteComment(draftRepoID, event.target.id).then((res) => { this.props.listComments(); }); } onResizeMouseUp = () => { if (this.state.inResizing) { this.setState({ inResizing: false }); } } onResizeMouseDown = () => { this.setState({ inResizing: true }); }; onResizeMouseMove = (event) => { let rate = 100 - (event.nativeEvent.clientY - 120 ) / this.refs.comment.clientHeight * 100; if (rate < 20 || rate > 70) { if (rate < 20) { this.setState({ commentFooterHeight: 25 }); } if (rate > 70) { this.setState({ commentFooterHeight: 65 }); } this.setState({ inResizing: false }); return null; } this.setState({ commentFooterHeight: rate }); }; scrollToQuote = (newIndex, oldIndex, quote) => { this.props.scrollToQuote(newIndex, oldIndex, quote); this.setState({ comment: '' }); } componentWillReceiveProps(nextProps) { if (this.props.commentsList.length < nextProps.commentsList.length) { let that = this; setTimeout(() => { that.refs.commentsList.scrollTo(0, 10000); }, 100); } } render() { const onResizeMove = this.state.inResizing ? this.onResizeMouseMove : null; const { commentsList } = this.props; return (
{gettext('Show resolved comments')}
{commentsList.length === 0 &&
{gettext('No comment yet.')}
}
); } } ReviewComments.propTypes = commentPropTypes; const commentItemPropTypes = { item: PropTypes.object.isRequired, deleteComment: PropTypes.func.isRequired, resolveComment: PropTypes.func.isRequired, editComment: PropTypes.func.isRequired, showResolvedComment: PropTypes.bool.isRequired, scrollToQuote: PropTypes.func.isRequired }; class CommentItem extends React.Component { constructor(props) { super(props); this.state = { dropdownOpen: false, comment: '', quote: '', newComment: this.props.item.comment, editable: false, }; } toggleDropDownMenu = () => { this.setState({ dropdownOpen: !this.state.dropdownOpen }); } convertComment = (item) => { processor.process(item.comment).then((result) => { let comment = String(result); this.setState({ comment: comment }); }); processor.process(item.quote).then((result) => { let quote = String(result); this.setState({ quote: quote }); }); } scrollToQuote = () => { const item = this.props.item; this.props.scrollToQuote(item.newIndex, item.oldIndex, item.quote); } toggleEditComment = () => { this.setState({ editable: !this.state.editable }); } updateComment = (event) => { const newComment = this.state.newComment; if (this.props.item.comment !== newComment) { this.props.editComment(event.target.id, newComment); } this.toggleEditComment(); } handleCommentChange = (event) => { this.setState({ newComment: event.target.value }); } componentWillMount() { this.convertComment(this.props.item); } componentWillReceiveProps(nextProps) { this.convertComment(nextProps.item); } render() { const item = this.props.item; if (item.resolved && !this.props.showResolvedComment) return null; if (this.state.editable) { return(
  • {item.name}
    {item.time}
    {' '}
  • ); } return (
  • {item.name}
    {item.time}
    {!item.resolved && {(item.userEmail === username) && {gettext('Delete')}} {(item.userEmail === username) && {gettext('Edit')}} {gettext('Mark as resolved')} }
    {(item.newIndex >= -1 && item.oldIndex >= -1) &&
    }
  • ); } } CommentItem.propTypes = commentItemPropTypes; export default ReviewComments;