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 { UserListing } from './user-listing';
13 import { i18n } from '../i18next';
15 interface PrivateMessageState {
22 interface PrivateMessageProps {
23 private_message_view: PrivateMessageView;
26 export class PrivateMessage extends Component<
30 private emptyState: PrivateMessageState = {
37 constructor(props: any, context: any) {
38 super(props, context);
40 this.state = this.emptyState;
41 this.handleReplyCancel = this.handleReplyCancel.bind(this);
42 this.handlePrivateMessageCreate = this.handlePrivateMessageCreate.bind(
45 this.handlePrivateMessageEdit = this.handlePrivateMessageEdit.bind(this);
50 UserService.Instance.user &&
51 UserService.Instance.user.id == this.props.private_message_view.creator.id
56 let message_view = this.props.private_message_view;
57 // TODO check this again
58 let userOther: UserSafe = this.mine
59 ? message_view.recipient
60 : message_view.creator;
63 <div class="border-top border-light">
65 <ul class="list-inline mb-0 text-muted small">
66 {/* TODO refactor this */}
67 <li className="list-inline-item">
68 {this.mine ? i18n.t('to') : i18n.t('from')}
70 <li className="list-inline-item">
71 <UserListing user={userOther} />
73 <li className="list-inline-item">
75 <MomentTime data={message_view.private_message} />
78 <li className="list-inline-item">
80 className="pointer text-monospace"
81 onClick={linkEvent(this, this.handleMessageCollapse)}
83 {this.state.collapsed ? (
84 <svg class="icon icon-inline">
85 <use xlinkHref="#icon-plus-square"></use>
88 <svg class="icon icon-inline">
89 <use xlinkHref="#icon-minus-square"></use>
95 {this.state.showEdit && (
98 privateMessage={message_view}
99 onEdit={this.handlePrivateMessageEdit}
100 onCreate={this.handlePrivateMessageCreate}
101 onCancel={this.handleReplyCancel}
104 {!this.state.showEdit && !this.state.collapsed && (
106 {this.state.viewSource ? (
107 <pre>{this.messageUnlessRemoved}</pre>
111 dangerouslySetInnerHTML={mdToHtml(this.messageUnlessRemoved)}
114 <ul class="list-inline mb-0 text-muted font-weight-bold">
117 <li className="list-inline-item">
119 class="btn btn-link btn-animate text-muted"
120 onClick={linkEvent(this, this.handleMarkRead)}
122 message_view.private_message.read
123 ? i18n.t('mark_as_unread')
124 : i18n.t('mark_as_read')
128 class={`icon icon-inline ${
129 message_view.private_message.read && 'text-success'
132 <use xlinkHref="#icon-check"></use>
136 <li className="list-inline-item">
138 class="btn btn-link btn-animate text-muted"
139 onClick={linkEvent(this, this.handleReplyClick)}
140 data-tippy-content={i18n.t('reply')}
142 <svg class="icon icon-inline">
143 <use xlinkHref="#icon-reply1"></use>
151 <li className="list-inline-item">
153 class="btn btn-link btn-animate text-muted"
154 onClick={linkEvent(this, this.handleEditClick)}
155 data-tippy-content={i18n.t('edit')}
157 <svg class="icon icon-inline">
158 <use xlinkHref="#icon-edit"></use>
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
173 class={`icon icon-inline ${
174 message_view.private_message.deleted &&
178 <use xlinkHref="#icon-trash"></use>
184 <li className="list-inline-item">
186 class="btn btn-link btn-animate text-muted"
187 onClick={linkEvent(this, this.handleViewSource)}
188 data-tippy-content={i18n.t('view_source')}
191 class={`icon icon-inline ${
192 this.state.viewSource && 'text-success'
195 <use xlinkHref="#icon-file-text"></use>
203 {this.state.showReply && (
205 recipient={userOther}
206 onCreate={this.handlePrivateMessageCreate}
209 {/* A collapsed clearfix */}
210 {this.state.collapsed && <div class="row col-12"></div>}
215 get messageUnlessRemoved(): string {
216 let message = this.props.private_message_view.private_message;
217 return message.deleted ? `*${i18n.t('deleted')}*` : message.content;
220 handleReplyClick(i: PrivateMessage) {
221 i.state.showReply = true;
225 handleEditClick(i: PrivateMessage) {
226 i.state.showEdit = true;
230 handleDeleteClick(i: PrivateMessage) {
231 let form: DeletePrivateMessage = {
232 private_message_id: i.props.private_message_view.private_message.id,
233 deleted: !i.props.private_message_view.private_message.deleted,
236 WebSocketService.Instance.send(wsClient.deletePrivateMessage(form));
239 handleReplyCancel() {
240 this.state.showReply = false;
241 this.state.showEdit = false;
242 this.setState(this.state);
245 handleMarkRead(i: PrivateMessage) {
246 let form: MarkPrivateMessageAsRead = {
247 private_message_id: i.props.private_message_view.private_message.id,
248 read: !i.props.private_message_view.private_message.read,
251 WebSocketService.Instance.send(wsClient.markPrivateMessageAsRead(form));
254 handleMessageCollapse(i: PrivateMessage) {
255 i.state.collapsed = !i.state.collapsed;
259 handleViewSource(i: PrivateMessage) {
260 i.state.viewSource = !i.state.viewSource;
264 handlePrivateMessageEdit() {
265 this.state.showEdit = false;
266 this.setState(this.state);
269 handlePrivateMessageCreate(message: PrivateMessageView) {
271 UserService.Instance.user &&
272 message.creator.id == UserService.Instance.user.id
274 this.state.showReply = false;
275 this.setState(this.state);
276 toast(i18n.t('message_sent'));