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