4 editPrivateMessageReport,
8 import { isBrowser } from "@utils/browser";
9 import { amAdmin } from "@utils/roles";
10 import { RouteDataResponse } from "@utils/types";
11 import { Component, linkEvent } from "inferno";
13 CommentReportResponse,
17 ListCommentReportsResponse,
19 ListPostReportsResponse,
20 ListPrivateMessageReports,
21 ListPrivateMessageReportsResponse,
24 PrivateMessageReportResponse,
25 PrivateMessageReportView,
28 ResolvePrivateMessageReport,
29 } from "lemmy-js-client";
30 import { fetchLimit } from "../../config";
31 import { InitialFetchRequest } from "../../interfaces";
37 } from "../../services";
38 import { RequestState } from "../../services/HttpService";
39 import { CommentReport } from "../comment/comment-report";
40 import { HtmlTags } from "../common/html-tags";
41 import { Spinner } from "../common/icon";
42 import { Paginator } from "../common/paginator";
43 import { PostReport } from "../post/post-report";
44 import { PrivateMessageReport } from "../private_message/private-message-report";
64 type ReportsData = RouteDataResponse<{
65 commentReportsRes: ListCommentReportsResponse;
66 postReportsRes: ListPostReportsResponse;
67 messageReportsRes: ListPrivateMessageReportsResponse;
73 view: CommentReportView | PostReportView | PrivateMessageReportView;
77 interface ReportsState {
78 commentReportsRes: RequestState<ListCommentReportsResponse>;
79 postReportsRes: RequestState<ListPostReportsResponse>;
80 messageReportsRes: RequestState<ListPrivateMessageReportsResponse>;
81 unreadOrAll: UnreadOrAll;
82 messageType: MessageType;
83 siteRes: GetSiteResponse;
85 isIsomorphic: boolean;
88 export class Reports extends Component<any, ReportsState> {
89 private isoData = setIsoData<ReportsData>(this.context);
90 state: ReportsState = {
91 commentReportsRes: { state: "empty" },
92 postReportsRes: { state: "empty" },
93 messageReportsRes: { state: "empty" },
94 unreadOrAll: UnreadOrAll.Unread,
95 messageType: MessageType.All,
97 siteRes: this.isoData.site_res,
101 constructor(props: any, context: any) {
102 super(props, context);
104 this.handlePageChange = this.handlePageChange.bind(this);
105 this.handleResolveCommentReport =
106 this.handleResolveCommentReport.bind(this);
107 this.handleResolvePostReport = this.handleResolvePostReport.bind(this);
108 this.handleResolvePrivateMessageReport =
109 this.handleResolvePrivateMessageReport.bind(this);
111 // Only fetch the data if coming from another route
112 if (!isBrowser() || FirstLoadService.isFirstLoad) {
113 const { commentReportsRes, postReportsRes, messageReportsRes } =
114 this.isoData.routeData;
126 messageReportsRes: messageReportsRes,
132 async componentDidMount() {
133 if (!this.state.isIsomorphic) {
134 await this.refetch();
138 get documentTitle(): string {
139 const mui = UserService.Instance.myUserInfo;
141 ? `@${mui.local_user_view.person.name} ${I18NextService.i18n.t(
143 )} - ${this.state.siteRes.site_view.site.name}`
149 <div className="person-reports container-lg">
150 <div className="row">
151 <div className="col-12">
153 title={this.documentTitle}
154 path={this.context.router.route.match.url}
156 <h5 className="mb-2">{I18NextService.i18n.t("reports")}</h5>
160 page={this.state.page}
161 onChange={this.handlePageChange}
170 switch (this.state.messageType) {
171 case MessageType.All: {
174 case MessageType.CommentReport: {
175 return this.commentReports();
177 case MessageType.PostReport: {
178 return this.postReports();
180 case MessageType.PrivateMessageReport: {
181 return this.privateMessageReports();
190 unreadOrAllRadios() {
192 <div className="btn-group btn-group-toggle flex-wrap mb-2">
194 className={`btn btn-outline-secondary pointer
195 ${this.state.unreadOrAll == UnreadOrAll.Unread && "active"}
200 className="btn-check"
201 value={UnreadOrAll.Unread}
202 checked={this.state.unreadOrAll == UnreadOrAll.Unread}
203 onChange={linkEvent(this, this.handleUnreadOrAllChange)}
205 {I18NextService.i18n.t("unread")}
208 className={`btn btn-outline-secondary pointer
209 ${this.state.unreadOrAll == UnreadOrAll.All && "active"}
214 className="btn-check"
215 value={UnreadOrAll.All}
216 checked={this.state.unreadOrAll == UnreadOrAll.All}
217 onChange={linkEvent(this, this.handleUnreadOrAllChange)}
219 {I18NextService.i18n.t("all")}
225 messageTypeRadios() {
227 <div className="btn-group btn-group-toggle flex-wrap mb-2">
229 className={`btn btn-outline-secondary pointer
230 ${this.state.messageType == MessageType.All && "active"}
235 className="btn-check"
236 value={MessageType.All}
237 checked={this.state.messageType == MessageType.All}
238 onChange={linkEvent(this, this.handleMessageTypeChange)}
240 {I18NextService.i18n.t("all")}
243 className={`btn btn-outline-secondary pointer
244 ${this.state.messageType == MessageType.CommentReport && "active"}
249 className="btn-check"
250 value={MessageType.CommentReport}
251 checked={this.state.messageType == MessageType.CommentReport}
252 onChange={linkEvent(this, this.handleMessageTypeChange)}
254 {I18NextService.i18n.t("comments")}
257 className={`btn btn-outline-secondary pointer
258 ${this.state.messageType == MessageType.PostReport && "active"}
263 className="btn-check"
264 value={MessageType.PostReport}
265 checked={this.state.messageType == MessageType.PostReport}
266 onChange={linkEvent(this, this.handleMessageTypeChange)}
268 {I18NextService.i18n.t("posts")}
272 className={`btn btn-outline-secondary pointer
274 this.state.messageType == MessageType.PrivateMessageReport &&
281 className="btn-check"
282 value={MessageType.PrivateMessageReport}
284 this.state.messageType == MessageType.PrivateMessageReport
286 onChange={linkEvent(this, this.handleMessageTypeChange)}
288 {I18NextService.i18n.t("messages")}
297 <div className="mb-2">
298 <span className="me-3">{this.unreadOrAllRadios()}</span>
299 <span className="me-3">{this.messageTypeRadios()}</span>
304 commentReportToItemType(r: CommentReportView): ItemType {
306 id: r.comment_report.id,
307 type_: MessageEnum.CommentReport,
309 published: r.comment_report.published,
313 postReportToItemType(r: PostReportView): ItemType {
315 id: r.post_report.id,
316 type_: MessageEnum.PostReport,
318 published: r.post_report.published,
322 privateMessageReportToItemType(r: PrivateMessageReportView): ItemType {
324 id: r.private_message_report.id,
325 type_: MessageEnum.PrivateMessageReport,
327 published: r.private_message_report.published,
331 get buildCombined(): ItemType[] {
332 const commentRes = this.state.commentReportsRes;
334 commentRes.state == "success"
335 ? commentRes.data.comment_reports.map(this.commentReportToItemType)
338 const postRes = this.state.postReportsRes;
340 postRes.state == "success"
341 ? postRes.data.post_reports.map(this.postReportToItemType)
343 const pmRes = this.state.messageReportsRes;
344 const privateMessages =
345 pmRes.state == "success"
346 ? pmRes.data.private_message_reports.map(
347 this.privateMessageReportToItemType
351 return [...comments, ...posts, ...privateMessages].sort((a, b) =>
352 b.published.localeCompare(a.published)
356 renderItemType(i: ItemType) {
358 case MessageEnum.CommentReport:
362 report={i.view as CommentReportView}
363 onResolveReport={this.handleResolveCommentReport}
366 case MessageEnum.PostReport:
370 report={i.view as PostReportView}
371 onResolveReport={this.handleResolvePostReport}
374 case MessageEnum.PrivateMessageReport:
376 <PrivateMessageReport
378 report={i.view as PrivateMessageReportView}
379 onResolveReport={this.handleResolvePrivateMessageReport}
390 {this.buildCombined.map(i => (
393 {this.renderItemType(i)}
401 const res = this.state.commentReportsRes;
410 const reports = res.data.comment_reports;
417 key={cr.comment_report.id}
419 onResolveReport={this.handleResolveCommentReport}
430 const res = this.state.postReportsRes;
439 const reports = res.data.post_reports;
446 key={pr.post_report.id}
448 onResolveReport={this.handleResolvePostReport}
458 privateMessageReports() {
459 const res = this.state.messageReportsRes;
468 const reports = res.data.private_message_reports;
471 {reports.map(pmr => (
474 <PrivateMessageReport
475 key={pmr.private_message_report.id}
477 onResolveReport={this.handleResolvePrivateMessageReport}
487 async handlePageChange(page: number) {
488 this.setState({ page });
489 await this.refetch();
492 async handleUnreadOrAllChange(i: Reports, event: any) {
493 i.setState({ unreadOrAll: Number(event.target.value), page: 1 });
497 async handleMessageTypeChange(i: Reports, event: any) {
498 i.setState({ messageType: Number(event.target.value), page: 1 });
502 static async fetchInitialData({
505 }: InitialFetchRequest): Promise<ReportsData> {
506 const unresolved_only = true;
508 const limit = fetchLimit;
510 const commentReportsForm: ListCommentReports = {
514 auth: auth as string,
517 const postReportsForm: ListPostReports = {
521 auth: auth as string,
524 const data: ReportsData = {
525 commentReportsRes: await client.listCommentReports(commentReportsForm),
526 postReportsRes: await client.listPostReports(postReportsForm),
527 messageReportsRes: { state: "empty" },
531 const privateMessageReportsForm: ListPrivateMessageReports = {
535 auth: auth as string,
538 data.messageReportsRes = await client.listPrivateMessageReports(
539 privateMessageReportsForm
547 const unresolved_only = this.state.unreadOrAll == UnreadOrAll.Unread;
548 const page = this.state.page;
549 const limit = fetchLimit;
550 const auth = myAuthRequired();
553 commentReportsRes: { state: "loading" },
554 postReportsRes: { state: "loading" },
555 messageReportsRes: { state: "loading" },
561 | ListPrivateMessageReports = {
569 commentReportsRes: await HttpService.client.listCommentReports(form),
570 postReportsRes: await HttpService.client.listPostReports(form),
575 messageReportsRes: await HttpService.client.listPrivateMessageReports(
582 async handleResolveCommentReport(form: ResolveCommentReport) {
583 const res = await HttpService.client.resolveCommentReport(form);
584 this.findAndUpdateCommentReport(res);
587 async handleResolvePostReport(form: ResolvePostReport) {
588 const res = await HttpService.client.resolvePostReport(form);
589 this.findAndUpdatePostReport(res);
592 async handleResolvePrivateMessageReport(form: ResolvePrivateMessageReport) {
593 const res = await HttpService.client.resolvePrivateMessageReport(form);
594 this.findAndUpdatePrivateMessageReport(res);
597 findAndUpdateCommentReport(res: RequestState<CommentReportResponse>) {
599 if (s.commentReportsRes.state == "success" && res.state == "success") {
600 s.commentReportsRes.data.comment_reports = editCommentReport(
601 res.data.comment_report_view,
602 s.commentReportsRes.data.comment_reports
609 findAndUpdatePostReport(res: RequestState<PostReportResponse>) {
611 if (s.postReportsRes.state == "success" && res.state == "success") {
612 s.postReportsRes.data.post_reports = editPostReport(
613 res.data.post_report_view,
614 s.postReportsRes.data.post_reports
621 findAndUpdatePrivateMessageReport(
622 res: RequestState<PrivateMessageReportResponse>
625 if (s.messageReportsRes.state == "success" && res.state == "success") {
626 s.messageReportsRes.data.private_message_reports =
627 editPrivateMessageReport(
628 res.data.private_message_report_view,
629 s.messageReportsRes.data.private_message_reports