1 import { Component, linkEvent } from 'inferno';
2 import { Link } from 'inferno-router';
4 PrivateMessage as PrivateMessageI,
5 EditPrivateMessageForm,
6 } from '../interfaces';
7 import { WebSocketService, UserService } from '../services';
10 pictshareAvatarThumbnail,
14 import { MomentTime } from './moment-time';
15 import { PrivateMessageForm } from './private-message-form';
16 import { i18n } from '../i18next';
18 interface PrivateMessageState {
25 interface PrivateMessageProps {
26 privateMessage: PrivateMessageI;
29 export class PrivateMessage extends Component<
33 private emptyState: PrivateMessageState = {
40 constructor(props: any, context: any) {
41 super(props, context);
43 this.state = this.emptyState;
44 this.handleReplyCancel = this.handleReplyCancel.bind(this);
45 this.handlePrivateMessageCreate = this.handlePrivateMessageCreate.bind(
48 this.handlePrivateMessageEdit = this.handlePrivateMessageEdit.bind(this);
52 return UserService.Instance.user.id == this.props.privateMessage.creator_id;
56 let message = this.props.privateMessage;
58 <div class="border-top border-light">
60 <ul class="list-inline mb-0 text-muted small">
61 {/* TODO refactor this */}
62 <li className="list-inline-item">
63 {this.mine ? i18n.t('to') : i18n.t('from')}
65 <li className="list-inline-item">
67 className="text-body font-weight-bold"
70 ? `/u/${message.recipient_name}`
71 : `/u/${message.creator_name}`
75 ? message.recipient_avatar
76 : message.creator_avatar) &&
81 src={pictshareAvatarThumbnail(
83 ? message.recipient_avatar
84 : message.creator_avatar
86 class="rounded-circle mr-1"
90 {this.mine ? message.recipient_name : message.creator_name}
94 <li className="list-inline-item">
96 <MomentTime data={message} />
99 <li className="list-inline-item">
101 className="pointer text-monospace"
102 onClick={linkEvent(this, this.handleMessageCollapse)}
104 {this.state.collapsed ? (
105 <svg class="icon icon-inline">
106 <use xlinkHref="#icon-plus-square"></use>
109 <svg class="icon icon-inline">
110 <use xlinkHref="#icon-minus-square"></use>
116 {this.state.showEdit && (
118 privateMessage={message}
119 onEdit={this.handlePrivateMessageEdit}
120 onCancel={this.handleReplyCancel}
123 {!this.state.showEdit && !this.state.collapsed && (
125 {this.state.viewSource ? (
126 <pre>{this.messageUnlessRemoved}</pre>
130 dangerouslySetInnerHTML={mdToHtml(this.messageUnlessRemoved)}
133 <ul class="list-inline mb-0 text-muted font-weight-bold">
136 <li className="list-inline-item">
138 class="btn btn-link btn-sm btn-animate text-muted"
139 onClick={linkEvent(this, this.handleMarkRead)}
142 ? i18n.t('mark_as_unread')
143 : i18n.t('mark_as_read')
147 class={`icon icon-inline ${message.read &&
150 <use xlinkHref="#icon-check"></use>
154 <li className="list-inline-item">
156 class="btn btn-link btn-sm btn-animate text-muted"
157 onClick={linkEvent(this, this.handleReplyClick)}
158 data-tippy-content={i18n.t('reply')}
160 <svg class="icon icon-inline">
161 <use xlinkHref="#icon-reply1"></use>
169 <li className="list-inline-item">
171 class="btn btn-link btn-sm btn-animate text-muted"
172 onClick={linkEvent(this, this.handleEditClick)}
173 data-tippy-content={i18n.t('edit')}
175 <svg class="icon icon-inline">
176 <use xlinkHref="#icon-edit"></use>
180 <li className="list-inline-item">
182 class="btn btn-link btn-sm btn-animate text-muted"
183 onClick={linkEvent(this, this.handleDeleteClick)}
191 class={`icon icon-inline ${message.deleted &&
194 <use xlinkHref="#icon-trash"></use>
200 <li className="list-inline-item">
202 class="btn btn-link btn-sm btn-animate text-muted"
203 onClick={linkEvent(this, this.handleViewSource)}
204 data-tippy-content={i18n.t('view_source')}
207 class={`icon icon-inline ${this.state.viewSource &&
210 <use xlinkHref="#icon-file-text"></use>
218 {this.state.showReply && (
221 recipient_id: this.props.privateMessage.creator_id,
223 onCreate={this.handlePrivateMessageCreate}
226 {/* A collapsed clearfix */}
227 {this.state.collapsed && <div class="row col-12"></div>}
232 get messageUnlessRemoved(): string {
233 let message = this.props.privateMessage;
234 return message.deleted ? `*${i18n.t('deleted')}*` : message.content;
237 handleReplyClick(i: PrivateMessage) {
238 i.state.showReply = true;
242 handleEditClick(i: PrivateMessage) {
243 i.state.showEdit = true;
247 handleDeleteClick(i: PrivateMessage) {
248 let form: EditPrivateMessageForm = {
249 edit_id: i.props.privateMessage.id,
250 deleted: !i.props.privateMessage.deleted,
252 WebSocketService.Instance.editPrivateMessage(form);
255 handleReplyCancel() {
256 this.state.showReply = false;
257 this.state.showEdit = false;
258 this.setState(this.state);
261 handleMarkRead(i: PrivateMessage) {
262 let form: EditPrivateMessageForm = {
263 edit_id: i.props.privateMessage.id,
264 read: !i.props.privateMessage.read,
266 WebSocketService.Instance.editPrivateMessage(form);
269 handleMessageCollapse(i: PrivateMessage) {
270 i.state.collapsed = !i.state.collapsed;
274 handleViewSource(i: PrivateMessage) {
275 i.state.viewSource = !i.state.viewSource;
279 handlePrivateMessageEdit() {
280 this.state.showEdit = false;
281 this.setState(this.state);
284 handlePrivateMessageCreate() {
285 this.state.showReply = false;
286 this.setState(this.state);
287 toast(i18n.t('message_sent'));