
* wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * wip * Update src/shared/utils/app/convert-comment-sort-type.ts Co-authored-by: SleeplessOne1917 <abias1122@gmail.com> * prettier pass --------- Co-authored-by: SleeplessOne1917 <abias1122@gmail.com>
205 lines
6 KiB
TypeScript
205 lines
6 KiB
TypeScript
import { myAuthRequired } from "@utils/app";
|
|
import { capitalizeFirstLetter } from "@utils/helpers";
|
|
import { Component, InfernoNode, linkEvent } from "inferno";
|
|
import { T } from "inferno-i18next-dess";
|
|
import {
|
|
CreatePrivateMessage,
|
|
EditPrivateMessage,
|
|
Person,
|
|
PrivateMessageView,
|
|
} from "lemmy-js-client";
|
|
import { relTags } from "../../config";
|
|
import { i18n } from "../../i18next";
|
|
import { setupTippy } from "../../tippy";
|
|
import { Icon, Spinner } from "../common/icon";
|
|
import { MarkdownTextArea } from "../common/markdown-textarea";
|
|
import NavigationPrompt from "../common/navigation-prompt";
|
|
import { PersonListing } from "../person/person-listing";
|
|
|
|
interface PrivateMessageFormProps {
|
|
recipient: Person;
|
|
privateMessageView?: PrivateMessageView; // If a pm is given, that means this is an edit
|
|
onCancel?(): any;
|
|
onCreate?(form: CreatePrivateMessage): void;
|
|
onEdit?(form: EditPrivateMessage): void;
|
|
}
|
|
|
|
interface PrivateMessageFormState {
|
|
content?: string;
|
|
loading: boolean;
|
|
previewMode: boolean;
|
|
showDisclaimer: boolean;
|
|
submitted: boolean;
|
|
}
|
|
|
|
export class PrivateMessageForm extends Component<
|
|
PrivateMessageFormProps,
|
|
PrivateMessageFormState
|
|
> {
|
|
state: PrivateMessageFormState = {
|
|
loading: false,
|
|
previewMode: false,
|
|
showDisclaimer: false,
|
|
content: this.props.privateMessageView
|
|
? this.props.privateMessageView.private_message.content
|
|
: undefined,
|
|
submitted: false,
|
|
};
|
|
|
|
constructor(props: any, context: any) {
|
|
super(props, context);
|
|
|
|
this.handleContentChange = this.handleContentChange.bind(this);
|
|
}
|
|
|
|
componentDidMount() {
|
|
setupTippy();
|
|
}
|
|
|
|
componentWillReceiveProps(
|
|
nextProps: Readonly<{ children?: InfernoNode } & PrivateMessageFormProps>
|
|
): void {
|
|
if (this.props != nextProps) {
|
|
this.setState({ loading: false, content: undefined, previewMode: false });
|
|
}
|
|
}
|
|
// TODO
|
|
// <Prompt
|
|
// when={!this.state.loading && this.state.content}
|
|
// message={i18n.t("block_leaving")}
|
|
// />
|
|
|
|
render() {
|
|
return (
|
|
<form
|
|
className="private-message-form"
|
|
onSubmit={linkEvent(this, this.handlePrivateMessageSubmit)}
|
|
>
|
|
<NavigationPrompt
|
|
when={
|
|
!this.state.loading && !!this.state.content && !this.state.submitted
|
|
}
|
|
/>
|
|
{!this.props.privateMessageView && (
|
|
<div className="mb-3 row">
|
|
<label className="col-sm-2 col-form-label">
|
|
{capitalizeFirstLetter(i18n.t("to"))}
|
|
</label>
|
|
|
|
<div className="col-sm-10 form-control-plaintext">
|
|
<PersonListing person={this.props.recipient} />
|
|
</div>
|
|
</div>
|
|
)}
|
|
<div className="mb-3 row">
|
|
<label className="col-sm-2 col-form-label">
|
|
{i18n.t("message")}
|
|
<button
|
|
className="btn btn-link text-warning d-inline-block"
|
|
onClick={linkEvent(this, this.handleShowDisclaimer)}
|
|
data-tippy-content={i18n.t("private_message_disclaimer")}
|
|
aria-label={i18n.t("private_message_disclaimer")}
|
|
>
|
|
<Icon icon="alert-triangle" classes="icon-inline" />
|
|
</button>
|
|
</label>
|
|
<div className="col-sm-10">
|
|
<MarkdownTextArea
|
|
initialContent={this.state.content}
|
|
onContentChange={this.handleContentChange}
|
|
allLanguages={[]}
|
|
siteLanguages={[]}
|
|
hideNavigationWarnings
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{this.state.showDisclaimer && (
|
|
<div className="mb-3 row">
|
|
<div className="offset-sm-2 col-sm-10">
|
|
<div className="alert alert-danger" role="alert">
|
|
<T i18nKey="private_message_disclaimer">
|
|
#
|
|
<a
|
|
className="alert-link"
|
|
rel={relTags}
|
|
href="https://element.io/get-started"
|
|
>
|
|
#
|
|
</a>
|
|
</T>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
<div className="mb-3 row">
|
|
<div className="offset-sm-2 col-sm-10">
|
|
<button
|
|
type="submit"
|
|
className="btn btn-secondary me-2"
|
|
disabled={this.state.loading}
|
|
>
|
|
{this.state.loading ? (
|
|
<Spinner />
|
|
) : this.props.privateMessageView ? (
|
|
capitalizeFirstLetter(i18n.t("save"))
|
|
) : (
|
|
capitalizeFirstLetter(i18n.t("send_message"))
|
|
)}
|
|
</button>
|
|
{this.props.privateMessageView && (
|
|
<button
|
|
type="button"
|
|
className="btn btn-secondary"
|
|
onClick={linkEvent(this, this.handleCancel)}
|
|
>
|
|
{i18n.t("cancel")}
|
|
</button>
|
|
)}
|
|
<ul className="d-inline-block float-right list-inline mb-1 text-muted font-weight-bold">
|
|
<li className="list-inline-item"></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
);
|
|
}
|
|
|
|
handlePrivateMessageSubmit(i: PrivateMessageForm, event: any) {
|
|
event.preventDefault();
|
|
i.setState({ loading: true, submitted: true });
|
|
const pm = i.props.privateMessageView;
|
|
const auth = myAuthRequired();
|
|
const content = i.state.content ?? "";
|
|
if (pm) {
|
|
i.props.onEdit?.({
|
|
private_message_id: pm.private_message.id,
|
|
content,
|
|
auth,
|
|
});
|
|
} else {
|
|
i.props.onCreate?.({
|
|
content,
|
|
recipient_id: i.props.recipient.id,
|
|
auth,
|
|
});
|
|
}
|
|
}
|
|
|
|
handleContentChange(val: string) {
|
|
this.setState({ content: val });
|
|
}
|
|
|
|
handleCancel(i: PrivateMessageForm) {
|
|
i.props.onCancel?.();
|
|
}
|
|
|
|
handlePreviewToggle(i: PrivateMessageForm, event: any) {
|
|
event.preventDefault();
|
|
i.setState({ previewMode: !i.state.previewMode });
|
|
}
|
|
|
|
handleShowDisclaimer(i: PrivateMessageForm) {
|
|
i.setState({ showDisclaimer: !i.state.showDisclaimer });
|
|
}
|
|
}
|