1 import { Component, linkEvent } from "inferno";
5 MarkPrivateMessageAsRead,
7 } from "lemmy-js-client";
8 import { WebSocketService, UserService } from "../services";
9 import { authField, mdToHtml, toast, wsClient } from "../utils";
10 import { MomentTime } from "./moment-time";
11 import { PrivateMessageForm } from "./private-message-form";
12 import { PersonListing } from "./person-listing";
13 import { Icon } from "./icon";
14 import { i18n } from "../i18next";
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 = this.handlePrivateMessageCreate.bind(
46 this.handlePrivateMessageEdit = this.handlePrivateMessageEdit.bind(this);
51 UserService.Instance.localUserView &&
52 UserService.Instance.localUserView.person.id ==
53 this.props.private_message_view.creator.id
58 let message_view = this.props.private_message_view;
59 // TODO check this again
60 let otherPerson: PersonSafe = this.mine
61 ? message_view.recipient
62 : message_view.creator;
65 <div class="border-top border-light">
67 <ul class="list-inline mb-0 text-muted small">
68 {/* TODO refactor this */}
69 <li className="list-inline-item">
70 {this.mine ? i18n.t("to") : i18n.t("from")}
72 <li className="list-inline-item">
73 <PersonListing person={otherPerson} />
75 <li className="list-inline-item">
77 <MomentTime data={message_view.private_message} />
80 <li className="list-inline-item">
83 className="pointer text-monospace"
84 onClick={linkEvent(this, this.handleMessageCollapse)}
86 {this.state.collapsed ? (
87 <Icon icon="plus-square" classes="icon-inline" />
89 <Icon icon="minus-square" classes="icon-inline" />
94 {this.state.showEdit && (
96 recipient={otherPerson}
97 privateMessage={message_view}
98 onEdit={this.handlePrivateMessageEdit}
99 onCreate={this.handlePrivateMessageCreate}
100 onCancel={this.handleReplyCancel}
103 {!this.state.showEdit && !this.state.collapsed && (
105 {this.state.viewSource ? (
106 <pre>{this.messageUnlessRemoved}</pre>
110 dangerouslySetInnerHTML={mdToHtml(this.messageUnlessRemoved)}
113 <ul class="list-inline mb-0 text-muted font-weight-bold">
116 <li className="list-inline-item">
118 class="btn btn-link btn-animate text-muted"
119 onClick={linkEvent(this, this.handleMarkRead)}
121 message_view.private_message.read
122 ? i18n.t("mark_as_unread")
123 : i18n.t("mark_as_read")
126 message_view.private_message.read
127 ? i18n.t("mark_as_unread")
128 : i18n.t("mark_as_read")
133 classes={`icon-inline ${
134 message_view.private_message.read && "text-success"
139 <li className="list-inline-item">
141 class="btn btn-link btn-animate text-muted"
142 onClick={linkEvent(this, this.handleReplyClick)}
143 data-tippy-content={i18n.t("reply")}
144 aria-label={i18n.t("reply")}
146 <Icon icon="reply1" classes="icon-inline" />
153 <li className="list-inline-item">
155 class="btn btn-link btn-animate text-muted"
156 onClick={linkEvent(this, this.handleEditClick)}
157 data-tippy-content={i18n.t("edit")}
158 aria-label={i18n.t("edit")}
160 <Icon icon="edit" classes="icon-inline" />
163 <li className="list-inline-item">
165 class="btn btn-link btn-animate text-muted"
166 onClick={linkEvent(this, this.handleDeleteClick)}
168 !message_view.private_message.deleted
173 !message_view.private_message.deleted
180 classes={`icon-inline ${
181 message_view.private_message.deleted &&
189 <li className="list-inline-item">
191 class="btn btn-link btn-animate text-muted"
192 onClick={linkEvent(this, this.handleViewSource)}
193 data-tippy-content={i18n.t("view_source")}
194 aria-label={i18n.t("view_source")}
198 classes={`icon-inline ${
199 this.state.viewSource && "text-success"
208 {this.state.showReply && (
210 recipient={otherPerson}
211 onCreate={this.handlePrivateMessageCreate}
214 {/* A collapsed clearfix */}
215 {this.state.collapsed && <div class="row col-12"></div>}
220 get messageUnlessRemoved(): string {
221 let message = this.props.private_message_view.private_message;
222 return message.deleted ? `*${i18n.t("deleted")}*` : message.content;
225 handleReplyClick(i: PrivateMessage) {
226 i.state.showReply = true;
230 handleEditClick(i: PrivateMessage) {
231 i.state.showEdit = true;
235 handleDeleteClick(i: PrivateMessage) {
236 let form: DeletePrivateMessage = {
237 private_message_id: i.props.private_message_view.private_message.id,
238 deleted: !i.props.private_message_view.private_message.deleted,
241 WebSocketService.Instance.send(wsClient.deletePrivateMessage(form));
244 handleReplyCancel() {
245 this.state.showReply = false;
246 this.state.showEdit = false;
247 this.setState(this.state);
250 handleMarkRead(i: PrivateMessage) {
251 let form: MarkPrivateMessageAsRead = {
252 private_message_id: i.props.private_message_view.private_message.id,
253 read: !i.props.private_message_view.private_message.read,
256 WebSocketService.Instance.send(wsClient.markPrivateMessageAsRead(form));
259 handleMessageCollapse(i: PrivateMessage) {
260 i.state.collapsed = !i.state.collapsed;
264 handleViewSource(i: PrivateMessage) {
265 i.state.viewSource = !i.state.viewSource;
269 handlePrivateMessageEdit() {
270 this.state.showEdit = false;
271 this.setState(this.state);
274 handlePrivateMessageCreate(message: PrivateMessageView) {
276 UserService.Instance.localUserView &&
277 message.creator.id == UserService.Instance.localUserView.person.id
279 this.state.showReply = false;
280 this.setState(this.state);
281 toast(i18n.t("message_sent"));