2018-09-10 09:55:26 -07:00
|
|
|
import React from 'react';
|
|
|
|
import { connect } from 'react-redux';
|
2018-11-20 08:38:01 -08:00
|
|
|
import { Spin, Button, message } from 'antd';
|
2018-09-10 09:55:26 -07:00
|
|
|
import { AppState } from 'store/reducers';
|
2018-10-04 21:27:02 -07:00
|
|
|
import { ProposalWithCrowdFund } from 'types';
|
2018-09-18 15:15:01 -07:00
|
|
|
import { fetchProposalComments, postProposalComment } from 'modules/proposals/actions';
|
2018-09-10 09:55:26 -07:00
|
|
|
import {
|
|
|
|
getProposalComments,
|
|
|
|
getIsFetchingComments,
|
|
|
|
getCommentsError,
|
|
|
|
} from 'modules/proposals/selectors';
|
2018-11-08 11:38:00 -08:00
|
|
|
import { getIsSignedIn } from 'modules/auth/selectors';
|
2018-09-10 09:55:26 -07:00
|
|
|
import Comments from 'components/Comments';
|
2018-09-18 15:15:01 -07:00
|
|
|
import Placeholder from 'components/Placeholder';
|
|
|
|
import MarkdownEditor, { MARKDOWN_TYPE } from 'components/MarkdownEditor';
|
2018-09-22 09:44:55 -07:00
|
|
|
import './style.less';
|
2018-09-10 09:55:26 -07:00
|
|
|
|
|
|
|
interface OwnProps {
|
|
|
|
proposalId: ProposalWithCrowdFund['proposalId'];
|
|
|
|
}
|
|
|
|
|
|
|
|
interface StateProps {
|
|
|
|
comments: ReturnType<typeof getProposalComments>;
|
|
|
|
isFetchingComments: ReturnType<typeof getIsFetchingComments>;
|
|
|
|
commentsError: ReturnType<typeof getCommentsError>;
|
2018-11-20 08:38:01 -08:00
|
|
|
isPostCommentPending: AppState['proposal']['isPostCommentPending'];
|
|
|
|
postCommentError: AppState['proposal']['postCommentError'];
|
2018-11-08 11:38:00 -08:00
|
|
|
isSignedIn: ReturnType<typeof getIsSignedIn>;
|
2018-09-10 09:55:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
interface DispatchProps {
|
|
|
|
fetchProposalComments: typeof fetchProposalComments;
|
2018-09-18 15:15:01 -07:00
|
|
|
postProposalComment: typeof postProposalComment;
|
2018-09-10 09:55:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
type Props = DispatchProps & OwnProps & StateProps;
|
|
|
|
|
2018-09-18 15:15:01 -07:00
|
|
|
interface State {
|
|
|
|
comment: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
class ProposalComments extends React.Component<Props, State> {
|
|
|
|
state: State = {
|
|
|
|
comment: '',
|
|
|
|
};
|
|
|
|
|
2018-11-20 08:38:01 -08:00
|
|
|
private editor: MarkdownEditor | null = null;
|
|
|
|
|
2018-09-10 09:55:26 -07:00
|
|
|
componentDidMount() {
|
|
|
|
if (this.props.proposalId) {
|
|
|
|
this.props.fetchProposalComments(this.props.proposalId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillReceiveProps(nextProps: Props) {
|
|
|
|
if (nextProps.proposalId && nextProps.proposalId !== this.props.proposalId) {
|
|
|
|
this.props.fetchProposalComments(nextProps.proposalId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-20 08:38:01 -08:00
|
|
|
componentDidUpdate(prevProps: Props) {
|
|
|
|
// TODO: Come up with better check on if our comment post was a success
|
|
|
|
const { isPostCommentPending, postCommentError } = this.props;
|
|
|
|
if (!isPostCommentPending && !postCommentError && prevProps.isPostCommentPending) {
|
|
|
|
this.setState({ comment: '' });
|
|
|
|
this.editor!.reset();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (postCommentError && postCommentError !== prevProps.postCommentError) {
|
|
|
|
message.error('Failed to submit comment');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-10 09:55:26 -07:00
|
|
|
render() {
|
2018-11-20 08:38:01 -08:00
|
|
|
const {
|
|
|
|
comments,
|
|
|
|
isFetchingComments,
|
|
|
|
commentsError,
|
|
|
|
isPostCommentPending,
|
|
|
|
isSignedIn,
|
|
|
|
} = this.props;
|
2018-09-18 15:15:01 -07:00
|
|
|
const { comment } = this.state;
|
2018-09-10 09:55:26 -07:00
|
|
|
let content = null;
|
|
|
|
|
|
|
|
if (isFetchingComments) {
|
|
|
|
content = <Spin />;
|
|
|
|
} else if (commentsError) {
|
|
|
|
content = (
|
|
|
|
<>
|
|
|
|
<h2>Something went wrong</h2>
|
|
|
|
<p>{commentsError}</p>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
} else if (comments) {
|
|
|
|
if (comments.length) {
|
2018-11-08 11:14:52 -08:00
|
|
|
content = <Comments comments={comments} />;
|
2018-09-18 15:15:01 -07:00
|
|
|
} else {
|
2018-09-10 09:55:26 -07:00
|
|
|
content = (
|
2018-09-18 15:15:01 -07:00
|
|
|
<Placeholder
|
|
|
|
title="No comments have been made yet"
|
|
|
|
subtitle="Why not be the first?"
|
|
|
|
/>
|
2018-09-10 09:55:26 -07:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-18 15:15:01 -07:00
|
|
|
return (
|
|
|
|
<>
|
2018-11-08 11:38:00 -08:00
|
|
|
{isSignedIn && (
|
|
|
|
<div className="ProposalComments-post">
|
|
|
|
<MarkdownEditor
|
2018-11-20 08:38:01 -08:00
|
|
|
ref={el => (this.editor = el)}
|
2018-11-08 11:38:00 -08:00
|
|
|
onChange={this.handleCommentChange}
|
|
|
|
type={MARKDOWN_TYPE.REDUCED}
|
|
|
|
/>
|
|
|
|
<div style={{ marginTop: '0.5rem' }} />
|
2018-11-20 08:38:01 -08:00
|
|
|
<Button
|
|
|
|
onClick={this.postComment}
|
|
|
|
disabled={!comment.length}
|
|
|
|
loading={isPostCommentPending}
|
|
|
|
>
|
2018-11-08 11:38:00 -08:00
|
|
|
Submit comment
|
|
|
|
</Button>
|
|
|
|
</div>
|
|
|
|
)}
|
2018-09-18 15:15:01 -07:00
|
|
|
{content}
|
|
|
|
</>
|
|
|
|
);
|
2018-09-10 09:55:26 -07:00
|
|
|
}
|
2018-09-18 15:15:01 -07:00
|
|
|
|
|
|
|
private handleCommentChange = (comment: string) => {
|
|
|
|
this.setState({ comment });
|
|
|
|
};
|
|
|
|
|
|
|
|
private postComment = () => {
|
|
|
|
this.props.postProposalComment(this.props.proposalId, this.state.comment);
|
|
|
|
};
|
2018-09-10 09:55:26 -07:00
|
|
|
}
|
|
|
|
|
2018-11-08 11:38:00 -08:00
|
|
|
export default connect<StateProps, DispatchProps, OwnProps, AppState>(
|
|
|
|
(state, ownProps) => ({
|
2018-09-10 09:55:26 -07:00
|
|
|
comments: getProposalComments(state, ownProps.proposalId),
|
|
|
|
isFetchingComments: getIsFetchingComments(state),
|
|
|
|
commentsError: getCommentsError(state),
|
2018-11-20 08:38:01 -08:00
|
|
|
isPostCommentPending: state.proposal.isPostCommentPending,
|
|
|
|
postCommentError: state.proposal.postCommentError,
|
2018-11-08 11:38:00 -08:00
|
|
|
isSignedIn: getIsSignedIn(state),
|
2018-09-10 09:55:26 -07:00
|
|
|
}),
|
|
|
|
{
|
|
|
|
fetchProposalComments,
|
2018-09-18 15:15:01 -07:00
|
|
|
postProposalComment,
|
2018-09-10 09:55:26 -07:00
|
|
|
},
|
|
|
|
)(ProposalComments);
|