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 { UserListing } from './user-listing';
25 import { MarkdownTextArea } from './markdown-textarea';
26 import { i18n } from '../i18next';
27 import { T } from 'inferno-i18next';
29 interface PrivateMessageFormProps {
31 privateMessage?: PrivateMessageView; // If a pm is given, that means this is an edit
33 onCreate?(message: PrivateMessageView): any;
34 onEdit?(message: PrivateMessageView): any;
37 interface PrivateMessageFormState {
38 privateMessageForm: CreatePrivateMessage;
41 showDisclaimer: boolean;
44 export class PrivateMessageForm extends Component<
45 PrivateMessageFormProps,
46 PrivateMessageFormState
48 private subscription: Subscription;
49 private emptyState: PrivateMessageFormState = {
52 recipient_id: this.props.recipient.id,
57 showDisclaimer: false,
60 constructor(props: any, context: any) {
61 super(props, context);
63 this.state = this.emptyState;
65 this.handleContentChange = this.handleContentChange.bind(this);
67 this.parseMessage = this.parseMessage.bind(this);
68 this.subscription = wsSubscribe(this.parseMessage);
71 if (this.props.privateMessage) {
72 this.state.privateMessageForm.content = this.props.privateMessage.private_message.content;
80 componentDidUpdate() {
81 if (!this.state.loading && this.state.privateMessageForm.content) {
82 window.onbeforeunload = () => true;
84 window.onbeforeunload = undefined;
88 componentWillUnmount() {
90 this.subscription.unsubscribe();
91 window.onbeforeunload = null;
99 when={!this.state.loading && this.state.privateMessageForm.content}
100 message={i18n.t('block_leaving')}
102 <form onSubmit={linkEvent(this, this.handlePrivateMessageSubmit)}>
103 {!this.props.privateMessage && (
104 <div class="form-group row">
105 <label class="col-sm-2 col-form-label">
106 {capitalizeFirstLetter(i18n.t('to'))}
109 <div class="col-sm-10 form-control-plaintext">
110 <UserListing user={this.props.recipient} />
114 <div class="form-group row">
115 <label class="col-sm-2 col-form-label">
118 onClick={linkEvent(this, this.handleShowDisclaimer)}
119 class="ml-2 pointer text-danger"
120 data-tippy-content={i18n.t('disclaimer')}
122 <svg class={`icon icon-inline`}>
123 <use xlinkHref="#icon-alert-triangle"></use>
127 <div class="col-sm-10">
129 initialContent={this.state.privateMessageForm.content}
130 onContentChange={this.handleContentChange}
135 {this.state.showDisclaimer && (
136 <div class="form-group row">
137 <div class="offset-sm-2 col-sm-10">
138 <div class="alert alert-danger" role="alert">
139 <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 ? (
162 <svg class="icon icon-spinner spin">
163 <use xlinkHref="#icon-spinner"></use>
165 ) : this.props.privateMessage ? (
166 capitalizeFirstLetter(i18n.t('save'))
168 capitalizeFirstLetter(i18n.t('send_message'))
171 {this.props.privateMessage && (
174 class="btn btn-secondary"
175 onClick={linkEvent(this, this.handleCancel)}
180 <ul class="d-inline-block float-right list-inline mb-1 text-muted font-weight-bold">
181 <li class="list-inline-item"></li>
190 handlePrivateMessageSubmit(i: PrivateMessageForm, event: any) {
191 event.preventDefault();
192 if (i.props.privateMessage) {
193 let form: EditPrivateMessage = {
194 edit_id: i.props.privateMessage.private_message.id,
195 content: i.state.privateMessageForm.content,
198 WebSocketService.Instance.send(wsClient.editPrivateMessage(form));
200 WebSocketService.Instance.send(
201 wsClient.createPrivateMessage(i.state.privateMessageForm)
204 i.state.loading = true;
208 handleContentChange(val: string) {
209 this.state.privateMessageForm.content = val;
210 this.setState(this.state);
213 handleCancel(i: PrivateMessageForm) {
217 handlePreviewToggle(i: PrivateMessageForm, event: any) {
218 event.preventDefault();
219 i.state.previewMode = !i.state.previewMode;
223 handleShowDisclaimer(i: PrivateMessageForm) {
224 i.state.showDisclaimer = !i.state.showDisclaimer;
228 parseMessage(msg: any) {
229 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);