import { None, Option, Some } from "@sniptt/monads"; import { Component, linkEvent } from "inferno"; import { CommentReportResponse, CommentReportView, GetSiteResponse, ListCommentReports, ListCommentReportsResponse, ListPostReports, ListPostReportsResponse, ListPrivateMessageReports, ListPrivateMessageReportsResponse, PostReportResponse, PostReportView, PrivateMessageReportResponse, PrivateMessageReportView, UserOperation, wsJsonToRes, wsUserOp, } from "lemmy-js-client"; import { Subscription } from "rxjs"; import { i18n } from "../../i18next"; import { InitialFetchRequest } from "../../interfaces"; import { UserService, WebSocketService } from "../../services"; import { amAdmin, auth, fetchLimit, isBrowser, setIsoData, setupTippy, toast, updateCommentReportRes, updatePostReportRes, updatePrivateMessageReportRes, wsClient, wsSubscribe, } from "../../utils"; import { CommentReport } from "../comment/comment-report"; import { HtmlTags } from "../common/html-tags"; import { Spinner } from "../common/icon"; import { Paginator } from "../common/paginator"; import { PostReport } from "../post/post-report"; import { PrivateMessageReport } from "../private_message/private-message-report"; enum UnreadOrAll { Unread, All, } enum MessageType { All, CommentReport, PostReport, PrivateMessageReport, } enum MessageEnum { CommentReport, PostReport, PrivateMessageReport, } type ItemType = { id: number; type_: MessageEnum; view: CommentReportView | PostReportView | PrivateMessageReportView; published: string; }; interface ReportsState { listCommentReportsResponse: Option; listPostReportsResponse: Option; listPrivateMessageReportsResponse: Option; unreadOrAll: UnreadOrAll; messageType: MessageType; combined: ItemType[]; siteRes: GetSiteResponse; page: number; loading: boolean; } export class Reports extends Component { private isoData = setIsoData( this.context, ListCommentReportsResponse, ListPostReportsResponse, ListPrivateMessageReportsResponse ); private subscription: Subscription; private emptyState: ReportsState = { listCommentReportsResponse: None, listPostReportsResponse: None, listPrivateMessageReportsResponse: None, unreadOrAll: UnreadOrAll.Unread, messageType: MessageType.All, combined: [], page: 1, siteRes: this.isoData.site_res, loading: true, }; constructor(props: any, context: any) { super(props, context); this.state = this.emptyState; this.handlePageChange = this.handlePageChange.bind(this); if (UserService.Instance.myUserInfo.isNone() && isBrowser()) { toast(i18n.t("not_logged_in"), "danger"); this.context.router.history.push(`/login`); } 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) { this.state = { ...this.state, listCommentReportsResponse: Some( this.isoData.routeData[0] as ListCommentReportsResponse ), listPostReportsResponse: Some( this.isoData.routeData[1] as ListPostReportsResponse ), }; if (amAdmin()) { this.state = { ...this.state, listPrivateMessageReportsResponse: Some( this.isoData.routeData[2] as ListPrivateMessageReportsResponse ), }; } this.state = { ...this.state, combined: this.buildCombined(), loading: false, }; } else { this.refetch(); } } componentWillUnmount() { if (isBrowser()) { this.subscription.unsubscribe(); } } get documentTitle(): string { return this.state.siteRes.site_view.match({ some: siteView => UserService.Instance.myUserInfo.match({ some: mui => `@${mui.local_user_view.person.name} ${i18n.t("reports")} - ${ siteView.site.name }`, none: "", }), none: "", }); } render() { return (
{this.state.loading ? (
) : (
{i18n.t("reports")}
{this.selects()} {this.state.messageType == MessageType.All && this.all()} {this.state.messageType == MessageType.CommentReport && this.commentReports()} {this.state.messageType == MessageType.PostReport && this.postReports()} {this.state.messageType == MessageType.PrivateMessageReport && this.privateMessageReports()}
)}
); } unreadOrAllRadios() { return (
); } messageTypeRadios() { return (
{amAdmin() && ( )}
); } selects() { return (
{this.unreadOrAllRadios()} {this.messageTypeRadios()}
); } commentReportToItemType(r: CommentReportView): ItemType { return { id: r.comment_report.id, type_: MessageEnum.CommentReport, view: r, published: r.comment_report.published, }; } postReportToItemType(r: PostReportView): ItemType { return { id: r.post_report.id, type_: MessageEnum.PostReport, view: r, published: r.post_report.published, }; } privateMessageReportToItemType(r: PrivateMessageReportView): ItemType { return { id: r.private_message_report.id, type_: MessageEnum.PrivateMessageReport, view: r, published: r.private_message_report.published, }; } buildCombined(): ItemType[] { let comments: ItemType[] = this.state.listCommentReportsResponse .map(r => r.comment_reports) .unwrapOr([]) .map(r => this.commentReportToItemType(r)); let posts: ItemType[] = this.state.listPostReportsResponse .map(r => r.post_reports) .unwrapOr([]) .map(r => this.postReportToItemType(r)); let privateMessages: ItemType[] = this.state.listPrivateMessageReportsResponse .map(r => r.private_message_reports) .unwrapOr([]) .map(r => this.privateMessageReportToItemType(r)); return [...comments, ...posts, ...privateMessages].sort((a, b) => b.published.localeCompare(a.published) ); } renderItemType(i: ItemType) { switch (i.type_) { case MessageEnum.CommentReport: return ( ); case MessageEnum.PostReport: return ; case MessageEnum.PrivateMessageReport: return ( ); default: return
; } } all() { return (
{this.state.combined.map(i => ( <>
{this.renderItemType(i)} ))}
); } commentReports() { return this.state.listCommentReportsResponse.match({ some: res => (
{res.comment_reports.map(cr => ( <>
))}
), none: <>, }); } postReports() { return this.state.listPostReportsResponse.match({ some: res => (
{res.post_reports.map(pr => ( <>
))}
), none: <>, }); } privateMessageReports() { return this.state.listPrivateMessageReportsResponse.match({ some: res => (
{res.private_message_reports.map(pmr => ( <>
))}
), none: <>, }); } handlePageChange(page: number) { this.setState({ page }); this.refetch(); } handleUnreadOrAllChange(i: Reports, event: any) { i.setState({ unreadOrAll: Number(event.target.value), page: 1 }); i.refetch(); } handleMessageTypeChange(i: Reports, event: any) { i.setState({ messageType: Number(event.target.value), page: 1 }); i.refetch(); } static fetchInitialData(req: InitialFetchRequest): Promise[] { let promises: Promise[] = []; let unresolved_only = Some(true); let page = Some(1); let limit = Some(fetchLimit); let community_id = None; let auth = req.auth.unwrap(); let commentReportsForm = new ListCommentReports({ // TODO community_id unresolved_only, community_id, page, limit, auth, }); promises.push(req.client.listCommentReports(commentReportsForm)); let postReportsForm = new ListPostReports({ // TODO community_id unresolved_only, community_id, page, limit, auth, }); promises.push(req.client.listPostReports(postReportsForm)); if (amAdmin()) { let privateMessageReportsForm = new ListPrivateMessageReports({ unresolved_only, page, limit, auth, }); promises.push( req.client.listPrivateMessageReports(privateMessageReportsForm) ); } return promises; } refetch() { let unresolved_only = Some(this.state.unreadOrAll == UnreadOrAll.Unread); let community_id = None; let page = Some(this.state.page); let limit = Some(fetchLimit); let commentReportsForm = new ListCommentReports({ unresolved_only, // TODO community_id community_id, page, limit, auth: auth().unwrap(), }); WebSocketService.Instance.send( wsClient.listCommentReports(commentReportsForm) ); let postReportsForm = new ListPostReports({ unresolved_only, // TODO community_id community_id, page, limit, auth: auth().unwrap(), }); WebSocketService.Instance.send(wsClient.listPostReports(postReportsForm)); if (amAdmin()) { let privateMessageReportsForm = new ListPrivateMessageReports({ unresolved_only, page, limit, auth: auth().unwrap(), }); WebSocketService.Instance.send( wsClient.listPrivateMessageReports(privateMessageReportsForm) ); } } parseMessage(msg: any) { let op = wsUserOp(msg); console.log(msg); if (msg.error) { toast(i18n.t(msg.error), "danger"); return; } else if (msg.reconnect) { this.refetch(); } else if (op == UserOperation.ListCommentReports) { let data = wsJsonToRes( msg, ListCommentReportsResponse ); this.setState({ listCommentReportsResponse: Some(data) }); this.setState({ combined: this.buildCombined(), loading: false }); // this.sendUnreadCount(); window.scrollTo(0, 0); setupTippy(); } else if (op == UserOperation.ListPostReports) { let data = wsJsonToRes( msg, ListPostReportsResponse ); this.setState({ listPostReportsResponse: Some(data) }); this.setState({ combined: this.buildCombined(), loading: false }); // this.sendUnreadCount(); window.scrollTo(0, 0); setupTippy(); } else if (op == UserOperation.ListPrivateMessageReports) { let data = wsJsonToRes( msg, ListPrivateMessageReportsResponse ); this.setState({ listPrivateMessageReportsResponse: Some(data) }); this.setState({ combined: this.buildCombined(), loading: false }); // this.sendUnreadCount(); window.scrollTo(0, 0); setupTippy(); } else if (op == UserOperation.ResolvePostReport) { let data = wsJsonToRes(msg, PostReportResponse); updatePostReportRes( data.post_report_view, this.state.listPostReportsResponse.map(r => r.post_reports).unwrapOr([]) ); let urcs = UserService.Instance.unreadReportCountSub; if (data.post_report_view.post_report.resolved) { urcs.next(urcs.getValue() - 1); } else { urcs.next(urcs.getValue() + 1); } this.setState(this.state); } else if (op == UserOperation.ResolveCommentReport) { let data = wsJsonToRes(msg, CommentReportResponse); updateCommentReportRes( data.comment_report_view, this.state.listCommentReportsResponse .map(r => r.comment_reports) .unwrapOr([]) ); let urcs = UserService.Instance.unreadReportCountSub; if (data.comment_report_view.comment_report.resolved) { urcs.next(urcs.getValue() - 1); } else { urcs.next(urcs.getValue() + 1); } this.setState(this.state); } else if (op == UserOperation.ResolvePrivateMessageReport) { let data = wsJsonToRes( msg, PrivateMessageReportResponse ); updatePrivateMessageReportRes( data.private_message_report_view, this.state.listPrivateMessageReportsResponse .map(r => r.private_message_reports) .unwrapOr([]) ); let urcs = UserService.Instance.unreadReportCountSub; if (data.private_message_report_view.private_message_report.resolved) { urcs.next(urcs.getValue() - 1); } else { urcs.next(urcs.getValue() + 1); } this.setState(this.state); } } }