1 import { Component } from "inferno";
2 import { T } from "inferno-i18next-dess";
3 import { Link } from "inferno-router";
12 } from "lemmy-js-client";
13 import { Subscription } from "rxjs";
14 import { CommentNodeI } from "shared/interfaces";
15 import { i18n } from "../../i18next";
16 import { UserService, WebSocketService } from "../../services";
18 capitalizeFirstLetter,
20 myFirstDiscussionLanguageId,
24 import { Icon } from "../common/icon";
25 import { MarkdownTextArea } from "../common/markdown-textarea";
27 interface CommentFormProps {
29 * Can either be the parent, or the editable comment. The right side is a postId.
31 node: CommentNodeI | number;
35 onReplyCancel?(): any;
36 allLanguages: Language[];
37 siteLanguages: number[];
40 interface CommentFormState {
46 export class CommentForm extends Component<CommentFormProps, CommentFormState> {
47 private subscription?: Subscription;
48 state: CommentFormState = {
50 typeof this.props.node === "number"
51 ? capitalizeFirstLetter(i18n.t("post"))
53 ? capitalizeFirstLetter(i18n.t("save"))
54 : capitalizeFirstLetter(i18n.t("reply")),
58 constructor(props: any, context: any) {
59 super(props, context);
61 this.handleCommentSubmit = this.handleCommentSubmit.bind(this);
62 this.handleReplyCancel = this.handleReplyCancel.bind(this);
64 this.parseMessage = this.parseMessage.bind(this);
65 this.subscription = wsSubscribe(this.parseMessage);
68 componentWillUnmount() {
69 this.subscription?.unsubscribe();
74 typeof this.props.node !== "number"
76 ? this.props.node.comment_view.comment.content
81 typeof this.props.node !== "number"
82 ? this.props.node.comment_view.comment.language_id
83 : myFirstDiscussionLanguageId(
84 this.props.allLanguages,
85 this.props.siteLanguages,
86 UserService.Instance.myUserInfo
90 <div className="mb-3">
91 {UserService.Instance.myUserInfo ? (
93 initialContent={initialContent}
94 initialLanguageId={selectedLang}
96 buttonTitle={this.state.buttonTitle}
97 finished={this.state.finished}
98 replyType={typeof this.props.node !== "number"}
99 focus={this.props.focus}
100 disabled={this.props.disabled}
101 onSubmit={this.handleCommentSubmit}
102 onReplyCancel={this.handleReplyCancel}
103 placeholder={i18n.t("comment_here")}
104 allLanguages={this.props.allLanguages}
105 siteLanguages={this.props.siteLanguages}
108 <div className="alert alert-warning" role="alert">
109 <Icon icon="alert-triangle" classes="icon-inline mr-2" />
110 <T i18nKey="must_login" class="d-inline">
112 <Link className="alert-link" to="/login">
122 handleCommentSubmit(msg: {
127 let content = msg.val;
128 let language_id = msg.languageId;
129 let node = this.props.node;
131 this.setState({ formId: msg.formId });
135 if (typeof node === "number") {
137 let form: CreateComment = {
139 form_id: this.state.formId,
144 WebSocketService.Instance.send(wsClient.createComment(form));
146 if (this.props.edit) {
147 let form: EditComment = {
149 form_id: this.state.formId,
150 comment_id: node.comment_view.comment.id,
154 WebSocketService.Instance.send(wsClient.editComment(form));
156 let form: CreateComment = {
158 form_id: this.state.formId,
159 post_id: node.comment_view.post.id,
160 parent_id: node.comment_view.comment.id,
164 WebSocketService.Instance.send(wsClient.createComment(form));
170 handleReplyCancel() {
171 this.props.onReplyCancel?.();
174 parseMessage(msg: any) {
175 let op = wsUserOp(msg);
178 // Only do the showing and hiding if logged in
179 if (UserService.Instance.myUserInfo) {
181 op == UserOperation.CreateComment ||
182 op == UserOperation.EditComment
184 let data = wsJsonToRes<CommentResponse>(msg);
186 // This only finishes this form, if the randomly generated form_id matches the one received
187 if (this.state.formId && this.state.formId == data.form_id) {
188 this.setState({ finished: true });
190 // Necessary because it broke tribute for some reason
191 this.setState({ finished: false });