4 editPrivateMessageReport,
8 import { amAdmin } from "@utils/roles";
9 import { RouteDataResponse } from "@utils/types";
10 import { Component, linkEvent } from "inferno";
12 CommentReportResponse,
16 ListCommentReportsResponse,
18 ListPostReportsResponse,
19 ListPrivateMessageReports,
20 ListPrivateMessageReportsResponse,
23 PrivateMessageReportResponse,
24 PrivateMessageReportView,
27 ResolvePrivateMessageReport,
28 } from "lemmy-js-client";
29 import { fetchLimit } from "../../config";
30 import { i18n } from "../../i18next";
31 import { InitialFetchRequest } from "../../interfaces";
32 import { HttpService, UserService } from "../../services";
33 import { FirstLoadService } from "../../services/FirstLoadService";
34 import { RequestState } from "../../services/HttpService";
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="person-reports 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 className="btn-check"
197 value={UnreadOrAll.Unread}
198 checked={this.state.unreadOrAll == UnreadOrAll.Unread}
199 onChange={linkEvent(this, this.handleUnreadOrAllChange)}
204 className={`btn btn-outline-secondary pointer
205 ${this.state.unreadOrAll == UnreadOrAll.All && "active"}
210 className="btn-check"
211 value={UnreadOrAll.All}
212 checked={this.state.unreadOrAll == UnreadOrAll.All}
213 onChange={linkEvent(this, this.handleUnreadOrAllChange)}
221 messageTypeRadios() {
223 <div className="btn-group btn-group-toggle flex-wrap mb-2">
225 className={`btn btn-outline-secondary pointer
226 ${this.state.messageType == MessageType.All && "active"}
231 className="btn-check"
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 className="btn-check"
246 value={MessageType.CommentReport}
247 checked={this.state.messageType == MessageType.CommentReport}
248 onChange={linkEvent(this, this.handleMessageTypeChange)}
253 className={`btn btn-outline-secondary pointer
254 ${this.state.messageType == MessageType.PostReport && "active"}
259 className="btn-check"
260 value={MessageType.PostReport}
261 checked={this.state.messageType == MessageType.PostReport}
262 onChange={linkEvent(this, this.handleMessageTypeChange)}
268 className={`btn btn-outline-secondary pointer
270 this.state.messageType == MessageType.PrivateMessageReport &&
277 className="btn-check"
278 value={MessageType.PrivateMessageReport}
280 this.state.messageType == MessageType.PrivateMessageReport
282 onChange={linkEvent(this, this.handleMessageTypeChange)}
293 <div className="mb-2">
294 <span className="me-3">{this.unreadOrAllRadios()}</span>
295 <span className="me-3">{this.messageTypeRadios()}</span>
300 commentReportToItemType(r: CommentReportView): ItemType {
302 id: r.comment_report.id,
303 type_: MessageEnum.CommentReport,
305 published: r.comment_report.published,
309 postReportToItemType(r: PostReportView): ItemType {
311 id: r.post_report.id,
312 type_: MessageEnum.PostReport,
314 published: r.post_report.published,
318 privateMessageReportToItemType(r: PrivateMessageReportView): ItemType {
320 id: r.private_message_report.id,
321 type_: MessageEnum.PrivateMessageReport,
323 published: r.private_message_report.published,
327 get buildCombined(): ItemType[] {
328 const commentRes = this.state.commentReportsRes;
330 commentRes.state == "success"
331 ? commentRes.data.comment_reports.map(this.commentReportToItemType)
334 const postRes = this.state.postReportsRes;
336 postRes.state == "success"
337 ? postRes.data.post_reports.map(this.postReportToItemType)
339 const pmRes = this.state.messageReportsRes;
340 const privateMessages =
341 pmRes.state == "success"
342 ? pmRes.data.private_message_reports.map(
343 this.privateMessageReportToItemType
347 return [...comments, ...posts, ...privateMessages].sort((a, b) =>
348 b.published.localeCompare(a.published)
352 renderItemType(i: ItemType) {
354 case MessageEnum.CommentReport:
358 report={i.view as CommentReportView}
359 onResolveReport={this.handleResolveCommentReport}
362 case MessageEnum.PostReport:
366 report={i.view as PostReportView}
367 onResolveReport={this.handleResolvePostReport}
370 case MessageEnum.PrivateMessageReport:
372 <PrivateMessageReport
374 report={i.view as PrivateMessageReportView}
375 onResolveReport={this.handleResolvePrivateMessageReport}
386 {this.buildCombined.map(i => (
389 {this.renderItemType(i)}
397 const res = this.state.commentReportsRes;
406 const reports = res.data.comment_reports;
413 key={cr.comment_report.id}
415 onResolveReport={this.handleResolveCommentReport}
426 const res = this.state.postReportsRes;
435 const reports = res.data.post_reports;
442 key={pr.post_report.id}
444 onResolveReport={this.handleResolvePostReport}
454 privateMessageReports() {
455 const res = this.state.messageReportsRes;
464 const reports = res.data.private_message_reports;
467 {reports.map(pmr => (
470 <PrivateMessageReport
471 key={pmr.private_message_report.id}
473 onResolveReport={this.handleResolvePrivateMessageReport}
483 async handlePageChange(page: number) {
484 this.setState({ page });
485 await this.refetch();
488 async handleUnreadOrAllChange(i: Reports, event: any) {
489 i.setState({ unreadOrAll: Number(event.target.value), page: 1 });
493 async handleMessageTypeChange(i: Reports, event: any) {
494 i.setState({ messageType: Number(event.target.value), page: 1 });
498 static async fetchInitialData({
501 }: InitialFetchRequest): Promise<ReportsData> {
502 const unresolved_only = true;
504 const limit = fetchLimit;
506 const commentReportsForm: ListCommentReports = {
510 auth: auth as string,
513 const postReportsForm: ListPostReports = {
517 auth: auth as string,
520 const data: ReportsData = {
521 commentReportsRes: await client.listCommentReports(commentReportsForm),
522 postReportsRes: await client.listPostReports(postReportsForm),
523 messageReportsRes: { state: "empty" },
527 const privateMessageReportsForm: ListPrivateMessageReports = {
531 auth: auth as string,
534 data.messageReportsRes = await client.listPrivateMessageReports(
535 privateMessageReportsForm
543 const unresolved_only = this.state.unreadOrAll == UnreadOrAll.Unread;
544 const page = this.state.page;
545 const limit = fetchLimit;
546 const auth = myAuthRequired();
549 commentReportsRes: { state: "loading" },
550 postReportsRes: { state: "loading" },
551 messageReportsRes: { state: "loading" },
557 | ListPrivateMessageReports = {
565 commentReportsRes: await HttpService.client.listCommentReports(form),
566 postReportsRes: await HttpService.client.listPostReports(form),
571 messageReportsRes: await HttpService.client.listPrivateMessageReports(
578 async handleResolveCommentReport(form: ResolveCommentReport) {
579 const res = await HttpService.client.resolveCommentReport(form);
580 this.findAndUpdateCommentReport(res);
583 async handleResolvePostReport(form: ResolvePostReport) {
584 const res = await HttpService.client.resolvePostReport(form);
585 this.findAndUpdatePostReport(res);
588 async handleResolvePrivateMessageReport(form: ResolvePrivateMessageReport) {
589 const res = await HttpService.client.resolvePrivateMessageReport(form);
590 this.findAndUpdatePrivateMessageReport(res);
593 findAndUpdateCommentReport(res: RequestState<CommentReportResponse>) {
595 if (s.commentReportsRes.state == "success" && res.state == "success") {
596 s.commentReportsRes.data.comment_reports = editCommentReport(
597 res.data.comment_report_view,
598 s.commentReportsRes.data.comment_reports
605 findAndUpdatePostReport(res: RequestState<PostReportResponse>) {
607 if (s.postReportsRes.state == "success" && res.state == "success") {
608 s.postReportsRes.data.post_reports = editPostReport(
609 res.data.post_report_view,
610 s.postReportsRes.data.post_reports
617 findAndUpdatePrivateMessageReport(
618 res: RequestState<PrivateMessageReportResponse>
621 if (s.messageReportsRes.state == "success" && res.state == "success") {
622 s.messageReportsRes.data.private_message_reports =
623 editPrivateMessageReport(
624 res.data.private_message_report_view,
625 s.messageReportsRes.data.private_message_reports