1 import { Component, linkEvent } from "inferno";
2 import { T } from "inferno-i18next-dess";
3 import { Prompt } from "inferno-router";
8 PrivateMessageResponse,
11 } from "lemmy-js-client";
12 import { Subscription } from "rxjs";
13 import { i18n } from "../../i18next";
14 import { WebSocketService } from "../../services";
17 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 {
32 recipient: PersonSafe;
33 privateMessage?: 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 {
40 privateMessageForm: CreatePrivateMessage;
43 showDisclaimer: boolean;
46 export class PrivateMessageForm extends Component<
47 PrivateMessageFormProps,
48 PrivateMessageFormState
50 private subscription: Subscription;
51 private emptyState: PrivateMessageFormState = {
54 recipient_id: this.props.recipient.id,
59 showDisclaimer: false,
62 constructor(props: any, context: any) {
63 super(props, context);
65 this.state = this.emptyState;
67 this.handleContentChange = this.handleContentChange.bind(this);
69 this.parseMessage = this.parseMessage.bind(this);
70 this.subscription = wsSubscribe(this.parseMessage);
73 if (this.props.privateMessage) {
74 this.state.privateMessageForm.content =
75 this.props.privateMessage.private_message.content;
83 componentDidUpdate() {
84 if (!this.state.loading && this.state.privateMessageForm.content) {
85 window.onbeforeunload = () => true;
87 window.onbeforeunload = undefined;
91 componentWillUnmount() {
93 this.subscription.unsubscribe();
94 window.onbeforeunload = null;
102 when={!this.state.loading && this.state.privateMessageForm.content}
103 message={i18n.t("block_leaving")}
105 <form onSubmit={linkEvent(this, this.handlePrivateMessageSubmit)}>
106 {!this.props.privateMessage && (
107 <div class="form-group row">
108 <label class="col-sm-2 col-form-label">
109 {capitalizeFirstLetter(i18n.t("to"))}
112 <div class="col-sm-10 form-control-plaintext">
113 <PersonListing person={this.props.recipient} />
117 <div class="form-group row">
118 <label class="col-sm-2 col-form-label">
121 class="btn btn-link text-warning d-inline-block"
122 onClick={linkEvent(this, this.handleShowDisclaimer)}
123 data-tippy-content={i18n.t("private_message_disclaimer")}
124 aria-label={i18n.t("private_message_disclaimer")}
126 <Icon icon="alert-triangle" classes="icon-inline" />
129 <div class="col-sm-10">
131 initialContent={this.state.privateMessageForm.content}
132 onContentChange={this.handleContentChange}
137 {this.state.showDisclaimer && (
138 <div class="form-group row">
139 <div class="offset-sm-2 col-sm-10">
140 <div class="alert alert-danger" role="alert">
141 <T i18nKey="private_message_disclaimer">
146 href="https://element.io/get-started"
155 <div class="form-group row">
156 <div class="offset-sm-2 col-sm-10">
159 class="btn btn-secondary mr-2"
160 disabled={this.state.loading}
162 {this.state.loading ? (
164 ) : this.props.privateMessage ? (
165 capitalizeFirstLetter(i18n.t("save"))
167 capitalizeFirstLetter(i18n.t("send_message"))
170 {this.props.privateMessage && (
173 class="btn btn-secondary"
174 onClick={linkEvent(this, this.handleCancel)}
179 <ul class="d-inline-block float-right list-inline mb-1 text-muted font-weight-bold">
180 <li class="list-inline-item"></li>
189 handlePrivateMessageSubmit(i: PrivateMessageForm, event: any) {
190 event.preventDefault();
191 if (i.props.privateMessage) {
192 let form: EditPrivateMessage = {
193 private_message_id: i.props.privateMessage.private_message.id,
194 content: i.state.privateMessageForm.content,
197 WebSocketService.Instance.send(wsClient.editPrivateMessage(form));
199 WebSocketService.Instance.send(
200 wsClient.createPrivateMessage(i.state.privateMessageForm)
203 i.state.loading = true;
207 handleContentChange(val: string) {
208 this.state.privateMessageForm.content = val;
209 this.setState(this.state);
212 handleCancel(i: PrivateMessageForm) {
216 handlePreviewToggle(i: PrivateMessageForm, event: any) {
217 event.preventDefault();
218 i.state.previewMode = !i.state.previewMode;
222 handleShowDisclaimer(i: PrivateMessageForm) {
223 i.state.showDisclaimer = !i.state.showDisclaimer;
227 parseMessage(msg: any) {
228 let op = wsUserOp(msg);
231 toast(i18n.t(msg.error), "danger");
232 this.state.loading = false;
233 this.setState(this.state);
236 op == UserOperation.EditPrivateMessage ||
237 op == UserOperation.DeletePrivateMessage ||
238 op == UserOperation.MarkPrivateMessageAsRead
240 let data = wsJsonToRes<PrivateMessageResponse>(msg).data;
241 this.state.loading = false;
242 this.props.onEdit(data.private_message_view);
243 } else if (op == UserOperation.CreatePrivateMessage) {
244 let data = wsJsonToRes<PrivateMessageResponse>(msg).data;
245 this.state.loading = false;
246 this.props.onCreate(data.private_message_view);
247 this.setState(this.state);