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 { InitialFetchRequest } from "../../interfaces";
36 } from "../../services";
37 import { RequestState } from "../../services/HttpService";
38 import { CommentReport } from "../comment/comment-report";
39 import { HtmlTags } from "../common/html-tags";
40 import { Spinner } from "../common/icon";
41 import { Paginator } from "../common/paginator";
42 import { PostReport } from "../post/post-report";
43 import { PrivateMessageReport } from "../private_message/private-message-report";
63 type ReportsData = RouteDataResponse<{
64 commentReportsRes: ListCommentReportsResponse;
65 postReportsRes: ListPostReportsResponse;
66 messageReportsRes: ListPrivateMessageReportsResponse;
72 view: CommentReportView | PostReportView | PrivateMessageReportView;
76 interface ReportsState {
77 commentReportsRes: RequestState<ListCommentReportsResponse>;
78 postReportsRes: RequestState<ListPostReportsResponse>;
79 messageReportsRes: RequestState<ListPrivateMessageReportsResponse>;
80 unreadOrAll: UnreadOrAll;
81 messageType: MessageType;
82 siteRes: GetSiteResponse;
84 isIsomorphic: boolean;
87 export class Reports extends Component<any, ReportsState> {
88 private isoData = setIsoData<ReportsData>(this.context);
89 state: ReportsState = {
90 commentReportsRes: { state: "empty" },
91 postReportsRes: { state: "empty" },
92 messageReportsRes: { state: "empty" },
93 unreadOrAll: UnreadOrAll.Unread,
94 messageType: MessageType.All,
96 siteRes: this.isoData.site_res,
100 constructor(props: any, context: any) {
101 super(props, context);
103 this.handlePageChange = this.handlePageChange.bind(this);
104 this.handleResolveCommentReport =
105 this.handleResolveCommentReport.bind(this);
106 this.handleResolvePostReport = this.handleResolvePostReport.bind(this);
107 this.handleResolvePrivateMessageReport =
108 this.handleResolvePrivateMessageReport.bind(this);
110 // Only fetch the data if coming from another route
111 if (FirstLoadService.isFirstLoad) {
112 const { commentReportsRes, postReportsRes, messageReportsRes } =
113 this.isoData.routeData;
125 messageReportsRes: messageReportsRes,
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} ${I18NextService.i18n.t(
142 )} - ${this.state.siteRes.site_view.site.name}`
148 <div className="person-reports 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">{I18NextService.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 className="btn-check"
200 value={UnreadOrAll.Unread}
201 checked={this.state.unreadOrAll == UnreadOrAll.Unread}
202 onChange={linkEvent(this, this.handleUnreadOrAllChange)}
204 {I18NextService.i18n.t("unread")}
207 className={`btn btn-outline-secondary pointer
208 ${this.state.unreadOrAll == UnreadOrAll.All && "active"}
213 className="btn-check"
214 value={UnreadOrAll.All}
215 checked={this.state.unreadOrAll == UnreadOrAll.All}
216 onChange={linkEvent(this, this.handleUnreadOrAllChange)}
218 {I18NextService.i18n.t("all")}
224 messageTypeRadios() {
226 <div className="btn-group btn-group-toggle flex-wrap mb-2">
228 className={`btn btn-outline-secondary pointer
229 ${this.state.messageType == MessageType.All && "active"}
234 className="btn-check"
235 value={MessageType.All}
236 checked={this.state.messageType == MessageType.All}
237 onChange={linkEvent(this, this.handleMessageTypeChange)}
239 {I18NextService.i18n.t("all")}
242 className={`btn btn-outline-secondary pointer
243 ${this.state.messageType == MessageType.CommentReport && "active"}
248 className="btn-check"
249 value={MessageType.CommentReport}
250 checked={this.state.messageType == MessageType.CommentReport}
251 onChange={linkEvent(this, this.handleMessageTypeChange)}
253 {I18NextService.i18n.t("comments")}
256 className={`btn btn-outline-secondary pointer
257 ${this.state.messageType == MessageType.PostReport && "active"}
262 className="btn-check"
263 value={MessageType.PostReport}
264 checked={this.state.messageType == MessageType.PostReport}
265 onChange={linkEvent(this, this.handleMessageTypeChange)}
267 {I18NextService.i18n.t("posts")}
271 className={`btn btn-outline-secondary pointer
273 this.state.messageType == MessageType.PrivateMessageReport &&
280 className="btn-check"
281 value={MessageType.PrivateMessageReport}
283 this.state.messageType == MessageType.PrivateMessageReport
285 onChange={linkEvent(this, this.handleMessageTypeChange)}
287 {I18NextService.i18n.t("messages")}
296 <div className="mb-2">
297 <span className="me-3">{this.unreadOrAllRadios()}</span>
298 <span className="me-3">{this.messageTypeRadios()}</span>
303 commentReportToItemType(r: CommentReportView): ItemType {
305 id: r.comment_report.id,
306 type_: MessageEnum.CommentReport,
308 published: r.comment_report.published,
312 postReportToItemType(r: PostReportView): ItemType {
314 id: r.post_report.id,
315 type_: MessageEnum.PostReport,
317 published: r.post_report.published,
321 privateMessageReportToItemType(r: PrivateMessageReportView): ItemType {
323 id: r.private_message_report.id,
324 type_: MessageEnum.PrivateMessageReport,
326 published: r.private_message_report.published,
330 get buildCombined(): ItemType[] {
331 const commentRes = this.state.commentReportsRes;
333 commentRes.state == "success"
334 ? commentRes.data.comment_reports.map(this.commentReportToItemType)
337 const postRes = this.state.postReportsRes;
339 postRes.state == "success"
340 ? postRes.data.post_reports.map(this.postReportToItemType)
342 const pmRes = this.state.messageReportsRes;
343 const privateMessages =
344 pmRes.state == "success"
345 ? pmRes.data.private_message_reports.map(
346 this.privateMessageReportToItemType
350 return [...comments, ...posts, ...privateMessages].sort((a, b) =>
351 b.published.localeCompare(a.published)
355 renderItemType(i: ItemType) {
357 case MessageEnum.CommentReport:
361 report={i.view as CommentReportView}
362 onResolveReport={this.handleResolveCommentReport}
365 case MessageEnum.PostReport:
369 report={i.view as PostReportView}
370 onResolveReport={this.handleResolvePostReport}
373 case MessageEnum.PrivateMessageReport:
375 <PrivateMessageReport
377 report={i.view as PrivateMessageReportView}
378 onResolveReport={this.handleResolvePrivateMessageReport}
389 {this.buildCombined.map(i => (
392 {this.renderItemType(i)}
400 const res = this.state.commentReportsRes;
409 const reports = res.data.comment_reports;
416 key={cr.comment_report.id}
418 onResolveReport={this.handleResolveCommentReport}
429 const res = this.state.postReportsRes;
438 const reports = res.data.post_reports;
445 key={pr.post_report.id}
447 onResolveReport={this.handleResolvePostReport}
457 privateMessageReports() {
458 const res = this.state.messageReportsRes;
467 const reports = res.data.private_message_reports;
470 {reports.map(pmr => (
473 <PrivateMessageReport
474 key={pmr.private_message_report.id}
476 onResolveReport={this.handleResolvePrivateMessageReport}
486 async handlePageChange(page: number) {
487 this.setState({ page });
488 await this.refetch();
491 async handleUnreadOrAllChange(i: Reports, event: any) {
492 i.setState({ unreadOrAll: Number(event.target.value), page: 1 });
496 async handleMessageTypeChange(i: Reports, event: any) {
497 i.setState({ messageType: Number(event.target.value), page: 1 });
501 static async fetchInitialData({
504 }: InitialFetchRequest): Promise<ReportsData> {
505 const unresolved_only = true;
507 const limit = fetchLimit;
509 const commentReportsForm: ListCommentReports = {
513 auth: auth as string,
516 const postReportsForm: ListPostReports = {
520 auth: auth as string,
523 const data: ReportsData = {
524 commentReportsRes: await client.listCommentReports(commentReportsForm),
525 postReportsRes: await client.listPostReports(postReportsForm),
526 messageReportsRes: { state: "empty" },
530 const privateMessageReportsForm: ListPrivateMessageReports = {
534 auth: auth as string,
537 data.messageReportsRes = await client.listPrivateMessageReports(
538 privateMessageReportsForm
546 const unresolved_only = this.state.unreadOrAll == UnreadOrAll.Unread;
547 const page = this.state.page;
548 const limit = fetchLimit;
549 const auth = myAuthRequired();
552 commentReportsRes: { state: "loading" },
553 postReportsRes: { state: "loading" },
554 messageReportsRes: { state: "loading" },
560 | ListPrivateMessageReports = {
568 commentReportsRes: await HttpService.client.listCommentReports(form),
569 postReportsRes: await HttpService.client.listPostReports(form),
574 messageReportsRes: await HttpService.client.listPrivateMessageReports(
581 async handleResolveCommentReport(form: ResolveCommentReport) {
582 const res = await HttpService.client.resolveCommentReport(form);
583 this.findAndUpdateCommentReport(res);
586 async handleResolvePostReport(form: ResolvePostReport) {
587 const res = await HttpService.client.resolvePostReport(form);
588 this.findAndUpdatePostReport(res);
591 async handleResolvePrivateMessageReport(form: ResolvePrivateMessageReport) {
592 const res = await HttpService.client.resolvePrivateMessageReport(form);
593 this.findAndUpdatePrivateMessageReport(res);
596 findAndUpdateCommentReport(res: RequestState<CommentReportResponse>) {
598 if (s.commentReportsRes.state == "success" && res.state == "success") {
599 s.commentReportsRes.data.comment_reports = editCommentReport(
600 res.data.comment_report_view,
601 s.commentReportsRes.data.comment_reports
608 findAndUpdatePostReport(res: RequestState<PostReportResponse>) {
610 if (s.postReportsRes.state == "success" && res.state == "success") {
611 s.postReportsRes.data.post_reports = editPostReport(
612 res.data.post_report_view,
613 s.postReportsRes.data.post_reports
620 findAndUpdatePrivateMessageReport(
621 res: RequestState<PrivateMessageReportResponse>
624 if (s.messageReportsRes.state == "success" && res.state == "success") {
625 s.messageReportsRes.data.private_message_reports =
626 editPrivateMessageReport(
627 res.data.private_message_report_view,
628 s.messageReportsRes.data.private_message_reports