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 { UserService, WebSocketService } from '../services';
14 capitalizeFirstLetter,
22 import { UserListing } from './user-listing';
23 import { MarkdownTextArea } from './markdown-textarea';
24 import { i18n } from '../i18next';
25 import { T } from 'inferno-i18next';
27 interface PrivateMessageFormProps {
29 privateMessage?: PrivateMessageView; // If a pm is given, that means this is an edit
31 onCreate?(message: PrivateMessageView): any;
32 onEdit?(message: PrivateMessageView): any;
35 interface PrivateMessageFormState {
36 privateMessageForm: CreatePrivateMessage;
39 showDisclaimer: boolean;
42 export class PrivateMessageForm extends Component<
43 PrivateMessageFormProps,
44 PrivateMessageFormState
46 private subscription: Subscription;
47 private emptyState: PrivateMessageFormState = {
50 recipient_id: this.props.recipient.id,
51 auth: UserService.Instance.authField(),
55 showDisclaimer: false,
58 constructor(props: any, context: any) {
59 super(props, context);
61 this.state = this.emptyState;
63 this.handleContentChange = this.handleContentChange.bind(this);
65 this.parseMessage = this.parseMessage.bind(this);
66 this.subscription = wsSubscribe(this.parseMessage);
69 if (this.props.privateMessage) {
70 this.state.privateMessageForm.content = this.props.privateMessage.private_message.content;
78 componentDidUpdate() {
79 if (!this.state.loading && this.state.privateMessageForm.content) {
80 window.onbeforeunload = () => true;
82 window.onbeforeunload = undefined;
86 componentWillUnmount() {
88 this.subscription.unsubscribe();
89 window.onbeforeunload = null;
97 when={!this.state.loading && this.state.privateMessageForm.content}
98 message={i18n.t('block_leaving')}
100 <form onSubmit={linkEvent(this, this.handlePrivateMessageSubmit)}>
101 {!this.props.privateMessage && (
102 <div class="form-group row">
103 <label class="col-sm-2 col-form-label">
104 {capitalizeFirstLetter(i18n.t('to'))}
107 <div class="col-sm-10 form-control-plaintext">
108 <UserListing user={this.props.recipient} />
112 <div class="form-group row">
113 <label class="col-sm-2 col-form-label">
116 onClick={linkEvent(this, this.handleShowDisclaimer)}
117 class="ml-2 pointer text-danger"
118 data-tippy-content={i18n.t('disclaimer')}
120 <svg class={`icon icon-inline`}>
121 <use xlinkHref="#icon-alert-triangle"></use>
125 <div class="col-sm-10">
127 initialContent={this.state.privateMessageForm.content}
128 onContentChange={this.handleContentChange}
133 {this.state.showDisclaimer && (
134 <div class="form-group row">
135 <div class="offset-sm-2 col-sm-10">
136 <div class="alert alert-danger" role="alert">
137 <T i18nKey="private_message_disclaimer">
143 href="https://element.io/get-started"
152 <div class="form-group row">
153 <div class="offset-sm-2 col-sm-10">
156 class="btn btn-secondary mr-2"
157 disabled={this.state.loading}
159 {this.state.loading ? (
160 <svg class="icon icon-spinner spin">
161 <use xlinkHref="#icon-spinner"></use>
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 edit_id: i.props.privateMessage.private_message.id,
193 content: i.state.privateMessageForm.content,
194 auth: UserService.Instance.authField(),
196 WebSocketService.Instance.client.editPrivateMessage(form);
198 WebSocketService.Instance.client.createPrivateMessage(
199 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);
229 toast(i18n.t(msg.error), 'danger');
230 this.state.loading = false;
231 this.setState(this.state);
234 op == UserOperation.EditPrivateMessage ||
235 op == UserOperation.DeletePrivateMessage ||
236 op == UserOperation.MarkPrivateMessageAsRead
238 let data = wsJsonToRes<PrivateMessageResponse>(msg).data;
239 this.state.loading = false;
240 this.props.onEdit(data.private_message_view);
241 } else if (op == UserOperation.CreatePrivateMessage) {
242 let data = wsJsonToRes<PrivateMessageResponse>(msg).data;
243 this.state.loading = false;
244 this.props.onCreate(data.private_message_view);
245 this.setState(this.state);