1 import { Component, linkEvent } from "inferno";
2 import { T } from "inferno-i18next-dess";
3 import { Prompt } from "inferno-router";
8 PrivateMessageResponse,
13 } from "lemmy-js-client";
14 import { Subscription } from "rxjs";
15 import { i18n } from "../../i18next";
16 import { WebSocketService } from "../../services";
18 capitalizeFirstLetter,
27 import { Icon, Spinner } from "../common/icon";
28 import { MarkdownTextArea } from "../common/markdown-textarea";
29 import { PersonListing } from "../person/person-listing";
31 interface PrivateMessageFormProps {
33 privateMessageView?: PrivateMessageView; // If a pm is given, that means this is an edit
35 onCreate?(message: PrivateMessageView): any;
36 onEdit?(message: PrivateMessageView): any;
39 interface PrivateMessageFormState {
43 showDisclaimer: boolean;
46 export class PrivateMessageForm extends Component<
47 PrivateMessageFormProps,
48 PrivateMessageFormState
50 private subscription?: Subscription;
51 state: PrivateMessageFormState = {
54 showDisclaimer: false,
57 constructor(props: any, context: any) {
58 super(props, context);
60 this.handleContentChange = this.handleContentChange.bind(this);
62 this.parseMessage = this.parseMessage.bind(this);
63 this.subscription = wsSubscribe(this.parseMessage);
66 if (this.props.privateMessageView) {
68 this.props.privateMessageView.private_message.content;
76 componentDidUpdate() {
77 if (!this.state.loading && this.state.content) {
78 window.onbeforeunload = () => true;
80 window.onbeforeunload = null;
84 componentWillUnmount() {
86 this.subscription?.unsubscribe();
87 window.onbeforeunload = null;
95 when={!this.state.loading && this.state.content}
96 message={i18n.t("block_leaving")}
98 <form onSubmit={linkEvent(this, this.handlePrivateMessageSubmit)}>
99 {!this.props.privateMessageView && (
100 <div className="form-group row">
101 <label className="col-sm-2 col-form-label">
102 {capitalizeFirstLetter(i18n.t("to"))}
105 <div className="col-sm-10 form-control-plaintext">
106 <PersonListing person={this.props.recipient} />
110 <div className="form-group row">
111 <label className="col-sm-2 col-form-label">
114 className="btn btn-link text-warning d-inline-block"
115 onClick={linkEvent(this, this.handleShowDisclaimer)}
116 data-tippy-content={i18n.t("private_message_disclaimer")}
117 aria-label={i18n.t("private_message_disclaimer")}
119 <Icon icon="alert-triangle" classes="icon-inline" />
122 <div className="col-sm-10">
124 initialContent={this.state.content}
125 onContentChange={this.handleContentChange}
132 {this.state.showDisclaimer && (
133 <div className="form-group row">
134 <div className="offset-sm-2 col-sm-10">
135 <div className="alert alert-danger" role="alert">
136 <T i18nKey="private_message_disclaimer">
139 className="alert-link"
141 href="https://element.io/get-started"
150 <div className="form-group row">
151 <div className="offset-sm-2 col-sm-10">
154 className="btn btn-secondary mr-2"
155 disabled={this.state.loading}
157 {this.state.loading ? (
159 ) : this.props.privateMessageView ? (
160 capitalizeFirstLetter(i18n.t("save"))
162 capitalizeFirstLetter(i18n.t("send_message"))
165 {this.props.privateMessageView && (
168 className="btn btn-secondary"
169 onClick={linkEvent(this, this.handleCancel)}
174 <ul className="d-inline-block float-right list-inline mb-1 text-muted font-weight-bold">
175 <li className="list-inline-item"></li>
184 handlePrivateMessageSubmit(i: PrivateMessageForm, event: any) {
185 event.preventDefault();
186 const pm = i.props.privateMessageView;
187 const auth = myAuth();
188 const content = i.state.content;
189 if (auth && content) {
191 const form: EditPrivateMessage = {
192 private_message_id: pm.private_message.id,
196 WebSocketService.Instance.send(wsClient.editPrivateMessage(form));
198 const form: CreatePrivateMessage = {
200 recipient_id: i.props.recipient.id,
203 WebSocketService.Instance.send(wsClient.createPrivateMessage(form));
205 i.setState({ loading: true });
209 handleContentChange(val: string) {
210 this.setState({ content: val });
213 handleCancel(i: PrivateMessageForm) {
214 i.props.onCancel?.();
217 handlePreviewToggle(i: PrivateMessageForm, event: any) {
218 event.preventDefault();
219 i.setState({ previewMode: !i.state.previewMode });
222 handleShowDisclaimer(i: PrivateMessageForm) {
223 i.setState({ showDisclaimer: !i.state.showDisclaimer });
226 parseMessage(msg: any) {
227 const op = wsUserOp(msg);
230 toast(i18n.t(msg.error), "danger");
231 this.setState({ loading: false });
234 op == UserOperation.EditPrivateMessage ||
235 op == UserOperation.DeletePrivateMessage ||
236 op == UserOperation.MarkPrivateMessageAsRead
238 const data = wsJsonToRes<PrivateMessageResponse>(msg);
239 this.setState({ loading: false });
240 this.props.onEdit?.(data.private_message_view);
241 } else if (op == UserOperation.CreatePrivateMessage) {
242 const data = wsJsonToRes<PrivateMessageResponse>(msg);
243 this.props.onCreate?.(data.private_message_view);