2021-02-22 02:39:04 +00:00
|
|
|
import { Component, linkEvent } from "inferno";
|
|
|
|
import { Prompt } from "inferno-router";
|
|
|
|
import { Subscription } from "rxjs";
|
2020-09-06 16:15:25 +00:00
|
|
|
import {
|
2020-12-24 01:58:27 +00:00
|
|
|
CreatePrivateMessage,
|
|
|
|
EditPrivateMessage,
|
|
|
|
PrivateMessageView,
|
2020-09-06 16:15:25 +00:00
|
|
|
PrivateMessageResponse,
|
2021-03-15 18:09:31 +00:00
|
|
|
PersonSafe,
|
2020-09-06 16:15:25 +00:00
|
|
|
UserOperation,
|
2021-02-22 02:39:04 +00:00
|
|
|
} from "lemmy-js-client";
|
|
|
|
import { WebSocketService } from "../services";
|
2020-09-06 16:15:25 +00:00
|
|
|
import {
|
|
|
|
capitalizeFirstLetter,
|
|
|
|
wsJsonToRes,
|
|
|
|
toast,
|
|
|
|
setupTippy,
|
2020-09-08 18:44:55 +00:00
|
|
|
wsSubscribe,
|
|
|
|
isBrowser,
|
2020-12-24 01:58:27 +00:00
|
|
|
wsUserOp,
|
2020-12-24 22:05:57 +00:00
|
|
|
wsClient,
|
|
|
|
authField,
|
2021-02-22 02:39:04 +00:00
|
|
|
} from "../utils";
|
2021-03-15 18:09:31 +00:00
|
|
|
import { PersonListing } from "./person-listing";
|
2021-02-22 02:39:04 +00:00
|
|
|
import { MarkdownTextArea } from "./markdown-textarea";
|
|
|
|
import { Icon, Spinner } from "./icon";
|
|
|
|
import { i18n } from "../i18next";
|
|
|
|
import { T } from "inferno-i18next";
|
2020-09-06 16:15:25 +00:00
|
|
|
|
|
|
|
interface PrivateMessageFormProps {
|
2021-03-15 18:09:31 +00:00
|
|
|
recipient: PersonSafe;
|
2020-12-24 01:58:27 +00:00
|
|
|
privateMessage?: PrivateMessageView; // If a pm is given, that means this is an edit
|
2020-09-06 16:15:25 +00:00
|
|
|
onCancel?(): any;
|
2020-12-24 01:58:27 +00:00
|
|
|
onCreate?(message: PrivateMessageView): any;
|
|
|
|
onEdit?(message: PrivateMessageView): any;
|
2020-09-06 16:15:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
interface PrivateMessageFormState {
|
2020-12-24 01:58:27 +00:00
|
|
|
privateMessageForm: CreatePrivateMessage;
|
2020-09-06 16:15:25 +00:00
|
|
|
loading: boolean;
|
|
|
|
previewMode: boolean;
|
|
|
|
showDisclaimer: boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
export class PrivateMessageForm extends Component<
|
|
|
|
PrivateMessageFormProps,
|
|
|
|
PrivateMessageFormState
|
|
|
|
> {
|
|
|
|
private subscription: Subscription;
|
|
|
|
private emptyState: PrivateMessageFormState = {
|
|
|
|
privateMessageForm: {
|
|
|
|
content: null,
|
2020-09-08 18:44:55 +00:00
|
|
|
recipient_id: this.props.recipient.id,
|
2020-12-24 22:05:57 +00:00
|
|
|
auth: authField(),
|
2020-09-06 16:15:25 +00:00
|
|
|
},
|
|
|
|
loading: false,
|
|
|
|
previewMode: false,
|
|
|
|
showDisclaimer: false,
|
|
|
|
};
|
|
|
|
|
|
|
|
constructor(props: any, context: any) {
|
|
|
|
super(props, context);
|
|
|
|
|
|
|
|
this.state = this.emptyState;
|
|
|
|
|
|
|
|
this.handleContentChange = this.handleContentChange.bind(this);
|
|
|
|
|
2020-09-08 18:44:55 +00:00
|
|
|
this.parseMessage = this.parseMessage.bind(this);
|
|
|
|
this.subscription = wsSubscribe(this.parseMessage);
|
|
|
|
|
2020-12-24 01:58:27 +00:00
|
|
|
// Its an edit
|
2020-09-06 16:15:25 +00:00
|
|
|
if (this.props.privateMessage) {
|
2020-12-24 01:58:27 +00:00
|
|
|
this.state.privateMessageForm.content = this.props.privateMessage.private_message.content;
|
2020-09-06 16:15:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
componentDidMount() {
|
|
|
|
setupTippy();
|
|
|
|
}
|
|
|
|
|
|
|
|
componentDidUpdate() {
|
|
|
|
if (!this.state.loading && this.state.privateMessageForm.content) {
|
|
|
|
window.onbeforeunload = () => true;
|
|
|
|
} else {
|
|
|
|
window.onbeforeunload = undefined;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
componentWillUnmount() {
|
2020-09-08 18:44:55 +00:00
|
|
|
if (isBrowser()) {
|
|
|
|
this.subscription.unsubscribe();
|
|
|
|
window.onbeforeunload = null;
|
|
|
|
}
|
2020-09-06 16:15:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
return (
|
|
|
|
<div>
|
|
|
|
<Prompt
|
|
|
|
when={!this.state.loading && this.state.privateMessageForm.content}
|
2021-02-22 02:39:04 +00:00
|
|
|
message={i18n.t("block_leaving")}
|
2020-09-06 16:15:25 +00:00
|
|
|
/>
|
|
|
|
<form onSubmit={linkEvent(this, this.handlePrivateMessageSubmit)}>
|
|
|
|
{!this.props.privateMessage && (
|
|
|
|
<div class="form-group row">
|
|
|
|
<label class="col-sm-2 col-form-label">
|
2021-02-22 02:39:04 +00:00
|
|
|
{capitalizeFirstLetter(i18n.t("to"))}
|
2020-09-06 16:15:25 +00:00
|
|
|
</label>
|
|
|
|
|
2020-09-08 18:44:55 +00:00
|
|
|
<div class="col-sm-10 form-control-plaintext">
|
2021-03-15 18:09:31 +00:00
|
|
|
<PersonListing person={this.props.recipient} />
|
2020-09-08 18:44:55 +00:00
|
|
|
</div>
|
2020-09-06 16:15:25 +00:00
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
<div class="form-group row">
|
|
|
|
<label class="col-sm-2 col-form-label">
|
2021-02-22 02:39:04 +00:00
|
|
|
{i18n.t("message")}
|
2020-09-06 16:15:25 +00:00
|
|
|
<span
|
|
|
|
onClick={linkEvent(this, this.handleShowDisclaimer)}
|
2021-02-06 20:20:41 +00:00
|
|
|
role="button"
|
2020-09-06 16:15:25 +00:00
|
|
|
class="ml-2 pointer text-danger"
|
2021-03-01 21:23:25 +00:00
|
|
|
data-tippy-content={i18n.t("private_message_disclaimer")}
|
|
|
|
aria-label={i18n.t("private_message_disclaimer")}
|
2020-09-06 16:15:25 +00:00
|
|
|
>
|
2021-02-11 20:35:27 +00:00
|
|
|
<Icon icon="alert-triangle" classes="icon-inline" />
|
2020-09-06 16:15:25 +00:00
|
|
|
</span>
|
|
|
|
</label>
|
|
|
|
<div class="col-sm-10">
|
|
|
|
<MarkdownTextArea
|
|
|
|
initialContent={this.state.privateMessageForm.content}
|
|
|
|
onContentChange={this.handleContentChange}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
{this.state.showDisclaimer && (
|
|
|
|
<div class="form-group row">
|
|
|
|
<div class="offset-sm-2 col-sm-10">
|
|
|
|
<div class="alert alert-danger" role="alert">
|
|
|
|
<T i18nKey="private_message_disclaimer">
|
|
|
|
#
|
|
|
|
<a
|
|
|
|
class="alert-link"
|
|
|
|
rel="noopener"
|
|
|
|
href="https://element.io/get-started"
|
|
|
|
>
|
|
|
|
#
|
|
|
|
</a>
|
|
|
|
</T>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
<div class="form-group row">
|
|
|
|
<div class="offset-sm-2 col-sm-10">
|
|
|
|
<button
|
|
|
|
type="submit"
|
|
|
|
class="btn btn-secondary mr-2"
|
|
|
|
disabled={this.state.loading}
|
|
|
|
>
|
|
|
|
{this.state.loading ? (
|
2021-02-11 20:35:27 +00:00
|
|
|
<Spinner />
|
2020-09-06 16:15:25 +00:00
|
|
|
) : this.props.privateMessage ? (
|
2021-02-22 02:39:04 +00:00
|
|
|
capitalizeFirstLetter(i18n.t("save"))
|
2020-09-06 16:15:25 +00:00
|
|
|
) : (
|
2021-02-22 02:39:04 +00:00
|
|
|
capitalizeFirstLetter(i18n.t("send_message"))
|
2020-09-06 16:15:25 +00:00
|
|
|
)}
|
|
|
|
</button>
|
|
|
|
{this.props.privateMessage && (
|
|
|
|
<button
|
|
|
|
type="button"
|
|
|
|
class="btn btn-secondary"
|
|
|
|
onClick={linkEvent(this, this.handleCancel)}
|
|
|
|
>
|
2021-02-22 02:39:04 +00:00
|
|
|
{i18n.t("cancel")}
|
2020-09-06 16:15:25 +00:00
|
|
|
</button>
|
|
|
|
)}
|
|
|
|
<ul class="d-inline-block float-right list-inline mb-1 text-muted font-weight-bold">
|
|
|
|
<li class="list-inline-item"></li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
handlePrivateMessageSubmit(i: PrivateMessageForm, event: any) {
|
|
|
|
event.preventDefault();
|
|
|
|
if (i.props.privateMessage) {
|
2020-12-24 01:58:27 +00:00
|
|
|
let form: EditPrivateMessage = {
|
2021-01-18 22:42:41 +00:00
|
|
|
private_message_id: i.props.privateMessage.private_message.id,
|
2020-09-06 16:15:25 +00:00
|
|
|
content: i.state.privateMessageForm.content,
|
2020-12-24 22:05:57 +00:00
|
|
|
auth: authField(),
|
2020-09-06 16:15:25 +00:00
|
|
|
};
|
2020-12-24 22:05:57 +00:00
|
|
|
WebSocketService.Instance.send(wsClient.editPrivateMessage(form));
|
2020-09-06 16:15:25 +00:00
|
|
|
} else {
|
2020-12-24 22:05:57 +00:00
|
|
|
WebSocketService.Instance.send(
|
|
|
|
wsClient.createPrivateMessage(i.state.privateMessageForm)
|
2020-09-06 16:15:25 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
i.state.loading = true;
|
|
|
|
i.setState(i.state);
|
|
|
|
}
|
|
|
|
|
|
|
|
handleContentChange(val: string) {
|
|
|
|
this.state.privateMessageForm.content = val;
|
|
|
|
this.setState(this.state);
|
|
|
|
}
|
|
|
|
|
|
|
|
handleCancel(i: PrivateMessageForm) {
|
|
|
|
i.props.onCancel();
|
|
|
|
}
|
|
|
|
|
|
|
|
handlePreviewToggle(i: PrivateMessageForm, event: any) {
|
|
|
|
event.preventDefault();
|
|
|
|
i.state.previewMode = !i.state.previewMode;
|
|
|
|
i.setState(i.state);
|
|
|
|
}
|
|
|
|
|
|
|
|
handleShowDisclaimer(i: PrivateMessageForm) {
|
|
|
|
i.state.showDisclaimer = !i.state.showDisclaimer;
|
|
|
|
i.setState(i.state);
|
|
|
|
}
|
|
|
|
|
2020-12-24 01:58:27 +00:00
|
|
|
parseMessage(msg: any) {
|
|
|
|
let op = wsUserOp(msg);
|
2020-09-06 16:15:25 +00:00
|
|
|
if (msg.error) {
|
2021-02-22 02:39:04 +00:00
|
|
|
toast(i18n.t(msg.error), "danger");
|
2020-09-06 16:15:25 +00:00
|
|
|
this.state.loading = false;
|
|
|
|
this.setState(this.state);
|
|
|
|
return;
|
|
|
|
} else if (
|
2020-12-24 01:58:27 +00:00
|
|
|
op == UserOperation.EditPrivateMessage ||
|
|
|
|
op == UserOperation.DeletePrivateMessage ||
|
|
|
|
op == UserOperation.MarkPrivateMessageAsRead
|
2020-09-06 16:15:25 +00:00
|
|
|
) {
|
2020-12-24 01:58:27 +00:00
|
|
|
let data = wsJsonToRes<PrivateMessageResponse>(msg).data;
|
2020-09-06 16:15:25 +00:00
|
|
|
this.state.loading = false;
|
2020-12-24 01:58:27 +00:00
|
|
|
this.props.onEdit(data.private_message_view);
|
|
|
|
} else if (op == UserOperation.CreatePrivateMessage) {
|
|
|
|
let data = wsJsonToRes<PrivateMessageResponse>(msg).data;
|
2020-09-06 16:15:25 +00:00
|
|
|
this.state.loading = false;
|
2020-12-24 01:58:27 +00:00
|
|
|
this.props.onCreate(data.private_message_view);
|
2020-09-06 16:15:25 +00:00
|
|
|
this.setState(this.state);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|