import { Component, linkEvent } from 'inferno'; import { Link } from 'inferno-router'; import { Subscription } from 'rxjs'; import { UserOperation, GetModlog, GetModlogResponse, SiteView, ModRemovePostView, ModLockPostView, ModStickyPostView, ModRemoveCommentView, ModRemoveCommunityView, ModBanFromCommunityView, ModBanView, ModAddCommunityView, ModAddView, } from 'lemmy-js-client'; import { WebSocketService } from '../services'; import { wsJsonToRes, fetchLimit, toast, setIsoData, wsSubscribe, isBrowser, wsUserOp, wsClient, } from '../utils'; import { MomentTime } from './moment-time'; import { HtmlTags } from './html-tags'; import moment from 'moment'; import { i18n } from '../i18next'; import { InitialFetchRequest } from 'shared/interfaces'; import { UserListing } from './user-listing'; import { CommunityLink } from './community-link'; import { Spinner } from './icon'; enum ModlogEnum { ModRemovePost, ModLockPost, ModStickyPost, ModRemoveComment, ModRemoveCommunity, ModBanFromCommunity, ModAddCommunity, ModAdd, ModBan, } type ModlogType = { id: number; type_: ModlogEnum; view: | ModRemovePostView | ModLockPostView | ModStickyPostView | ModRemoveCommentView | ModRemoveCommunityView | ModBanFromCommunityView | ModBanView | ModAddCommunityView | ModAddView; when_: string; }; interface ModlogState { res: GetModlogResponse; communityId?: number; communityName?: string; page: number; site_view: SiteView; loading: boolean; } export class Modlog extends Component { private isoData = setIsoData(this.context); private subscription: Subscription; private emptyState: ModlogState = { res: { removed_posts: [], locked_posts: [], stickied_posts: [], removed_comments: [], removed_communities: [], banned_from_community: [], banned: [], added_to_community: [], added: [], }, page: 1, loading: true, site_view: this.isoData.site_res.site_view, }; constructor(props: any, context: any) { super(props, context); this.state = this.emptyState; this.state.communityId = this.props.match.params.community_id ? Number(this.props.match.params.community_id) : undefined; this.parseMessage = this.parseMessage.bind(this); this.subscription = wsSubscribe(this.parseMessage); // Only fetch the data if coming from another route if (this.isoData.path == this.context.router.route.match.url) { let data = this.isoData.routeData[0]; this.state.res = data; this.state.loading = false; } else { this.refetch(); } } componentWillUnmount() { if (isBrowser()) { this.subscription.unsubscribe(); } } buildCombined(res: GetModlogResponse): ModlogType[] { let removed_posts: ModlogType[] = res.removed_posts.map(r => ({ id: r.mod_remove_post.id, type_: ModlogEnum.ModRemovePost, view: r, when_: r.mod_remove_post.when_, })); let locked_posts: ModlogType[] = res.locked_posts.map(r => ({ id: r.mod_lock_post.id, type_: ModlogEnum.ModLockPost, view: r, when_: r.mod_lock_post.when_, })); let stickied_posts: ModlogType[] = res.stickied_posts.map(r => ({ id: r.mod_sticky_post.id, type_: ModlogEnum.ModStickyPost, view: r, when_: r.mod_sticky_post.when_, })); let removed_comments: ModlogType[] = res.removed_comments.map(r => ({ id: r.mod_remove_comment.id, type_: ModlogEnum.ModRemoveComment, view: r, when_: r.mod_remove_comment.when_, })); let removed_communities: ModlogType[] = res.removed_communities.map(r => ({ id: r.mod_remove_community.id, type_: ModlogEnum.ModRemoveCommunity, view: r, when_: r.mod_remove_community.when_, })); let banned_from_community: ModlogType[] = res.banned_from_community.map( r => ({ id: r.mod_ban_from_community.id, type_: ModlogEnum.ModBanFromCommunity, view: r, when_: r.mod_ban_from_community.when_, }) ); let added_to_community: ModlogType[] = res.added_to_community.map(r => ({ id: r.mod_add_community.id, type_: ModlogEnum.ModAddCommunity, view: r, when_: r.mod_add_community.when_, })); let added: ModlogType[] = res.added.map(r => ({ id: r.mod_add.id, type_: ModlogEnum.ModAdd, view: r, when_: r.mod_add.when_, })); let banned: ModlogType[] = res.banned.map(r => ({ id: r.mod_ban.id, type_: ModlogEnum.ModBan, view: r, when_: r.mod_ban.when_, })); let combined: ModlogType[] = []; combined.push(...removed_posts); combined.push(...locked_posts); combined.push(...stickied_posts); combined.push(...removed_comments); combined.push(...removed_communities); combined.push(...banned_from_community); combined.push(...added_to_community); combined.push(...added); combined.push(...banned); if (this.state.communityId && combined.length > 0) { this.state.communityName = (combined[0] .view as ModRemovePostView).community.name; } // Sort them by time combined.sort((a, b) => b.when_.localeCompare(a.when_)); return combined; } renderModlogType(i: ModlogType) { switch (i.type_) { case ModlogEnum.ModRemovePost: { let mrpv = i.view as ModRemovePostView; return [ mrpv.mod_remove_post.removed ? 'Removed ' : 'Restored ', Post {mrpv.post.name} , mrpv.mod_remove_post.reason && ` reason: ${mrpv.mod_remove_post.reason}`, ]; } case ModlogEnum.ModLockPost: { let mlpv = i.view as ModLockPostView; return [ mlpv.mod_lock_post.locked ? 'Locked ' : 'Unlocked ', Post {mlpv.post.name} , ]; } case ModlogEnum.ModStickyPost: { let mspv = i.view as ModStickyPostView; return [ mspv.mod_sticky_post.stickied ? 'Stickied ' : 'Unstickied ', Post {mspv.post.name} , ]; } case ModlogEnum.ModRemoveComment: { let mrc = i.view as ModRemoveCommentView; return [ mrc.mod_remove_comment.removed ? 'Removed ' : 'Restored ', Comment{' '} {mrc.comment.content} , {' '} by , mrc.mod_remove_comment.reason && ` reason: ${mrc.mod_remove_comment.reason}`, ]; } case ModlogEnum.ModRemoveCommunity: { let mrco = i.view as ModRemoveCommunityView; return [ mrco.mod_remove_community.removed ? 'Removed ' : 'Restored ', Community , mrco.mod_remove_community.reason && ` reason: ${mrco.mod_remove_community.reason}`, mrco.mod_remove_community.expires && ` expires: ${moment .utc(mrco.mod_remove_community.expires) .fromNow()}`, ]; } case ModlogEnum.ModBanFromCommunity: { let mbfc = i.view as ModBanFromCommunityView; return [ {mbfc.mod_ban_from_community.banned ? 'Banned ' : 'Unbanned '}{' '} , , from the community , ,
{mbfc.mod_ban_from_community.reason && ` reason: ${mbfc.mod_ban_from_community.reason}`}
,
{mbfc.mod_ban_from_community.expires && ` expires: ${moment .utc(mbfc.mod_ban_from_community.expires) .fromNow()}`}
, ]; } case ModlogEnum.ModAddCommunity: { let mac = i.view as ModAddCommunityView; return [ {mac.mod_add_community.removed ? 'Removed ' : 'Appointed '}{' '} , , as a mod to the community , , ]; } case ModlogEnum.ModBan: { let mb = i.view as ModBanView; return [ {mb.mod_ban.banned ? 'Banned ' : 'Unbanned '} , ,
{mb.mod_ban.reason && ` reason: ${mb.mod_ban.reason}`}
,
{mb.mod_ban.expires && ` expires: ${moment.utc(mb.mod_ban.expires).fromNow()}`}
, ]; } case ModlogEnum.ModAdd: { let ma = i.view as ModAddView; return [ {ma.mod_add.removed ? 'Removed ' : 'Appointed '} , , as an admin , ]; } default: return
; } } combined() { let combined = this.buildCombined(this.state.res); return ( {combined.map(i => ( {this.renderModlogType(i)} ))} ); } get documentTitle(): string { return `Modlog - ${this.state.site_view.site.name}`; } render() { return (
{this.state.loading ? (
) : (
{this.state.communityName && ( /c/{this.state.communityName}{' '} )} {i18n.t('modlog')}
{this.combined()}
{i18n.t('time')} {i18n.t('mod')} {i18n.t('action')}
{this.paginator()}
)}
); } paginator() { return (
{this.state.page > 1 && ( )}
); } nextPage(i: Modlog) { i.state.page++; i.setState(i.state); i.refetch(); } prevPage(i: Modlog) { i.state.page--; i.setState(i.state); i.refetch(); } refetch() { let modlogForm: GetModlog = { community_id: this.state.communityId, page: this.state.page, limit: fetchLimit, }; WebSocketService.Instance.send(wsClient.getModlog(modlogForm)); } static fetchInitialData(req: InitialFetchRequest): Promise[] { let pathSplit = req.path.split('/'); let communityId = pathSplit[3]; let promises: Promise[] = []; let modlogForm: GetModlog = { page: 1, limit: fetchLimit, }; if (communityId) { modlogForm.community_id = Number(communityId); } promises.push(req.client.getModlog(modlogForm)); return promises; } parseMessage(msg: any) { let op = wsUserOp(msg); if (msg.error) { toast(i18n.t(msg.error), 'danger'); return; } else if (op == UserOperation.GetModlog) { let data = wsJsonToRes(msg).data; this.state.loading = false; window.scrollTo(0, 0); this.state.res = data; this.setState(this.state); } } }