1 import { Component, linkEvent } from "inferno";
7 ListCommentReportsResponse,
9 ListPostReportsResponse,
10 ListPrivateMessageReports,
11 ListPrivateMessageReportsResponse,
14 PrivateMessageReportResponse,
15 PrivateMessageReportView,
18 ResolvePrivateMessageReport,
19 } from "lemmy-js-client";
20 import { i18n } from "../../i18next";
21 import { InitialFetchRequest } from "../../interfaces";
22 import { HttpService, UserService } from "../../services";
23 import { FirstLoadService } from "../../services/FirstLoadService";
24 import { RequestState } from "../../services/HttpService";
29 editPrivateMessageReport,
34 import amAdmin from "../../utils/roles/am-admin";
35 import { CommentReport } from "../comment/comment-report";
36 import { HtmlTags } from "../common/html-tags";
37 import { Spinner } from "../common/icon";
38 import { Paginator } from "../common/paginator";
39 import { PostReport } from "../post/post-report";
40 import { PrivateMessageReport } from "../private_message/private-message-report";
60 type ReportsData = RouteDataResponse<{
61 commentReportsRes: ListCommentReportsResponse;
62 postReportsRes: ListPostReportsResponse;
63 messageReportsRes: ListPrivateMessageReportsResponse;
69 view: CommentReportView | PostReportView | PrivateMessageReportView;
73 interface ReportsState {
74 commentReportsRes: RequestState<ListCommentReportsResponse>;
75 postReportsRes: RequestState<ListPostReportsResponse>;
76 messageReportsRes: RequestState<ListPrivateMessageReportsResponse>;
77 unreadOrAll: UnreadOrAll;
78 messageType: MessageType;
79 siteRes: GetSiteResponse;
81 isIsomorphic: boolean;
84 export class Reports extends Component<any, ReportsState> {
85 private isoData = setIsoData<ReportsData>(this.context);
86 state: ReportsState = {
87 commentReportsRes: { state: "empty" },
88 postReportsRes: { state: "empty" },
89 messageReportsRes: { state: "empty" },
90 unreadOrAll: UnreadOrAll.Unread,
91 messageType: MessageType.All,
93 siteRes: this.isoData.site_res,
97 constructor(props: any, context: any) {
98 super(props, context);
100 this.handlePageChange = this.handlePageChange.bind(this);
101 this.handleResolveCommentReport =
102 this.handleResolveCommentReport.bind(this);
103 this.handleResolvePostReport = this.handleResolvePostReport.bind(this);
104 this.handleResolvePrivateMessageReport =
105 this.handleResolvePrivateMessageReport.bind(this);
107 // Only fetch the data if coming from another route
108 if (FirstLoadService.isFirstLoad) {
109 const { commentReportsRes, postReportsRes, messageReportsRes } =
110 this.isoData.routeData;
122 messageReportsRes: messageReportsRes,
128 async componentDidMount() {
129 if (!this.state.isIsomorphic) {
130 await this.refetch();
134 get documentTitle(): string {
135 const mui = UserService.Instance.myUserInfo;
137 ? `@${mui.local_user_view.person.name} ${i18n.t("reports")} - ${
138 this.state.siteRes.site_view.site.name
145 <div className="container-lg">
146 <div className="row">
147 <div className="col-12">
149 title={this.documentTitle}
150 path={this.context.router.route.match.url}
152 <h5 className="mb-2">{i18n.t("reports")}</h5>
156 page={this.state.page}
157 onChange={this.handlePageChange}
166 switch (this.state.messageType) {
167 case MessageType.All: {
170 case MessageType.CommentReport: {
171 return this.commentReports();
173 case MessageType.PostReport: {
174 return this.postReports();
176 case MessageType.PrivateMessageReport: {
177 return this.privateMessageReports();
186 unreadOrAllRadios() {
188 <div className="btn-group btn-group-toggle flex-wrap mb-2">
190 className={`btn btn-outline-secondary pointer
191 ${this.state.unreadOrAll == UnreadOrAll.Unread && "active"}
196 value={UnreadOrAll.Unread}
197 checked={this.state.unreadOrAll == UnreadOrAll.Unread}
198 onChange={linkEvent(this, this.handleUnreadOrAllChange)}
203 className={`btn btn-outline-secondary pointer
204 ${this.state.unreadOrAll == UnreadOrAll.All && "active"}
209 value={UnreadOrAll.All}
210 checked={this.state.unreadOrAll == UnreadOrAll.All}
211 onChange={linkEvent(this, this.handleUnreadOrAllChange)}
219 messageTypeRadios() {
221 <div className="btn-group btn-group-toggle flex-wrap mb-2">
223 className={`btn btn-outline-secondary pointer
224 ${this.state.messageType == MessageType.All && "active"}
229 value={MessageType.All}
230 checked={this.state.messageType == MessageType.All}
231 onChange={linkEvent(this, this.handleMessageTypeChange)}
236 className={`btn btn-outline-secondary pointer
237 ${this.state.messageType == MessageType.CommentReport && "active"}
242 value={MessageType.CommentReport}
243 checked={this.state.messageType == MessageType.CommentReport}
244 onChange={linkEvent(this, this.handleMessageTypeChange)}
249 className={`btn btn-outline-secondary pointer
250 ${this.state.messageType == MessageType.PostReport && "active"}
255 value={MessageType.PostReport}
256 checked={this.state.messageType == MessageType.PostReport}
257 onChange={linkEvent(this, this.handleMessageTypeChange)}
263 className={`btn btn-outline-secondary pointer
265 this.state.messageType == MessageType.PrivateMessageReport &&
272 value={MessageType.PrivateMessageReport}
274 this.state.messageType == MessageType.PrivateMessageReport
276 onChange={linkEvent(this, this.handleMessageTypeChange)}
287 <div className="mb-2">
288 <span className="mr-3">{this.unreadOrAllRadios()}</span>
289 <span className="mr-3">{this.messageTypeRadios()}</span>
294 commentReportToItemType(r: CommentReportView): ItemType {
296 id: r.comment_report.id,
297 type_: MessageEnum.CommentReport,
299 published: r.comment_report.published,
303 postReportToItemType(r: PostReportView): ItemType {
305 id: r.post_report.id,
306 type_: MessageEnum.PostReport,
308 published: r.post_report.published,
312 privateMessageReportToItemType(r: PrivateMessageReportView): ItemType {
314 id: r.private_message_report.id,
315 type_: MessageEnum.PrivateMessageReport,
317 published: r.private_message_report.published,
321 get buildCombined(): ItemType[] {
322 const commentRes = this.state.commentReportsRes;
324 commentRes.state == "success"
325 ? commentRes.data.comment_reports.map(this.commentReportToItemType)
328 const postRes = this.state.postReportsRes;
330 postRes.state == "success"
331 ? postRes.data.post_reports.map(this.postReportToItemType)
333 const pmRes = this.state.messageReportsRes;
334 const privateMessages =
335 pmRes.state == "success"
336 ? pmRes.data.private_message_reports.map(
337 this.privateMessageReportToItemType
341 return [...comments, ...posts, ...privateMessages].sort((a, b) =>
342 b.published.localeCompare(a.published)
346 renderItemType(i: ItemType) {
348 case MessageEnum.CommentReport:
352 report={i.view as CommentReportView}
353 onResolveReport={this.handleResolveCommentReport}
356 case MessageEnum.PostReport:
360 report={i.view as PostReportView}
361 onResolveReport={this.handleResolvePostReport}
364 case MessageEnum.PrivateMessageReport:
366 <PrivateMessageReport
368 report={i.view as PrivateMessageReportView}
369 onResolveReport={this.handleResolvePrivateMessageReport}
380 {this.buildCombined.map(i => (
383 {this.renderItemType(i)}
391 const res = this.state.commentReportsRes;
400 const reports = res.data.comment_reports;
407 key={cr.comment_report.id}
409 onResolveReport={this.handleResolveCommentReport}
420 const res = this.state.postReportsRes;
429 const reports = res.data.post_reports;
436 key={pr.post_report.id}
438 onResolveReport={this.handleResolvePostReport}
448 privateMessageReports() {
449 const res = this.state.messageReportsRes;
458 const reports = res.data.private_message_reports;
461 {reports.map(pmr => (
464 <PrivateMessageReport
465 key={pmr.private_message_report.id}
467 onResolveReport={this.handleResolvePrivateMessageReport}
477 async handlePageChange(page: number) {
478 this.setState({ page });
479 await this.refetch();
482 async handleUnreadOrAllChange(i: Reports, event: any) {
483 i.setState({ unreadOrAll: Number(event.target.value), page: 1 });
487 async handleMessageTypeChange(i: Reports, event: any) {
488 i.setState({ messageType: Number(event.target.value), page: 1 });
492 static async fetchInitialData({
495 }: InitialFetchRequest): Promise<ReportsData> {
496 const unresolved_only = true;
498 const limit = fetchLimit;
500 const commentReportsForm: ListCommentReports = {
504 auth: auth as string,
507 const postReportsForm: ListPostReports = {
511 auth: auth as string,
514 const data: ReportsData = {
515 commentReportsRes: await client.listCommentReports(commentReportsForm),
516 postReportsRes: await client.listPostReports(postReportsForm),
517 messageReportsRes: { state: "empty" },
521 const privateMessageReportsForm: ListPrivateMessageReports = {
525 auth: auth as string,
528 data.messageReportsRes = await client.listPrivateMessageReports(
529 privateMessageReportsForm
537 const unresolved_only = this.state.unreadOrAll == UnreadOrAll.Unread;
538 const page = this.state.page;
539 const limit = fetchLimit;
540 const auth = myAuthRequired();
543 commentReportsRes: { state: "loading" },
544 postReportsRes: { state: "loading" },
545 messageReportsRes: { state: "loading" },
551 | ListPrivateMessageReports = {
559 commentReportsRes: await HttpService.client.listCommentReports(form),
560 postReportsRes: await HttpService.client.listPostReports(form),
565 messageReportsRes: await HttpService.client.listPrivateMessageReports(
572 async handleResolveCommentReport(form: ResolveCommentReport) {
573 const res = await HttpService.client.resolveCommentReport(form);
574 this.findAndUpdateCommentReport(res);
577 async handleResolvePostReport(form: ResolvePostReport) {
578 const res = await HttpService.client.resolvePostReport(form);
579 this.findAndUpdatePostReport(res);
582 async handleResolvePrivateMessageReport(form: ResolvePrivateMessageReport) {
583 const res = await HttpService.client.resolvePrivateMessageReport(form);
584 this.findAndUpdatePrivateMessageReport(res);
587 findAndUpdateCommentReport(res: RequestState<CommentReportResponse>) {
589 if (s.commentReportsRes.state == "success" && res.state == "success") {
590 s.commentReportsRes.data.comment_reports = editCommentReport(
591 res.data.comment_report_view,
592 s.commentReportsRes.data.comment_reports
599 findAndUpdatePostReport(res: RequestState<PostReportResponse>) {
601 if (s.postReportsRes.state == "success" && res.state == "success") {
602 s.postReportsRes.data.post_reports = editPostReport(
603 res.data.post_report_view,
604 s.postReportsRes.data.post_reports
611 findAndUpdatePrivateMessageReport(
612 res: RequestState<PrivateMessageReportResponse>
615 if (s.messageReportsRes.state == "success" && res.state == "success") {
616 s.messageReportsRes.data.private_message_reports =
617 editPrivateMessageReport(
618 res.data.private_message_report_view,
619 s.messageReportsRes.data.private_message_reports