1 import { Component, linkEvent } from 'inferno';
2 import { Link } from 'inferno-router';
3 import { Subscription } from 'rxjs';
17 WebSocketJsonResponse,
19 } from 'lemmy-js-client';
20 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';
36 interface ModlogState {
48 communityName?: string;
54 export class Modlog extends Component<any, ModlogState> {
55 private isoData = setIsoData(this.context);
56 private subscription: Subscription;
57 private emptyState: ModlogState = {
61 site: this.isoData.site.site,
64 constructor(props: any, context: any) {
65 super(props, context);
67 this.state = this.emptyState;
68 this.state.communityId = this.props.match.params.community_id
69 ? Number(this.props.match.params.community_id)
72 this.parseMessage = this.parseMessage.bind(this);
73 this.subscription = wsSubscribe(this.parseMessage);
75 // Only fetch the data if coming from another route
76 if (this.isoData.path == this.context.router.route.match.url) {
77 let data = this.isoData.routeData[0];
78 this.setCombined(data);
79 this.state.loading = false;
85 componentWillUnmount() {
87 this.subscription.unsubscribe();
91 setCombined(res: GetModlogResponse) {
92 let removed_posts = addTypeInfo(res.removed_posts, 'removed_posts');
93 let locked_posts = addTypeInfo(res.locked_posts, 'locked_posts');
94 let stickied_posts = addTypeInfo(res.stickied_posts, 'stickied_posts');
95 let removed_comments = addTypeInfo(
99 let removed_communities = addTypeInfo(
100 res.removed_communities,
101 'removed_communities'
103 let banned_from_community = addTypeInfo(
104 res.banned_from_community,
105 'banned_from_community'
107 let added_to_community = addTypeInfo(
108 res.added_to_community,
111 let added = addTypeInfo(res.added, 'added');
112 let banned = addTypeInfo(res.banned, 'banned');
113 this.state.combined = [];
115 this.state.combined.push(...removed_posts);
116 this.state.combined.push(...locked_posts);
117 this.state.combined.push(...stickied_posts);
118 this.state.combined.push(...removed_comments);
119 this.state.combined.push(...removed_communities);
120 this.state.combined.push(...banned_from_community);
121 this.state.combined.push(...added_to_community);
122 this.state.combined.push(...added);
123 this.state.combined.push(...banned);
125 if (this.state.communityId && this.state.combined.length > 0) {
126 this.state.communityName = (this.state.combined[0]
127 .data as ModRemovePost).community_name;
131 this.state.combined.sort((a, b) =>
132 b.data.when_.localeCompare(a.data.when_)
139 {this.state.combined.map(i => (
142 <MomentTime data={i.data} />
145 <Link to={`/u/${i.data.mod_user_name}`}>
146 {i.data.mod_user_name}
150 {i.type_ == 'removed_posts' && (
152 {(i.data as ModRemovePost).removed ? 'Removed' : 'Restored'}
156 <Link to={`/post/${(i.data as ModRemovePost).post_id}`}>
157 {(i.data as ModRemovePost).post_name}
161 {(i.data as ModRemovePost).reason &&
162 ` reason: ${(i.data as ModRemovePost).reason}`}
166 {i.type_ == 'locked_posts' && (
168 {(i.data as ModLockPost).locked ? 'Locked' : 'Unlocked'}
172 <Link to={`/post/${(i.data as ModLockPost).post_id}`}>
173 {(i.data as ModLockPost).post_name}
178 {i.type_ == 'stickied_posts' && (
180 {(i.data as ModStickyPost).stickied
186 <Link to={`/post/${(i.data as ModStickyPost).post_id}`}>
187 {(i.data as ModStickyPost).post_name}
192 {i.type_ == 'removed_comments' && (
194 {(i.data as ModRemoveComment).removed
202 (i.data as ModRemoveComment).post_id
203 }/comment/${(i.data as ModRemoveComment).comment_id}`}
205 {(i.data as ModRemoveComment).comment_content}
213 (i.data as ModRemoveComment).comment_user_name
216 {(i.data as ModRemoveComment).comment_user_name}
220 {(i.data as ModRemoveComment).reason &&
221 ` reason: ${(i.data as ModRemoveComment).reason}`}
225 {i.type_ == 'removed_communities' && (
227 {(i.data as ModRemoveCommunity).removed
234 to={`/c/${(i.data as ModRemoveCommunity).community_name}`}
236 {(i.data as ModRemoveCommunity).community_name}
240 {(i.data as ModRemoveCommunity).reason &&
241 ` reason: ${(i.data as ModRemoveCommunity).reason}`}
244 {(i.data as ModRemoveCommunity).expires &&
246 .utc((i.data as ModRemoveCommunity).expires)
251 {i.type_ == 'banned_from_community' && (
254 {(i.data as ModBanFromCommunity).banned
261 (i.data as ModBanFromCommunity).other_user_name
264 {(i.data as ModBanFromCommunity).other_user_name}
267 <span> from the community </span>
271 (i.data as ModBanFromCommunity).community_name
274 {(i.data as ModBanFromCommunity).community_name}
278 {(i.data as ModBanFromCommunity).reason &&
279 ` reason: ${(i.data as ModBanFromCommunity).reason}`}
282 {(i.data as ModBanFromCommunity).expires &&
284 .utc((i.data as ModBanFromCommunity).expires)
289 {i.type_ == 'added_to_community' && (
292 {(i.data as ModAddCommunity).removed
298 to={`/u/${(i.data as ModAddCommunity).other_user_name}`}
300 {(i.data as ModAddCommunity).other_user_name}
303 <span> as a mod to the community </span>
306 to={`/c/${(i.data as ModAddCommunity).community_name}`}
308 {(i.data as ModAddCommunity).community_name}
313 {i.type_ == 'banned' && (
316 {(i.data as ModBan).banned ? 'Banned ' : 'Unbanned '}{' '}
319 <Link to={`/u/${(i.data as ModBan).other_user_name}`}>
320 {(i.data as ModBan).other_user_name}
324 {(i.data as ModBan).reason &&
325 ` reason: ${(i.data as ModBan).reason}`}
328 {(i.data as ModBan).expires &&
330 .utc((i.data as ModBan).expires)
335 {i.type_ == 'added' && (
338 {(i.data as ModAdd).removed ? 'Removed ' : 'Appointed '}{' '}
341 <Link to={`/u/${(i.data as ModAdd).other_user_name}`}>
342 {(i.data as ModAdd).other_user_name}
345 <span> as an admin </span>
355 get documentTitle(): string {
356 return `Modlog - ${this.state.site.name}`;
361 <div class="container">
363 title={this.documentTitle}
364 path={this.context.router.route.match.url}
366 {this.state.loading ? (
368 <svg class="icon icon-spinner spin">
369 <use xlinkHref="#icon-spinner"></use>
375 {this.state.communityName && (
377 className="text-body"
378 to={`/c/${this.state.communityName}`}
380 /c/{this.state.communityName}{' '}
383 <span>{i18n.t('modlog')}</span>
385 <div class="table-responsive">
386 <table id="modlog_table" class="table table-sm table-hover">
387 <thead class="pointer">
389 <th> {i18n.t('time')}</th>
390 <th>{i18n.t('mod')}</th>
391 <th>{i18n.t('action')}</th>
407 {this.state.page > 1 && (
409 class="btn btn-secondary mr-1"
410 onClick={linkEvent(this, this.prevPage)}
416 class="btn btn-secondary"
417 onClick={linkEvent(this, this.nextPage)}
425 nextPage(i: Modlog) {
431 prevPage(i: Modlog) {
438 let modlogForm: GetModlogForm = {
439 community_id: this.state.communityId,
440 page: this.state.page,
443 WebSocketService.Instance.getModlog(modlogForm);
446 static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
447 let pathSplit = req.path.split('/');
448 let communityId = pathSplit[3];
449 let promises: Promise<any>[] = [];
451 let modlogForm: GetModlogForm = {
457 modlogForm.community_id = Number(communityId);
460 promises.push(req.client.getModlog(modlogForm));
464 parseMessage(msg: WebSocketJsonResponse) {
466 let res = wsJsonToRes(msg);
468 toast(i18n.t(msg.error), 'danger');
470 } else if (res.op == UserOperation.GetModlog) {
471 let data = res.data as GetModlogResponse;
472 this.state.loading = false;
473 window.scrollTo(0, 0);
474 this.setCombined(data);
475 this.setState(this.state);