import React from 'react'; import PropTypes from 'prop-types'; import moment from 'moment'; import { processor } from '@seafile/seafile-editor/dist/utils/seafile-markdown2html'; import { Button, Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap'; import { gettext } from '../../utils/constants'; import { seafileAPI } from '../../utils/seafile-api'; import ParticipantsList from './participants-list'; import { Utils } from '../../utils/utils'; import toaster from '../toast'; import '../../css/comments-list.css'; const { username, repoID, filePath } = window.app.pageOptions; const CommentPanelPropTypes = { toggleCommentPanel: PropTypes.func.isRequired, commentsNumber: PropTypes.number, participants: PropTypes.array, onParticipantsChange: PropTypes.func, }; class CommentPanel extends React.Component { constructor(props) { super(props); this.state = { commentsList: [], showResolvedComment: true, participants: null, }; this.isParticipant = false; } toggleResolvedComment = () => { this.setState({ showResolvedComment: !this.state.showResolvedComment }); } listComments = () => { seafileAPI.listComments(repoID, filePath).then((res) => { this.setState({ commentsList: res.data.comments }); }).catch(error => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); } handleCommentChange = (event) => { this.setState({ comment: event.target.value, }); } submitComment = () => { let comment = this.refs.commentTextarea.value; if (comment.trim()) { seafileAPI.postComment(repoID, filePath, comment).then(() => { this.listComments(); }).catch(error => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); this.addParticipant(); } this.refs.commentTextarea.value = ''; } addParticipant = () => { if (this.isParticipant) return; seafileAPI.addFileParticipant(repoID, filePath, username).then((res) => { this.isParticipant = true; this.onParticipantsChange(repoID, filePath); }).catch((err) => { let errMessage = Utils.getErrorMsg(err); toaster.danger(errMessage); }); } resolveComment = (event) => { seafileAPI.updateComment(repoID, event.target.id, 'true').then(() => { this.listComments(); }).catch(error => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); } deleteComment = (event) => { seafileAPI.deleteComment(repoID, event.target.id).then(() => { this.listComments(); }).catch(error => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); } editComment = (commentID, newComment) => { seafileAPI.updateComment(repoID, commentID, null, null, newComment).then((res) => { this.listComments(); }).catch(error => { let errMessage = Utils.getErrorMsg(error); toaster.danger(errMessage); }); } onParticipantsChange = () => { if (this.props.onParticipantsChange) { this.props.onParticipantsChange(); } else { this.getParticipants(); } } getParticipants = () => { if (this.props.participants) { this.setState({ participants: this.props.participants }, () => { this.checkParticipant(); }); } else { seafileAPI.listFileParticipants(repoID, filePath).then((res) => { this.setState({ participants: res.data.participant_list }, () => { this.checkParticipant(); }); }); } } checkParticipant = () => { const participants = this.state.participants; if (participants.length === 0) { this.isParticipant = false; } else { this.isParticipant = participants.some((participant) => { return participant.email === username; }); } } componentDidMount() { this.listComments(); this.getParticipants(); } componentWillReceiveProps(nextProps) { if (this.props.commentsNumber !== nextProps.commentsNumber) { this.listComments(); } if (this.props.participants !== nextProps.participants) { this.setState({ participants: nextProps.participants }); } } render() { const { participants } = this.state; return (