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";
30 editPrivateMessageReport,
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 commentReportsResponse: ListCommentReportsResponse;
62 postReportsResponse: ListPostReportsResponse;
63 privateMessageReportsResponse?: 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) {
110 commentReportsResponse: commentReportsRes,
111 postReportsResponse: postReportsRes,
112 privateMessageReportsResponse: messageReportsRes,
113 } = this.isoData.routeData;
125 messageReportsRes: messageReportsRes ?? { state: "empty" },
131 async componentDidMount() {
132 if (!this.state.isIsomorphic) {
133 await this.refetch();
137 get documentTitle(): string {
138 const mui = UserService.Instance.myUserInfo;
140 ? `@${mui.local_user_view.person.name} ${i18n.t("reports")} - ${
141 this.state.siteRes.site_view.site.name
148 <div className="container-lg">
149 <div className="row">
150 <div className="col-12">
152 title={this.documentTitle}
153 path={this.context.router.route.match.url}
155 <h5 className="mb-2">{i18n.t("reports")}</h5>
159 page={this.state.page}
160 onChange={this.handlePageChange}
169 switch (this.state.messageType) {
170 case MessageType.All: {
173 case MessageType.CommentReport: {
174 return this.commentReports();
176 case MessageType.PostReport: {
177 return this.postReports();
179 case MessageType.PrivateMessageReport: {
180 return this.privateMessageReports();
189 unreadOrAllRadios() {
191 <div className="btn-group btn-group-toggle flex-wrap mb-2">
193 className={`btn btn-outline-secondary pointer
194 ${this.state.unreadOrAll == UnreadOrAll.Unread && "active"}
199 value={UnreadOrAll.Unread}
200 checked={this.state.unreadOrAll == UnreadOrAll.Unread}
201 onChange={linkEvent(this, this.handleUnreadOrAllChange)}
206 className={`btn btn-outline-secondary pointer
207 ${this.state.unreadOrAll == UnreadOrAll.All && "active"}
212 value={UnreadOrAll.All}
213 checked={this.state.unreadOrAll == UnreadOrAll.All}
214 onChange={linkEvent(this, this.handleUnreadOrAllChange)}
222 messageTypeRadios() {
224 <div className="btn-group btn-group-toggle flex-wrap mb-2">
226 className={`btn btn-outline-secondary pointer
227 ${this.state.messageType == MessageType.All && "active"}
232 value={MessageType.All}
233 checked={this.state.messageType == MessageType.All}
234 onChange={linkEvent(this, this.handleMessageTypeChange)}
239 className={`btn btn-outline-secondary pointer
240 ${this.state.messageType == MessageType.CommentReport && "active"}
245 value={MessageType.CommentReport}
246 checked={this.state.messageType == MessageType.CommentReport}
247 onChange={linkEvent(this, this.handleMessageTypeChange)}
252 className={`btn btn-outline-secondary pointer
253 ${this.state.messageType == MessageType.PostReport && "active"}
258 value={MessageType.PostReport}
259 checked={this.state.messageType == MessageType.PostReport}
260 onChange={linkEvent(this, this.handleMessageTypeChange)}
266 className={`btn btn-outline-secondary pointer
268 this.state.messageType == MessageType.PrivateMessageReport &&
275 value={MessageType.PrivateMessageReport}
277 this.state.messageType == MessageType.PrivateMessageReport
279 onChange={linkEvent(this, this.handleMessageTypeChange)}
290 <div className="mb-2">
291 <span className="mr-3">{this.unreadOrAllRadios()}</span>
292 <span className="mr-3">{this.messageTypeRadios()}</span>
297 commentReportToItemType(r: CommentReportView): ItemType {
299 id: r.comment_report.id,
300 type_: MessageEnum.CommentReport,
302 published: r.comment_report.published,
306 postReportToItemType(r: PostReportView): ItemType {
308 id: r.post_report.id,
309 type_: MessageEnum.PostReport,
311 published: r.post_report.published,
315 privateMessageReportToItemType(r: PrivateMessageReportView): ItemType {
317 id: r.private_message_report.id,
318 type_: MessageEnum.PrivateMessageReport,
320 published: r.private_message_report.published,
324 get buildCombined(): ItemType[] {
325 const commentRes = this.state.commentReportsRes;
327 commentRes.state == "success"
328 ? commentRes.data.comment_reports.map(this.commentReportToItemType)
331 const postRes = this.state.postReportsRes;
333 postRes.state == "success"
334 ? postRes.data.post_reports.map(this.postReportToItemType)
336 const pmRes = this.state.messageReportsRes;
337 const privateMessages =
338 pmRes.state == "success"
339 ? pmRes.data.private_message_reports.map(
340 this.privateMessageReportToItemType
344 return [...comments, ...posts, ...privateMessages].sort((a, b) =>
345 b.published.localeCompare(a.published)
349 renderItemType(i: ItemType) {
351 case MessageEnum.CommentReport:
355 report={i.view as CommentReportView}
356 onResolveReport={this.handleResolveCommentReport}
359 case MessageEnum.PostReport:
363 report={i.view as PostReportView}
364 onResolveReport={this.handleResolvePostReport}
367 case MessageEnum.PrivateMessageReport:
369 <PrivateMessageReport
371 report={i.view as PrivateMessageReportView}
372 onResolveReport={this.handleResolvePrivateMessageReport}
383 {this.buildCombined.map(i => (
386 {this.renderItemType(i)}
394 const res = this.state.commentReportsRes;
403 const reports = res.data.comment_reports;
410 key={cr.comment_report.id}
412 onResolveReport={this.handleResolveCommentReport}
423 const res = this.state.postReportsRes;
432 const reports = res.data.post_reports;
439 key={pr.post_report.id}
441 onResolveReport={this.handleResolvePostReport}
451 privateMessageReports() {
452 const res = this.state.messageReportsRes;
461 const reports = res.data.private_message_reports;
464 {reports.map(pmr => (
467 <PrivateMessageReport
468 key={pmr.private_message_report.id}
470 onResolveReport={this.handleResolvePrivateMessageReport}
480 async handlePageChange(page: number) {
481 this.setState({ page });
482 await this.refetch();
485 async handleUnreadOrAllChange(i: Reports, event: any) {
486 i.setState({ unreadOrAll: Number(event.target.value), page: 1 });
490 async handleMessageTypeChange(i: Reports, event: any) {
491 i.setState({ messageType: Number(event.target.value), page: 1 });
495 static async fetchInitialData({
498 }: InitialFetchRequest): Promise<ReportsData> {
499 const unresolved_only = true;
501 const limit = fetchLimit;
503 const commentReportsForm: ListCommentReports = {
507 auth: auth as string,
510 const postReportsForm: ListPostReports = {
514 auth: auth as string,
517 const data: ReportsData = {
518 commentReportsResponse: await client.listCommentReports(
521 postReportsResponse: await client.listPostReports(postReportsForm),
525 const privateMessageReportsForm: ListPrivateMessageReports = {
529 auth: auth as string,
532 data.privateMessageReportsResponse =
533 await client.listPrivateMessageReports(privateMessageReportsForm);
540 const unresolved_only = this.state.unreadOrAll == UnreadOrAll.Unread;
541 const page = this.state.page;
542 const limit = fetchLimit;
543 const auth = myAuthRequired();
546 commentReportsRes: { state: "loading" },
547 postReportsRes: { state: "loading" },
548 messageReportsRes: { state: "loading" },
554 | ListPrivateMessageReports = {
562 commentReportsRes: await HttpService.client.listCommentReports(form),
563 postReportsRes: await HttpService.client.listPostReports(form),
568 messageReportsRes: await HttpService.client.listPrivateMessageReports(
575 async handleResolveCommentReport(form: ResolveCommentReport) {
576 const res = await HttpService.client.resolveCommentReport(form);
577 this.findAndUpdateCommentReport(res);
580 async handleResolvePostReport(form: ResolvePostReport) {
581 const res = await HttpService.client.resolvePostReport(form);
582 this.findAndUpdatePostReport(res);
585 async handleResolvePrivateMessageReport(form: ResolvePrivateMessageReport) {
586 const res = await HttpService.client.resolvePrivateMessageReport(form);
587 this.findAndUpdatePrivateMessageReport(res);
590 findAndUpdateCommentReport(res: RequestState<CommentReportResponse>) {
592 if (s.commentReportsRes.state == "success" && res.state == "success") {
593 s.commentReportsRes.data.comment_reports = editCommentReport(
594 res.data.comment_report_view,
595 s.commentReportsRes.data.comment_reports
602 findAndUpdatePostReport(res: RequestState<PostReportResponse>) {
604 if (s.postReportsRes.state == "success" && res.state == "success") {
605 s.postReportsRes.data.post_reports = editPostReport(
606 res.data.post_report_view,
607 s.postReportsRes.data.post_reports
614 findAndUpdatePrivateMessageReport(
615 res: RequestState<PrivateMessageReportResponse>
618 if (s.messageReportsRes.state == "success" && res.state == "success") {
619 s.messageReportsRes.data.private_message_reports =
620 editPrivateMessageReport(
621 res.data.private_message_report_view,
622 s.messageReportsRes.data.private_message_reports