zcash-grant-system/frontend/client/components/Comment/index.tsx

128 lines
3.8 KiB
TypeScript
Raw Normal View History

2018-09-10 09:55:26 -07:00
import React from 'react';
import { connect } from 'react-redux';
2018-09-10 09:55:26 -07:00
import moment from 'moment';
import { Button } from 'antd';
import Markdown from 'components/Markdown';
import Identicon from 'components/Identicon';
import MarkdownEditor, { MARKDOWN_TYPE } from 'components/MarkdownEditor';
import { postProposalComment } from 'modules/proposals/actions';
2018-10-04 21:27:02 -07:00
import { Comment as IComment, Proposal } from 'types';
import { AppState } from 'store/reducers';
import './style.less';
2018-09-10 09:55:26 -07:00
interface OwnProps {
2018-09-10 09:55:26 -07:00
comment: IComment;
proposalId: Proposal['proposalId'];
2018-09-10 09:55:26 -07:00
}
interface StateProps {
isPostCommentPending: AppState['proposal']['isPostCommentPending'];
postCommentError: AppState['proposal']['postCommentError'];
}
interface DispatchProps {
postProposalComment: typeof postProposalComment;
}
type Props = OwnProps & StateProps & DispatchProps;
interface State {
reply: string;
isReplying: boolean;
}
class Comment extends React.Component<Props> {
state: State = {
reply: '',
isReplying: false,
};
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({ reply: '', isReplying: false });
}
}
2018-09-10 09:55:26 -07:00
public render(): React.ReactNode {
const { comment, proposalId } = this.props;
const { isReplying, reply } = this.state;
2018-09-10 09:55:26 -07:00
return (
<div className="Comment">
<div className="Comment-info">
<div className="Comment-info-thumb">
<Identicon address={comment.author.accountAddress} />
</div>
{/* <div className="Comment-info-thumb" src={comment.author.avatar['120x120']} /> */}
<div className="Comment-info-name">{comment.author.displayName}</div>
<div className="Comment-info-time">
{moment.unix(comment.dateCreated).fromNow()}
</div>
</div>
2018-09-10 09:55:26 -07:00
<div className="Comment-body">
<Markdown source={comment.body} type={MARKDOWN_TYPE.REDUCED} />
</div>
2018-09-10 09:55:26 -07:00
<div className="Comment-controls">
<a className="Comment-controls-button" onClick={this.toggleReply}>
{isReplying ? 'Cancel' : 'Reply'}
</a>
{/*<a className="Comment-controls-button">Report</a>*/}
</div>
2018-09-10 09:55:26 -07:00
{(comment.replies.length || isReplying) && (
<div className="Comment-replies">
{isReplying && (
<div className="Comment-replies-form">
<MarkdownEditor
onChange={this.handleChangeReply}
type={MARKDOWN_TYPE.REDUCED}
/>
<div style={{ marginTop: '0.5rem' }} />
<Button onClick={this.reply} disabled={!reply.length}>
Submit reply
</Button>
</div>
)}
{comment.replies.map(subComment => (
<ConnectedComment
key={subComment.id}
comment={subComment}
proposalId={proposalId}
/>
2018-09-10 09:55:26 -07:00
))}
</div>
2018-09-10 09:55:26 -07:00
)}
</div>
2018-09-10 09:55:26 -07:00
);
}
private toggleReply = () => {
this.setState({ isReplying: !this.state.isReplying });
};
private handleChangeReply = (reply: string) => {
this.setState({ reply });
};
private reply = () => {
const { comment, proposalId } = this.props;
const { reply } = this.state;
this.props.postProposalComment(proposalId, reply, comment.id);
};
2018-09-10 09:55:26 -07:00
}
const ConnectedComment = connect<StateProps, DispatchProps, OwnProps, AppState>(
(state: AppState) => ({
isPostCommentPending: state.proposal.isPostCommentPending,
postCommentError: state.proposal.postCommentError,
}),
{
postProposalComment,
},
)(Comment);
export default ConnectedComment;