1 import { Component } from 'inferno';
2 import { Link } from 'inferno-router';
3 import { Subscription } from 'rxjs';
4 import { retryWhen, delay, take } from 'rxjs/operators';
6 CommentNode as CommentNodeI,
7 CommentForm as CommentFormI,
11 } from '../interfaces';
12 import { capitalizeFirstLetter, wsJsonToRes } from '../utils';
13 import { WebSocketService, UserService } from '../services';
14 import { i18n } from '../i18next';
15 import { T } from 'inferno-i18next';
16 import { MarkdownTextArea } from './markdown-textarea';
18 interface CommentFormProps {
21 onReplyCancel?(): any;
27 interface CommentFormState {
28 commentForm: CommentFormI;
33 export class CommentForm extends Component<CommentFormProps, CommentFormState> {
34 private subscription: Subscription;
35 private emptyState: CommentFormState = {
39 post_id: this.props.node
40 ? this.props.node.comment.post_id
42 creator_id: UserService.Instance.user
43 ? UserService.Instance.user.id
46 buttonTitle: !this.props.node
47 ? capitalizeFirstLetter(i18n.t('post'))
49 ? capitalizeFirstLetter(i18n.t('save'))
50 : capitalizeFirstLetter(i18n.t('reply')),
54 constructor(props: any, context: any) {
55 super(props, context);
57 this.handleCommentSubmit = this.handleCommentSubmit.bind(this);
58 this.handleReplyCancel = this.handleReplyCancel.bind(this);
60 this.state = this.emptyState;
62 if (this.props.node) {
63 if (this.props.edit) {
64 this.state.commentForm.edit_id = this.props.node.comment.id;
65 this.state.commentForm.parent_id = this.props.node.comment.parent_id;
66 this.state.commentForm.content = this.props.node.comment.content;
67 this.state.commentForm.creator_id = this.props.node.comment.creator_id;
69 // A reply gets a new parent id
70 this.state.commentForm.parent_id = this.props.node.comment.id;
74 this.subscription = WebSocketService.Instance.subject
75 .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
77 msg => this.parseMessage(msg),
78 err => console.error(err),
79 () => console.log('complete')
83 componentWillUnmount() {
84 this.subscription.unsubscribe();
90 {UserService.Instance.user ? (
92 initialContent={this.state.commentForm.content}
93 buttonTitle={this.state.buttonTitle}
94 finished={this.state.finished}
95 replyType={!!this.props.node}
96 focus={this.props.focus}
97 disabled={this.props.disabled}
98 onSubmit={this.handleCommentSubmit}
99 onReplyCancel={this.handleReplyCancel}
102 <div class="alert alert-light" role="alert">
103 <svg class="icon icon-inline mr-2">
104 <use xlinkHref="#icon-alert-triangle"></use>
106 <T i18nKey="must_login" class="d-inline">
108 <Link class="alert-link" to="/login">
118 handleCommentSubmit(msg: { val: string; formId: string }) {
119 this.state.commentForm.content = msg.val;
120 this.state.commentForm.form_id = msg.formId;
121 if (this.props.edit) {
122 WebSocketService.Instance.editComment(this.state.commentForm);
124 WebSocketService.Instance.createComment(this.state.commentForm);
126 this.setState(this.state);
129 handleReplyCancel() {
130 this.props.onReplyCancel();
133 parseMessage(msg: WebSocketJsonResponse) {
134 let res = wsJsonToRes(msg);
136 // Only do the showing and hiding if logged in
137 if (UserService.Instance.user) {
139 res.op == UserOperation.CreateComment ||
140 res.op == UserOperation.EditComment
142 let data = res.data as CommentResponse;
144 // This only finishes this form, if the randomly generated form_id matches the one received
145 if (this.state.commentForm.form_id == data.form_id) {
146 this.setState({ finished: true });
148 // Necessary because it broke tribute for some reaso
149 this.setState({ finished: false });