1 import { Component, linkEvent } from "inferno";
2 import { Prompt } from "inferno-router";
3 import { Subscription } from "rxjs";
8 PrivateMessageResponse,
11 } from "lemmy-js-client";
12 import { WebSocketService } from "../services";
14 capitalizeFirstLetter,
24 import { PersonListing } from "./person-listing";
25 import { MarkdownTextArea } from "./markdown-textarea";
26 import { Icon, Spinner } from "./icon";
27 import { i18n } from "../i18next";
28 import { T } from "inferno-i18next";
30 interface PrivateMessageFormProps {
31 recipient: PersonSafe;
32 privateMessage?: PrivateMessageView; // If a pm is given, that means this is an edit
34 onCreate?(message: PrivateMessageView): any;
35 onEdit?(message: PrivateMessageView): any;
38 interface PrivateMessageFormState {
39 privateMessageForm: CreatePrivateMessage;
42 showDisclaimer: boolean;
45 export class PrivateMessageForm extends Component<
46 PrivateMessageFormProps,
47 PrivateMessageFormState
49 private subscription: Subscription;
50 private emptyState: PrivateMessageFormState = {
53 recipient_id: this.props.recipient.id,
58 showDisclaimer: false,
61 constructor(props: any, context: any) {
62 super(props, context);
64 this.state = this.emptyState;
66 this.handleContentChange = this.handleContentChange.bind(this);
68 this.parseMessage = this.parseMessage.bind(this);
69 this.subscription = wsSubscribe(this.parseMessage);
72 if (this.props.privateMessage) {
73 this.state.privateMessageForm.content = this.props.privateMessage.private_message.content;
81 componentDidUpdate() {
82 if (!this.state.loading && this.state.privateMessageForm.content) {
83 window.onbeforeunload = () => true;
85 window.onbeforeunload = undefined;
89 componentWillUnmount() {
91 this.subscription.unsubscribe();
92 window.onbeforeunload = null;
100 when={!this.state.loading && this.state.privateMessageForm.content}
101 message={i18n.t("block_leaving")}
103 <form onSubmit={linkEvent(this, this.handlePrivateMessageSubmit)}>
104 {!this.props.privateMessage && (
105 <div class="form-group row">
106 <label class="col-sm-2 col-form-label">
107 {capitalizeFirstLetter(i18n.t("to"))}
110 <div class="col-sm-10 form-control-plaintext">
111 <PersonListing person={this.props.recipient} />
115 <div class="form-group row">
116 <label class="col-sm-2 col-form-label">
119 onClick={linkEvent(this, this.handleShowDisclaimer)}
121 class="ml-2 pointer text-danger"
122 data-tippy-content={i18n.t("private_message_disclaimer")}
123 aria-label={i18n.t("private_message_disclaimer")}
125 <Icon icon="alert-triangle" classes="icon-inline" />
128 <div class="col-sm-10">
130 initialContent={this.state.privateMessageForm.content}
131 onContentChange={this.handleContentChange}
136 {this.state.showDisclaimer && (
137 <div class="form-group row">
138 <div class="offset-sm-2 col-sm-10">
139 <div class="alert alert-danger" role="alert">
140 <T i18nKey="private_message_disclaimer">
145 href="https://element.io/get-started"
154 <div class="form-group row">
155 <div class="offset-sm-2 col-sm-10">
158 class="btn btn-secondary mr-2"
159 disabled={this.state.loading}
161 {this.state.loading ? (
163 ) : this.props.privateMessage ? (
164 capitalizeFirstLetter(i18n.t("save"))
166 capitalizeFirstLetter(i18n.t("send_message"))
169 {this.props.privateMessage && (
172 class="btn btn-secondary"
173 onClick={linkEvent(this, this.handleCancel)}
178 <ul class="d-inline-block float-right list-inline mb-1 text-muted font-weight-bold">
179 <li class="list-inline-item"></li>
188 handlePrivateMessageSubmit(i: PrivateMessageForm, event: any) {
189 event.preventDefault();
190 if (i.props.privateMessage) {
191 let form: EditPrivateMessage = {
192 private_message_id: i.props.privateMessage.private_message.id,
193 content: i.state.privateMessageForm.content,
196 WebSocketService.Instance.send(wsClient.editPrivateMessage(form));
198 WebSocketService.Instance.send(
199 wsClient.createPrivateMessage(i.state.privateMessageForm)
202 i.state.loading = true;
206 handleContentChange(val: string) {
207 this.state.privateMessageForm.content = val;
208 this.setState(this.state);
211 handleCancel(i: PrivateMessageForm) {
215 handlePreviewToggle(i: PrivateMessageForm, event: any) {
216 event.preventDefault();
217 i.state.previewMode = !i.state.previewMode;
221 handleShowDisclaimer(i: PrivateMessageForm) {
222 i.state.showDisclaimer = !i.state.showDisclaimer;
226 parseMessage(msg: any) {
227 let op = wsUserOp(msg);
230 toast(i18n.t(msg.error), "danger");
231 this.state.loading = false;
232 this.setState(this.state);
235 op == UserOperation.EditPrivateMessage ||
236 op == UserOperation.DeletePrivateMessage ||
237 op == UserOperation.MarkPrivateMessageAsRead
239 let data = wsJsonToRes<PrivateMessageResponse>(msg).data;
240 this.state.loading = false;
241 this.props.onEdit(data.private_message_view);
242 } else if (op == UserOperation.CreatePrivateMessage) {
243 let data = wsJsonToRes<PrivateMessageResponse>(msg).data;
244 this.state.loading = false;
245 this.props.onCreate(data.private_message_view);
246 this.setState(this.state);