1 import { Component, linkEvent } from 'inferno';
2 import { Link } from 'inferno-router';
3 import { Subscription } from 'rxjs';
13 ModRemoveCommunityView,
14 ModBanFromCommunityView,
18 } from 'lemmy-js-client';
19 import { WebSocketService } from '../services';
30 import { MomentTime } from './moment-time';
31 import { HtmlTags } from './html-tags';
32 import moment from 'moment';
33 import { i18n } from '../i18next';
34 import { InitialFetchRequest } from 'shared/interfaces';
35 import { UserListing } from './user-listing';
36 import { CommunityLink } from './community-link';
37 import { Spinner } from './icon';
58 | ModRemoveCommentView
59 | ModRemoveCommunityView
60 | ModBanFromCommunityView
67 interface ModlogState {
68 res: GetModlogResponse;
70 communityName?: string;
76 export class Modlog extends Component<any, ModlogState> {
77 private isoData = setIsoData(this.context);
78 private subscription: Subscription;
79 private emptyState: ModlogState = {
85 removed_communities: [],
86 banned_from_community: [],
88 added_to_community: [],
93 site_view: this.isoData.site_res.site_view,
96 constructor(props: any, context: any) {
97 super(props, context);
99 this.state = this.emptyState;
100 this.state.communityId = this.props.match.params.community_id
101 ? Number(this.props.match.params.community_id)
104 this.parseMessage = this.parseMessage.bind(this);
105 this.subscription = wsSubscribe(this.parseMessage);
107 // Only fetch the data if coming from another route
108 if (this.isoData.path == this.context.router.route.match.url) {
109 let data = this.isoData.routeData[0];
110 this.state.res = data;
111 this.state.loading = false;
117 componentWillUnmount() {
119 this.subscription.unsubscribe();
123 buildCombined(res: GetModlogResponse): ModlogType[] {
124 let removed_posts: ModlogType[] = res.removed_posts.map(r => ({
125 id: r.mod_remove_post.id,
126 type_: ModlogEnum.ModRemovePost,
128 when_: r.mod_remove_post.when_,
131 let locked_posts: ModlogType[] = res.locked_posts.map(r => ({
132 id: r.mod_lock_post.id,
133 type_: ModlogEnum.ModLockPost,
135 when_: r.mod_lock_post.when_,
138 let stickied_posts: ModlogType[] = res.stickied_posts.map(r => ({
139 id: r.mod_sticky_post.id,
140 type_: ModlogEnum.ModStickyPost,
142 when_: r.mod_sticky_post.when_,
145 let removed_comments: ModlogType[] = res.removed_comments.map(r => ({
146 id: r.mod_remove_comment.id,
147 type_: ModlogEnum.ModRemoveComment,
149 when_: r.mod_remove_comment.when_,
152 let removed_communities: ModlogType[] = res.removed_communities.map(r => ({
153 id: r.mod_remove_community.id,
154 type_: ModlogEnum.ModRemoveCommunity,
156 when_: r.mod_remove_community.when_,
159 let banned_from_community: ModlogType[] = res.banned_from_community.map(
161 id: r.mod_ban_from_community.id,
162 type_: ModlogEnum.ModBanFromCommunity,
164 when_: r.mod_ban_from_community.when_,
168 let added_to_community: ModlogType[] = res.added_to_community.map(r => ({
169 id: r.mod_add_community.id,
170 type_: ModlogEnum.ModAddCommunity,
172 when_: r.mod_add_community.when_,
175 let added: ModlogType[] = res.added.map(r => ({
177 type_: ModlogEnum.ModAdd,
179 when_: r.mod_add.when_,
182 let banned: ModlogType[] = res.banned.map(r => ({
184 type_: ModlogEnum.ModBan,
186 when_: r.mod_ban.when_,
189 let combined: ModlogType[] = [];
191 combined.push(...removed_posts);
192 combined.push(...locked_posts);
193 combined.push(...stickied_posts);
194 combined.push(...removed_comments);
195 combined.push(...removed_communities);
196 combined.push(...banned_from_community);
197 combined.push(...added_to_community);
198 combined.push(...added);
199 combined.push(...banned);
201 if (this.state.communityId && combined.length > 0) {
202 this.state.communityName = (combined[0]
203 .view as ModRemovePostView).community.name;
207 combined.sort((a, b) => b.when_.localeCompare(a.when_));
212 renderModlogType(i: ModlogType) {
214 case ModlogEnum.ModRemovePost: {
215 let mrpv = i.view as ModRemovePostView;
217 mrpv.mod_remove_post.removed ? 'Removed ' : 'Restored ',
219 Post <Link to={`/post/${mrpv.post.id}`}>{mrpv.post.name}</Link>
221 mrpv.mod_remove_post.reason &&
222 ` reason: ${mrpv.mod_remove_post.reason}`,
225 case ModlogEnum.ModLockPost: {
226 let mlpv = i.view as ModLockPostView;
228 mlpv.mod_lock_post.locked ? 'Locked ' : 'Unlocked ',
230 Post <Link to={`/post/${mlpv.post.id}`}>{mlpv.post.name}</Link>
234 case ModlogEnum.ModStickyPost: {
235 let mspv = i.view as ModStickyPostView;
237 mspv.mod_sticky_post.stickied ? 'Stickied ' : 'Unstickied ',
239 Post <Link to={`/post/${mspv.post.id}`}>{mspv.post.name}</Link>
243 case ModlogEnum.ModRemoveComment: {
244 let mrc = i.view as ModRemoveCommentView;
246 mrc.mod_remove_comment.removed ? 'Removed ' : 'Restored ',
249 <Link to={`/post/${mrc.post.id}/comment/${mrc.comment.id}`}>
250 {mrc.comment.content}
255 by <UserListing user={mrc.commenter} />
257 mrc.mod_remove_comment.reason &&
258 ` reason: ${mrc.mod_remove_comment.reason}`,
261 case ModlogEnum.ModRemoveCommunity: {
262 let mrco = i.view as ModRemoveCommunityView;
264 mrco.mod_remove_community.removed ? 'Removed ' : 'Restored ',
266 Community <CommunityLink community={mrco.community} />
268 mrco.mod_remove_community.reason &&
269 ` reason: ${mrco.mod_remove_community.reason}`,
270 mrco.mod_remove_community.expires &&
272 .utc(mrco.mod_remove_community.expires)
276 case ModlogEnum.ModBanFromCommunity: {
277 let mbfc = i.view as ModBanFromCommunityView;
280 {mbfc.mod_ban_from_community.banned ? 'Banned ' : 'Unbanned '}{' '}
283 <UserListing user={mbfc.banned_user} />
285 <span> from the community </span>,
287 <CommunityLink community={mbfc.community} />
290 {mbfc.mod_ban_from_community.reason &&
291 ` reason: ${mbfc.mod_ban_from_community.reason}`}
294 {mbfc.mod_ban_from_community.expires &&
296 .utc(mbfc.mod_ban_from_community.expires)
301 case ModlogEnum.ModAddCommunity: {
302 let mac = i.view as ModAddCommunityView;
305 {mac.mod_add_community.removed ? 'Removed ' : 'Appointed '}{' '}
308 <UserListing user={mac.modded_user} />
310 <span> as a mod to the community </span>,
312 <CommunityLink community={mac.community} />
316 case ModlogEnum.ModBan: {
317 let mb = i.view as ModBanView;
319 <span>{mb.mod_ban.banned ? 'Banned ' : 'Unbanned '} </span>,
321 <UserListing user={mb.banned_user} />
323 <div>{mb.mod_ban.reason && ` reason: ${mb.mod_ban.reason}`}</div>,
325 {mb.mod_ban.expires &&
326 ` expires: ${moment.utc(mb.mod_ban.expires).fromNow()}`}
330 case ModlogEnum.ModAdd: {
331 let ma = i.view as ModAddView;
333 <span>{ma.mod_add.removed ? 'Removed ' : 'Appointed '} </span>,
335 <UserListing user={ma.modded_user} />
337 <span> as an admin </span>,
346 let combined = this.buildCombined(this.state.res);
353 <MomentTime data={i} />
356 <UserListing user={i.view.moderator} />
358 <td>{this.renderModlogType(i)}</td>
365 get documentTitle(): string {
366 return `Modlog - ${this.state.site_view.site.name}`;
371 <div class="container">
373 title={this.documentTitle}
374 path={this.context.router.route.match.url}
376 {this.state.loading ? (
383 {this.state.communityName && (
385 className="text-body"
386 to={`/c/${this.state.communityName}`}
388 /c/{this.state.communityName}{' '}
391 <span>{i18n.t('modlog')}</span>
393 <div class="table-responsive">
394 <table id="modlog_table" class="table table-sm table-hover">
395 <thead class="pointer">
397 <th> {i18n.t('time')}</th>
398 <th>{i18n.t('mod')}</th>
399 <th>{i18n.t('action')}</th>
415 {this.state.page > 1 && (
417 class="btn btn-secondary mr-1"
418 onClick={linkEvent(this, this.prevPage)}
424 class="btn btn-secondary"
425 onClick={linkEvent(this, this.nextPage)}
433 nextPage(i: Modlog) {
439 prevPage(i: Modlog) {
446 let modlogForm: GetModlog = {
447 community_id: this.state.communityId,
448 page: this.state.page,
451 WebSocketService.Instance.send(wsClient.getModlog(modlogForm));
454 static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
455 let pathSplit = req.path.split('/');
456 let communityId = pathSplit[3];
457 let promises: Promise<any>[] = [];
459 let modlogForm: GetModlog = {
465 modlogForm.community_id = Number(communityId);
468 promises.push(req.client.getModlog(modlogForm));
472 parseMessage(msg: any) {
473 let op = wsUserOp(msg);
475 toast(i18n.t(msg.error), 'danger');
477 } else if (op == UserOperation.GetModlog) {
478 let data = wsJsonToRes<GetModlogResponse>(msg).data;
479 this.state.loading = false;
480 window.scrollTo(0, 0);
481 this.state.res = data;
482 this.setState(this.state);