]> Untitled Git - lemmy.git/blob - ui/src/components/private-message.tsx
Doing comment-node, comment-form and private-message.
[lemmy.git] / ui / src / components / private-message.tsx
1 import { Component, linkEvent } from 'inferno';
2 import { Link } from 'inferno-router';
3 import {
4   PrivateMessage as PrivateMessageI,
5   EditPrivateMessageForm,
6 } from '../interfaces';
7 import { WebSocketService, UserService } from '../services';
8 import {
9   mdToHtml,
10   pictshareAvatarThumbnail,
11   showAvatars,
12   toast,
13 } from '../utils';
14 import { MomentTime } from './moment-time';
15 import { PrivateMessageForm } from './private-message-form';
16 import { i18n } from '../i18next';
17
18 interface PrivateMessageState {
19   showReply: boolean;
20   showEdit: boolean;
21   collapsed: boolean;
22   viewSource: boolean;
23 }
24
25 interface PrivateMessageProps {
26   privateMessage: PrivateMessageI;
27 }
28
29 export class PrivateMessage extends Component<
30   PrivateMessageProps,
31   PrivateMessageState
32 > {
33   private emptyState: PrivateMessageState = {
34     showReply: false,
35     showEdit: false,
36     collapsed: false,
37     viewSource: false,
38   };
39
40   constructor(props: any, context: any) {
41     super(props, context);
42
43     this.state = this.emptyState;
44     this.handleReplyCancel = this.handleReplyCancel.bind(this);
45     this.handlePrivateMessageCreate = this.handlePrivateMessageCreate.bind(
46       this
47     );
48     this.handlePrivateMessageEdit = this.handlePrivateMessageEdit.bind(this);
49   }
50
51   get mine(): boolean {
52     return UserService.Instance.user.id == this.props.privateMessage.creator_id;
53   }
54
55   render() {
56     let message = this.props.privateMessage;
57     return (
58       <div class="mb-2">
59         <div>
60           <ul class="list-inline mb-0 text-muted small">
61             <li className="list-inline-item">
62               {this.mine ? i18n.t('to') : i18n.t('from')}
63             </li>
64             <li className="list-inline-item">
65               <Link
66                 className="text-info"
67                 to={
68                   this.mine
69                     ? `/u/${message.recipient_name}`
70                     : `/u/${message.creator_name}`
71                 }
72               >
73                 {(this.mine
74                   ? message.recipient_avatar
75                   : message.creator_avatar) &&
76                   showAvatars() && (
77                     <img
78                       height="32"
79                       width="32"
80                       src={pictshareAvatarThumbnail(
81                         this.mine
82                           ? message.recipient_avatar
83                           : message.creator_avatar
84                       )}
85                       class="rounded-circle mr-1"
86                     />
87                   )}
88                 <span>
89                   {this.mine ? message.recipient_name : message.creator_name}
90                 </span>
91               </Link>
92             </li>
93             <li className="list-inline-item">
94               <span>
95                 <MomentTime data={message} />
96               </span>
97             </li>
98             <li className="list-inline-item">
99               <div
100                 className="pointer text-monospace"
101                 onClick={linkEvent(this, this.handleMessageCollapse)}
102               >
103                 {this.state.collapsed ? '[+]' : '[-]'}
104               </div>
105             </li>
106           </ul>
107           {this.state.showEdit && (
108             <PrivateMessageForm
109               privateMessage={message}
110               onEdit={this.handlePrivateMessageEdit}
111               onCancel={this.handleReplyCancel}
112             />
113           )}
114           {!this.state.showEdit && !this.state.collapsed && (
115             <div>
116               {this.state.viewSource ? (
117                 <pre>{this.messageUnlessRemoved}</pre>
118               ) : (
119                 <div
120                   className="md-div"
121                   dangerouslySetInnerHTML={mdToHtml(this.messageUnlessRemoved)}
122                 />
123               )}
124               <ul class="list-inline mb-1 text-muted small font-weight-bold">
125                 {!this.mine && (
126                   <>
127                     <li className="list-inline-item">
128                       <span
129                         class="pointer"
130                         onClick={linkEvent(this, this.handleMarkRead)}
131                       >
132                         {message.read
133                           ? i18n.t('mark_as_unread')
134                           : i18n.t('mark_as_read')}
135                       </span>
136                     </li>
137                     <li className="list-inline-item">
138                       <span
139                         class="pointer"
140                         onClick={linkEvent(this, this.handleReplyClick)}
141                       >
142                         {i18n.t('reply')}
143                       </span>
144                     </li>
145                   </>
146                 )}
147                 {this.mine && (
148                   <>
149                     <li className="list-inline-item">
150                       <span
151                         class="pointer"
152                         onClick={linkEvent(this, this.handleEditClick)}
153                       >
154                         {i18n.t('edit')}
155                       </span>
156                     </li>
157                     <li className="list-inline-item">
158                       <span
159                         class="pointer"
160                         onClick={linkEvent(this, this.handleDeleteClick)}
161                       >
162                         {!message.deleted
163                           ? i18n.t('delete')
164                           : i18n.t('restore')}
165                       </span>
166                     </li>
167                   </>
168                 )}
169                 <li className="list-inline-item">•</li>
170                 <li className="list-inline-item">
171                   <span
172                     className="pointer"
173                     onClick={linkEvent(this, this.handleViewSource)}
174                   >
175                     {i18n.t('view_source')}
176                   </span>
177                 </li>
178               </ul>
179             </div>
180           )}
181         </div>
182         {this.state.showReply && (
183           <PrivateMessageForm
184             params={{
185               recipient_id: this.props.privateMessage.creator_id,
186             }}
187             onCreate={this.handlePrivateMessageCreate}
188           />
189         )}
190         {/* A collapsed clearfix */}
191         {this.state.collapsed && <div class="row col-12"></div>}
192       </div>
193     );
194   }
195
196   get messageUnlessRemoved(): string {
197     let message = this.props.privateMessage;
198     return message.deleted ? `*${i18n.t('deleted')}*` : message.content;
199   }
200
201   handleReplyClick(i: PrivateMessage) {
202     i.state.showReply = true;
203     i.setState(i.state);
204   }
205
206   handleEditClick(i: PrivateMessage) {
207     i.state.showEdit = true;
208     i.setState(i.state);
209   }
210
211   handleDeleteClick(i: PrivateMessage) {
212     let form: EditPrivateMessageForm = {
213       edit_id: i.props.privateMessage.id,
214       deleted: !i.props.privateMessage.deleted,
215     };
216     WebSocketService.Instance.editPrivateMessage(form);
217   }
218
219   handleReplyCancel() {
220     this.state.showReply = false;
221     this.state.showEdit = false;
222     this.setState(this.state);
223   }
224
225   handleMarkRead(i: PrivateMessage) {
226     let form: EditPrivateMessageForm = {
227       edit_id: i.props.privateMessage.id,
228       read: !i.props.privateMessage.read,
229     };
230     WebSocketService.Instance.editPrivateMessage(form);
231   }
232
233   handleMessageCollapse(i: PrivateMessage) {
234     i.state.collapsed = !i.state.collapsed;
235     i.setState(i.state);
236   }
237
238   handleViewSource(i: PrivateMessage) {
239     i.state.viewSource = !i.state.viewSource;
240     i.setState(i.state);
241   }
242
243   handlePrivateMessageEdit() {
244     this.state.showEdit = false;
245     this.setState(this.state);
246   }
247
248   handlePrivateMessageCreate() {
249     this.state.showReply = false;
250     this.setState(this.state);
251     toast(i18n.t('message_sent'));
252   }
253 }