]> Untitled Git - lemmy.git/blob - ui/src/components/modlog.tsx
Adds i18n to Prev and Next buttons in modlog
[lemmy.git] / ui / src / components / modlog.tsx
1 import { Component, linkEvent } from 'inferno';
2 import { Link } from 'inferno-router';
3 import { Subscription } from "rxjs";
4 import { retryWhen, delay, take } from 'rxjs/operators';
5 import { UserOperation, GetModlogForm, GetModlogResponse, ModRemovePost, ModLockPost, ModStickyPost, ModRemoveComment, ModRemoveCommunity, ModBanFromCommunity, ModBan, ModAddCommunity, ModAdd } from '../interfaces';
6 import { WebSocketService } from '../services';
7 import { msgOp, addTypeInfo, fetchLimit } from '../utils';
8 import { MomentTime } from './moment-time';
9 import * as moment from 'moment';
10 import { i18n } from '../i18next';
11 import { T } from 'inferno-i18next';
12
13 interface ModlogState {
14   combined: Array<{type_: string, data: ModRemovePost | ModLockPost | ModStickyPost | ModRemoveCommunity | ModAdd | ModBan}>,
15   communityId?: number,
16   communityName?: string,
17   page: number;
18   loading: boolean;
19 }
20
21 export class Modlog extends Component<any, ModlogState> {
22   private subscription: Subscription;
23   private emptyState: ModlogState = {
24     combined: [],
25     page: 1,
26     loading: true,
27   }
28
29   constructor(props: any, context: any) {
30     super(props, context);
31
32     this.state = this.emptyState;
33     this.state.communityId = this.props.match.params.community_id ? Number(this.props.match.params.community_id) : undefined;
34     this.subscription = WebSocketService.Instance.subject
35     .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10))))
36     .subscribe(
37       (msg) => this.parseMessage(msg),
38         (err) => console.error(err),
39         () => console.log('complete')
40     );
41
42     this.refetch();
43   }
44
45   componentWillUnmount() {
46     this.subscription.unsubscribe();
47   }
48
49   componentDidMount() {
50     document.title = `Modlog - ${WebSocketService.Instance.site.name}`;
51   }
52
53   setCombined(res: GetModlogResponse) {
54     let removed_posts = addTypeInfo(res.removed_posts, "removed_posts");
55     let locked_posts = addTypeInfo(res.locked_posts, "locked_posts");
56     let stickied_posts = addTypeInfo(res.stickied_posts, "stickied_posts");
57     let removed_comments = addTypeInfo(res.removed_comments, "removed_comments");
58     let removed_communities = addTypeInfo(res.removed_communities, "removed_communities");
59     let banned_from_community = addTypeInfo(res.banned_from_community, "banned_from_community");
60     let added_to_community = addTypeInfo(res.added_to_community, "added_to_community");
61     let added = addTypeInfo(res.added, "added");
62     let banned = addTypeInfo(res.banned, "banned");
63     this.state.combined = [];
64
65     this.state.combined.push(...removed_posts);
66     this.state.combined.push(...locked_posts);
67     this.state.combined.push(...stickied_posts);
68     this.state.combined.push(...removed_comments);
69     this.state.combined.push(...removed_communities);
70     this.state.combined.push(...banned_from_community);
71     this.state.combined.push(...added_to_community);
72     this.state.combined.push(...added);
73     this.state.combined.push(...banned);
74
75     if (this.state.communityId && this.state.combined.length > 0) {
76       this.state.communityName = (this.state.combined[0].data as ModRemovePost).community_name;
77     }
78
79     // Sort them by time
80     this.state.combined.sort((a, b) => b.data.when_.localeCompare(a.data.when_));
81
82     this.setState(this.state);
83   }
84
85   combined() {
86     return (
87       <tbody>
88         {this.state.combined.map(i =>
89           <tr>
90             <td><MomentTime data={i.data} /></td>
91             <td><Link to={`/u/${i.data.mod_user_name}`}>{i.data.mod_user_name}</Link></td>
92             <td>
93               {i.type_ == 'removed_posts' &&
94                 <>
95                   {(i.data as ModRemovePost).removed? 'Removed' : 'Restored'}
96                   <span> Post <Link to={`/post/${(i.data as ModRemovePost).post_id}`}>{(i.data as ModRemovePost).post_name}</Link></span>
97                   <div>{(i.data as ModRemovePost).reason && ` reason: ${(i.data as ModRemovePost).reason}`}</div>
98                 </>
99               }
100               {i.type_ == 'locked_posts' &&
101                 <>
102                   {(i.data as ModLockPost).locked? 'Locked' : 'Unlocked'}
103                   <span> Post <Link to={`/post/${(i.data as ModLockPost).post_id}`}>{(i.data as ModLockPost).post_name}</Link></span>
104                 </>
105               }
106               {i.type_ == 'stickied_posts' &&
107                 <>
108                   {(i.data as ModStickyPost).stickied? 'Stickied' : 'Unstickied'}
109                   <span> Post <Link to={`/post/${(i.data as ModStickyPost).post_id}`}>{(i.data as ModStickyPost).post_name}</Link></span>
110                 </>
111               }
112               {i.type_ == 'removed_comments' &&
113                 <>
114                   {(i.data as ModRemoveComment).removed? 'Removed' : 'Restored'}
115                   <span> Comment <Link to={`/post/${(i.data as ModRemoveComment).post_id}/comment/${(i.data as ModRemoveComment).comment_id}`}>{(i.data as ModRemoveComment).comment_content}</Link></span>
116                   <span> by <Link to={`/u/${(i.data as ModRemoveComment).comment_user_name}`}>{(i.data as ModRemoveComment).comment_user_name}</Link></span>
117                   <div>{(i.data as ModRemoveComment).reason && ` reason: ${(i.data as ModRemoveComment).reason}`}</div>
118                 </>
119               }
120               {i.type_ == 'removed_communities' &&
121                 <>
122                   {(i.data as ModRemoveCommunity).removed ? 'Removed' : 'Restored'}
123                   <span> Community <Link to={`/c/${(i.data as ModRemoveCommunity).community_name}`}>{(i.data as ModRemoveCommunity).community_name}</Link></span>
124                   <div>{(i.data as ModRemoveCommunity).reason && ` reason: ${(i.data as ModRemoveCommunity).reason}`}</div>
125                   <div>{(i.data as ModRemoveCommunity).expires && ` expires: ${moment.utc((i.data as ModRemoveCommunity).expires).fromNow()}`}</div>
126                 </>
127               }
128               {i.type_ == 'banned_from_community' &&
129                 <>
130                   <span>{(i.data as ModBanFromCommunity).banned ? 'Banned ' : 'Unbanned '} </span>
131                   <span><Link to={`/u/${(i.data as ModBanFromCommunity).other_user_name}`}>{(i.data as ModBanFromCommunity).other_user_name}</Link></span>
132                   <span> from the community </span>
133                   <span><Link to={`/c/${(i.data as ModBanFromCommunity).community_name}`}>{(i.data as ModBanFromCommunity).community_name}</Link></span>
134                   <div>{(i.data as ModBanFromCommunity).reason && ` reason: ${(i.data as ModBanFromCommunity).reason}`}</div>
135                   <div>{(i.data as ModBanFromCommunity).expires && ` expires: ${moment.utc((i.data as ModBanFromCommunity).expires).fromNow()}`}</div>
136                 </>
137               }
138               {i.type_ == 'added_to_community' &&
139                 <>
140                   <span>{(i.data as ModAddCommunity).removed ? 'Removed ' : 'Appointed '} </span>
141                   <span><Link to={`/u/${(i.data as ModAddCommunity).other_user_name}`}>{(i.data as ModAddCommunity).other_user_name}</Link></span>
142                   <span> as a mod to the community </span>
143                   <span><Link to={`/c/${(i.data as ModAddCommunity).community_name}`}>{(i.data as ModAddCommunity).community_name}</Link></span>
144                 </>
145               }
146               {i.type_ == 'banned' &&
147                 <>
148                   <span>{(i.data as ModBan).banned ? 'Banned ' : 'Unbanned '} </span>
149                   <span><Link to={`/u/${(i.data as ModBan).other_user_name}`}>{(i.data as ModBan).other_user_name}</Link></span>
150                   <div>{(i.data as ModBan).reason && ` reason: ${(i.data as ModBan).reason}`}</div>
151                   <div>{(i.data as ModBan).expires && ` expires: ${moment.utc((i.data as ModBan).expires).fromNow()}`}</div>
152                 </>
153               }
154               {i.type_ == 'added' &&
155                 <>
156                   <span>{(i.data as ModAdd).removed ? 'Removed ' : 'Appointed '} </span>
157                   <span><Link to={`/u/${(i.data as ModAdd).other_user_name}`}>{(i.data as ModAdd).other_user_name}</Link></span>
158                   <span> as an admin </span>
159                 </>
160               }
161             </td>
162           </tr>
163                                 )
164         }
165
166       </tbody>
167     );
168
169   }
170
171   render() {
172     return (
173       <div class="container">
174         {this.state.loading ?
175         <h5 class=""><svg class="icon icon-spinner spin"><use xlinkHref="#icon-spinner"></use></svg></h5> :
176         <div>
177           <h5>
178             {this.state.communityName && <Link className="text-white" to={`/c/${this.state.communityName}`}>/c/{this.state.communityName} </Link>}
179             <span>Modlog</span>
180           </h5>
181           <div class="table-responsive">
182             <table id="modlog_table" class="table table-sm table-hover">
183               <thead class="pointer">
184                 <tr>
185                   <th>Time</th>
186                   <th>Mod</th>
187                   <th>Action</th>
188                 </tr>
189               </thead>
190               {this.combined()}
191             </table>
192             {this.paginator()}
193           </div>
194         </div>
195         }
196       </div>
197     );
198   }
199
200   paginator() {
201     return (
202       <div class="mt-2">
203         {this.state.page > 1 &&
204           <button class="btn btn-sm btn-secondary mr-1" onClick={linkEvent(this, this.prevPage)}><T i18nKey="prev">#</T></button>
205         }
206         <button class="btn btn-sm btn-secondary" onClick={linkEvent(this, this.nextPage)}><T i18nKey="next">#</T></button>
207       </div>
208     );
209   }
210
211   nextPage(i: Modlog) {
212     i.state.page++;
213     i.setState(i.state);
214     i.refetch();
215   }
216
217   prevPage(i: Modlog) {
218     i.state.page--;
219     i.setState(i.state);
220     i.refetch();
221   }
222
223   refetch(){
224     let modlogForm: GetModlogForm = {
225       community_id: this.state.communityId,
226       page: this.state.page,
227       limit: fetchLimit,
228     };
229     WebSocketService.Instance.getModlog(modlogForm);
230   }
231
232   parseMessage(msg: any) {
233     console.log(msg);
234     let op: UserOperation = msgOp(msg);
235     if (msg.error) {
236       alert(i18n.t(msg.error));
237       return;
238     } else if (op == UserOperation.GetModlog) {
239       let res: GetModlogResponse = msg;
240       this.state.loading = false;
241       window.scrollTo(0,0);
242       this.setCombined(res);
243     }
244   }
245 }