]> Untitled Git - lemmy-ui.git/blob - src/shared/components/comment-form.tsx
b032a065c6dc869b312410462b88f2d3c1e266af
[lemmy-ui.git] / src / shared / components / comment-form.tsx
1 import { Component } from 'inferno';
2 import { Link } from 'inferno-router';
3 import { Subscription } from 'rxjs';
4 import {
5   CommentNode as CommentNodeI,
6   CommentForm as CommentFormI,
7   WebSocketJsonResponse,
8   UserOperation,
9   CommentResponse,
10 } from 'lemmy-js-client';
11 import { capitalizeFirstLetter, wsJsonToRes, wsSubscribe } from '../utils';
12 import { WebSocketService, UserService } from '../services';
13 import { i18n } from '../i18next';
14 import { T } from 'inferno-i18next';
15 import { MarkdownTextArea } from './markdown-textarea';
16
17 interface CommentFormProps {
18   postId?: number;
19   node?: CommentNodeI;
20   onReplyCancel?(): any;
21   edit?: boolean;
22   disabled?: boolean;
23   focus?: boolean;
24 }
25
26 interface CommentFormState {
27   commentForm: CommentFormI;
28   buttonTitle: string;
29   finished: boolean;
30 }
31
32 export class CommentForm extends Component<CommentFormProps, CommentFormState> {
33   private subscription: Subscription;
34   private emptyState: CommentFormState = {
35     commentForm: {
36       auth: null,
37       content: null,
38       post_id: this.props.node
39         ? this.props.node.comment.post_id
40         : this.props.postId,
41       creator_id: UserService.Instance.user
42         ? UserService.Instance.user.id
43         : null,
44     },
45     buttonTitle: !this.props.node
46       ? capitalizeFirstLetter(i18n.t('post'))
47       : this.props.edit
48       ? capitalizeFirstLetter(i18n.t('save'))
49       : capitalizeFirstLetter(i18n.t('reply')),
50     finished: false,
51   };
52
53   constructor(props: any, context: any) {
54     super(props, context);
55
56     this.handleCommentSubmit = this.handleCommentSubmit.bind(this);
57     this.handleReplyCancel = this.handleReplyCancel.bind(this);
58
59     this.state = this.emptyState;
60
61     if (this.props.node) {
62       if (this.props.edit) {
63         this.state.commentForm.edit_id = this.props.node.comment.id;
64         this.state.commentForm.parent_id = this.props.node.comment.parent_id;
65         this.state.commentForm.content = this.props.node.comment.content;
66         this.state.commentForm.creator_id = this.props.node.comment.creator_id;
67       } else {
68         // A reply gets a new parent id
69         this.state.commentForm.parent_id = this.props.node.comment.id;
70       }
71     }
72
73     this.parseMessage = this.parseMessage.bind(this);
74     this.subscription = wsSubscribe(this.parseMessage);
75   }
76
77   componentWillUnmount() {
78     this.subscription.unsubscribe();
79   }
80
81   render() {
82     return (
83       <div class="mb-3">
84         {UserService.Instance.user ? (
85           <MarkdownTextArea
86             initialContent={this.state.commentForm.content}
87             buttonTitle={this.state.buttonTitle}
88             finished={this.state.finished}
89             replyType={!!this.props.node}
90             focus={this.props.focus}
91             disabled={this.props.disabled}
92             onSubmit={this.handleCommentSubmit}
93             onReplyCancel={this.handleReplyCancel}
94           />
95         ) : (
96           <div class="alert alert-light" role="alert">
97             <svg class="icon icon-inline mr-2">
98               <use xlinkHref="#icon-alert-triangle"></use>
99             </svg>
100             <T i18nKey="must_login" class="d-inline">
101               #
102               <Link className="alert-link" to="/login">
103                 #
104               </Link>
105             </T>
106           </div>
107         )}
108       </div>
109     );
110   }
111
112   handleCommentSubmit(msg: { val: string; formId: string }) {
113     this.state.commentForm.content = msg.val;
114     this.state.commentForm.form_id = msg.formId;
115     if (this.props.edit) {
116       WebSocketService.Instance.editComment(this.state.commentForm);
117     } else {
118       WebSocketService.Instance.createComment(this.state.commentForm);
119     }
120     this.setState(this.state);
121   }
122
123   handleReplyCancel() {
124     this.props.onReplyCancel();
125   }
126
127   parseMessage(msg: WebSocketJsonResponse) {
128     let res = wsJsonToRes(msg);
129
130     // Only do the showing and hiding if logged in
131     if (UserService.Instance.user) {
132       if (
133         res.op == UserOperation.CreateComment ||
134         res.op == UserOperation.EditComment
135       ) {
136         let data = res.data as CommentResponse;
137
138         // This only finishes this form, if the randomly generated form_id matches the one received
139         if (this.state.commentForm.form_id == data.form_id) {
140           this.setState({ finished: true });
141
142           // Necessary because it broke tribute for some reaso
143           this.setState({ finished: false });
144         }
145       }
146     }
147   }
148 }