1 import { Component, linkEvent } from "inferno";
4 MarkPrivateMessageAsRead,
7 } from "lemmy-js-client";
8 import { i18n } from "../../i18next";
9 import { UserService, WebSocketService } from "../../services";
10 import { authField, mdToHtml, toast, wsClient } from "../../utils";
11 import { Icon } from "../common/icon";
12 import { MomentTime } from "../common/moment-time";
13 import { PersonListing } from "../person/person-listing";
14 import { PrivateMessageForm } from "./private-message-form";
16 interface PrivateMessageState {
23 interface PrivateMessageProps {
24 private_message_view: PrivateMessageView;
27 export class PrivateMessage extends Component<
31 private emptyState: PrivateMessageState = {
38 constructor(props: any, context: any) {
39 super(props, context);
41 this.state = this.emptyState;
42 this.handleReplyCancel = this.handleReplyCancel.bind(this);
43 this.handlePrivateMessageCreate =
44 this.handlePrivateMessageCreate.bind(this);
45 this.handlePrivateMessageEdit = this.handlePrivateMessageEdit.bind(this);
50 UserService.Instance.localUserView &&
51 UserService.Instance.localUserView.person.id ==
52 this.props.private_message_view.creator.id
57 let message_view = this.props.private_message_view;
58 // TODO check this again
59 let otherPerson: PersonSafe = this.mine
60 ? message_view.recipient
61 : message_view.creator;
64 <div class="border-top border-light">
66 <ul class="list-inline mb-0 text-muted small">
67 {/* TODO refactor this */}
68 <li className="list-inline-item">
69 {this.mine ? i18n.t("to") : i18n.t("from")}
71 <li className="list-inline-item">
72 <PersonListing person={otherPerson} />
74 <li className="list-inline-item">
76 <MomentTime data={message_view.private_message} />
79 <li className="list-inline-item">
82 className="pointer text-monospace"
83 onClick={linkEvent(this, this.handleMessageCollapse)}
85 {this.state.collapsed ? (
86 <Icon icon="plus-square" classes="icon-inline" />
88 <Icon icon="minus-square" classes="icon-inline" />
93 {this.state.showEdit && (
95 recipient={otherPerson}
96 privateMessage={message_view}
97 onEdit={this.handlePrivateMessageEdit}
98 onCreate={this.handlePrivateMessageCreate}
99 onCancel={this.handleReplyCancel}
102 {!this.state.showEdit && !this.state.collapsed && (
104 {this.state.viewSource ? (
105 <pre>{this.messageUnlessRemoved}</pre>
109 dangerouslySetInnerHTML={mdToHtml(this.messageUnlessRemoved)}
112 <ul class="list-inline mb-0 text-muted font-weight-bold">
115 <li className="list-inline-item">
117 class="btn btn-link btn-animate text-muted"
118 onClick={linkEvent(this, this.handleMarkRead)}
120 message_view.private_message.read
121 ? i18n.t("mark_as_unread")
122 : i18n.t("mark_as_read")
125 message_view.private_message.read
126 ? i18n.t("mark_as_unread")
127 : i18n.t("mark_as_read")
132 classes={`icon-inline ${
133 message_view.private_message.read && "text-success"
138 <li className="list-inline-item">
140 class="btn btn-link btn-animate text-muted"
141 onClick={linkEvent(this, this.handleReplyClick)}
142 data-tippy-content={i18n.t("reply")}
143 aria-label={i18n.t("reply")}
145 <Icon icon="reply1" classes="icon-inline" />
152 <li className="list-inline-item">
154 class="btn btn-link btn-animate text-muted"
155 onClick={linkEvent(this, this.handleEditClick)}
156 data-tippy-content={i18n.t("edit")}
157 aria-label={i18n.t("edit")}
159 <Icon icon="edit" classes="icon-inline" />
162 <li className="list-inline-item">
164 class="btn btn-link btn-animate text-muted"
165 onClick={linkEvent(this, this.handleDeleteClick)}
167 !message_view.private_message.deleted
172 !message_view.private_message.deleted
179 classes={`icon-inline ${
180 message_view.private_message.deleted &&
188 <li className="list-inline-item">
190 class="btn btn-link btn-animate text-muted"
191 onClick={linkEvent(this, this.handleViewSource)}
192 data-tippy-content={i18n.t("view_source")}
193 aria-label={i18n.t("view_source")}
197 classes={`icon-inline ${
198 this.state.viewSource && "text-success"
207 {this.state.showReply && (
209 recipient={otherPerson}
210 onCreate={this.handlePrivateMessageCreate}
213 {/* A collapsed clearfix */}
214 {this.state.collapsed && <div class="row col-12"></div>}
219 get messageUnlessRemoved(): string {
220 let message = this.props.private_message_view.private_message;
221 return message.deleted ? `*${i18n.t("deleted")}*` : message.content;
224 handleReplyClick(i: PrivateMessage) {
225 i.state.showReply = true;
229 handleEditClick(i: PrivateMessage) {
230 i.state.showEdit = true;
234 handleDeleteClick(i: PrivateMessage) {
235 let form: DeletePrivateMessage = {
236 private_message_id: i.props.private_message_view.private_message.id,
237 deleted: !i.props.private_message_view.private_message.deleted,
240 WebSocketService.Instance.send(wsClient.deletePrivateMessage(form));
243 handleReplyCancel() {
244 this.state.showReply = false;
245 this.state.showEdit = false;
246 this.setState(this.state);
249 handleMarkRead(i: PrivateMessage) {
250 let form: MarkPrivateMessageAsRead = {
251 private_message_id: i.props.private_message_view.private_message.id,
252 read: !i.props.private_message_view.private_message.read,
255 WebSocketService.Instance.send(wsClient.markPrivateMessageAsRead(form));
258 handleMessageCollapse(i: PrivateMessage) {
259 i.state.collapsed = !i.state.collapsed;
263 handleViewSource(i: PrivateMessage) {
264 i.state.viewSource = !i.state.viewSource;
268 handlePrivateMessageEdit() {
269 this.state.showEdit = false;
270 this.setState(this.state);
273 handlePrivateMessageCreate(message: PrivateMessageView) {
275 UserService.Instance.localUserView &&
276 message.creator.id == UserService.Instance.localUserView.person.id
278 this.state.showReply = false;
279 this.setState(this.state);
280 toast(i18n.t("message_sent"));