1 import { Component, linkEvent } from "inferno";
7 ListCommentReportsResponse,
9 ListPostReportsResponse,
10 ListPrivateMessageReports,
11 ListPrivateMessageReportsResponse,
14 PrivateMessageReportResponse,
15 PrivateMessageReportView,
19 } from "lemmy-js-client";
20 import { Subscription } from "rxjs";
21 import { i18n } from "../../i18next";
22 import { InitialFetchRequest } from "../../interfaces";
23 import { UserService, WebSocketService } from "../../services";
32 updateCommentReportRes,
34 updatePrivateMessageReportRes,
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";
66 view: CommentReportView | PostReportView | PrivateMessageReportView;
70 interface ReportsState {
71 listCommentReportsResponse?: ListCommentReportsResponse;
72 listPostReportsResponse?: ListPostReportsResponse;
73 listPrivateMessageReportsResponse?: ListPrivateMessageReportsResponse;
74 unreadOrAll: UnreadOrAll;
75 messageType: MessageType;
77 siteRes: GetSiteResponse;
82 export class Reports extends Component<any, ReportsState> {
83 private isoData = setIsoData(this.context);
84 private subscription?: Subscription;
85 state: ReportsState = {
86 unreadOrAll: UnreadOrAll.Unread,
87 messageType: MessageType.All,
90 siteRes: this.isoData.site_res,
94 constructor(props: any, context: any) {
95 super(props, context);
97 this.handlePageChange = this.handlePageChange.bind(this);
99 this.parseMessage = this.parseMessage.bind(this);
100 this.subscription = wsSubscribe(this.parseMessage);
102 // Only fetch the data if coming from another route
103 if (this.isoData.path == this.context.router.route.match.url) {
106 listCommentReportsResponse: this.isoData
107 .routeData[0] as ListCommentReportsResponse,
108 listPostReportsResponse: this.isoData
109 .routeData[1] as ListPostReportsResponse,
114 listPrivateMessageReportsResponse: this.isoData
115 .routeData[2] as ListPrivateMessageReportsResponse,
120 combined: this.buildCombined(),
128 componentWillUnmount() {
130 this.subscription?.unsubscribe();
134 get documentTitle(): string {
135 let 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 {this.state.loading ? (
151 <div className="row">
152 <div className="col-12">
154 title={this.documentTitle}
155 path={this.context.router.route.match.url}
157 <h5 className="mb-2">{i18n.t("reports")}</h5>
159 {this.state.messageType == MessageType.All && this.all()}
160 {this.state.messageType == MessageType.CommentReport &&
161 this.commentReports()}
162 {this.state.messageType == MessageType.PostReport &&
164 {this.state.messageType == MessageType.PrivateMessageReport &&
165 this.privateMessageReports()}
167 page={this.state.page}
168 onChange={this.handlePageChange}
177 unreadOrAllRadios() {
179 <div className="btn-group btn-group-toggle flex-wrap mb-2">
181 className={`btn btn-outline-secondary pointer
182 ${this.state.unreadOrAll == UnreadOrAll.Unread && "active"}
187 value={UnreadOrAll.Unread}
188 checked={this.state.unreadOrAll == UnreadOrAll.Unread}
189 onChange={linkEvent(this, this.handleUnreadOrAllChange)}
194 className={`btn btn-outline-secondary pointer
195 ${this.state.unreadOrAll == UnreadOrAll.All && "active"}
200 value={UnreadOrAll.All}
201 checked={this.state.unreadOrAll == UnreadOrAll.All}
202 onChange={linkEvent(this, this.handleUnreadOrAllChange)}
210 messageTypeRadios() {
212 <div className="btn-group btn-group-toggle flex-wrap mb-2">
214 className={`btn btn-outline-secondary pointer
215 ${this.state.messageType == MessageType.All && "active"}
220 value={MessageType.All}
221 checked={this.state.messageType == MessageType.All}
222 onChange={linkEvent(this, this.handleMessageTypeChange)}
227 className={`btn btn-outline-secondary pointer
228 ${this.state.messageType == MessageType.CommentReport && "active"}
233 value={MessageType.CommentReport}
234 checked={this.state.messageType == MessageType.CommentReport}
235 onChange={linkEvent(this, this.handleMessageTypeChange)}
240 className={`btn btn-outline-secondary pointer
241 ${this.state.messageType == MessageType.PostReport && "active"}
246 value={MessageType.PostReport}
247 checked={this.state.messageType == MessageType.PostReport}
248 onChange={linkEvent(this, this.handleMessageTypeChange)}
254 className={`btn btn-outline-secondary pointer
256 this.state.messageType == MessageType.PrivateMessageReport &&
263 value={MessageType.PrivateMessageReport}
265 this.state.messageType == MessageType.PrivateMessageReport
267 onChange={linkEvent(this, this.handleMessageTypeChange)}
278 <div className="mb-2">
279 <span className="mr-3">{this.unreadOrAllRadios()}</span>
280 <span className="mr-3">{this.messageTypeRadios()}</span>
285 commentReportToItemType(r: CommentReportView): ItemType {
287 id: r.comment_report.id,
288 type_: MessageEnum.CommentReport,
290 published: r.comment_report.published,
294 postReportToItemType(r: PostReportView): ItemType {
296 id: r.post_report.id,
297 type_: MessageEnum.PostReport,
299 published: r.post_report.published,
303 privateMessageReportToItemType(r: PrivateMessageReportView): ItemType {
305 id: r.private_message_report.id,
306 type_: MessageEnum.PrivateMessageReport,
308 published: r.private_message_report.published,
312 buildCombined(): ItemType[] {
313 // let comments: ItemType[] = this.state.listCommentReportsResponse
314 // .map(r => r.comment_reports)
316 // .map(r => this.commentReportToItemType(r));
318 this.state.listCommentReportsResponse?.comment_reports.map(
319 this.commentReportToItemType
322 this.state.listPostReportsResponse?.post_reports.map(
323 this.postReportToItemType
325 let privateMessages =
326 this.state.listPrivateMessageReportsResponse?.private_message_reports.map(
327 this.privateMessageReportToItemType
330 return [...comments, ...posts, ...privateMessages].sort((a, b) =>
331 b.published.localeCompare(a.published)
335 renderItemType(i: ItemType) {
337 case MessageEnum.CommentReport:
339 <CommentReport key={i.id} report={i.view as CommentReportView} />
341 case MessageEnum.PostReport:
342 return <PostReport key={i.id} report={i.view as PostReportView} />;
343 case MessageEnum.PrivateMessageReport:
345 <PrivateMessageReport
347 report={i.view as PrivateMessageReportView}
358 {this.state.combined.map(i => (
361 {this.renderItemType(i)}
369 let reports = this.state.listCommentReportsResponse?.comment_reports;
376 <CommentReport key={cr.comment_report.id} report={cr} />
385 let reports = this.state.listPostReportsResponse?.post_reports;
392 <PostReport key={pr.post_report.id} report={pr} />
400 privateMessageReports() {
402 this.state.listPrivateMessageReportsResponse?.private_message_reports;
406 {reports.map(pmr => (
409 <PrivateMessageReport
410 key={pmr.private_message_report.id}
420 handlePageChange(page: bigint) {
421 this.setState({ page });
425 handleUnreadOrAllChange(i: Reports, event: any) {
426 i.setState({ unreadOrAll: Number(event.target.value), page: 1n });
430 handleMessageTypeChange(i: Reports, event: any) {
431 i.setState({ messageType: Number(event.target.value), page: 1n });
435 static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
436 let promises: Promise<any>[] = [];
438 let unresolved_only = true;
440 let limit = fetchLimit;
444 let commentReportsForm: ListCommentReports = {
450 promises.push(req.client.listCommentReports(commentReportsForm));
452 let postReportsForm: ListPostReports = {
458 promises.push(req.client.listPostReports(postReportsForm));
461 let privateMessageReportsForm: ListPrivateMessageReports = {
468 req.client.listPrivateMessageReports(privateMessageReportsForm)
477 let unresolved_only = this.state.unreadOrAll == UnreadOrAll.Unread;
478 let page = this.state.page;
479 let limit = fetchLimit;
482 let commentReportsForm: ListCommentReports = {
488 WebSocketService.Instance.send(
489 wsClient.listCommentReports(commentReportsForm)
492 let postReportsForm: ListPostReports = {
498 WebSocketService.Instance.send(wsClient.listPostReports(postReportsForm));
501 let privateMessageReportsForm: ListPrivateMessageReports = {
507 WebSocketService.Instance.send(
508 wsClient.listPrivateMessageReports(privateMessageReportsForm)
514 parseMessage(msg: any) {
515 let op = wsUserOp(msg);
518 toast(i18n.t(msg.error), "danger");
520 } else if (msg.reconnect) {
522 } else if (op == UserOperation.ListCommentReports) {
523 let data = wsJsonToRes<ListCommentReportsResponse>(msg);
524 this.setState({ listCommentReportsResponse: data });
525 this.setState({ combined: this.buildCombined(), loading: false });
526 // this.sendUnreadCount();
527 window.scrollTo(0, 0);
529 } else if (op == UserOperation.ListPostReports) {
530 let data = wsJsonToRes<ListPostReportsResponse>(msg);
531 this.setState({ listPostReportsResponse: data });
532 this.setState({ combined: this.buildCombined(), loading: false });
533 // this.sendUnreadCount();
534 window.scrollTo(0, 0);
536 } else if (op == UserOperation.ListPrivateMessageReports) {
537 let data = wsJsonToRes<ListPrivateMessageReportsResponse>(msg);
538 this.setState({ listPrivateMessageReportsResponse: data });
539 this.setState({ combined: this.buildCombined(), loading: false });
540 // this.sendUnreadCount();
541 window.scrollTo(0, 0);
543 } else if (op == UserOperation.ResolvePostReport) {
544 let data = wsJsonToRes<PostReportResponse>(msg);
546 data.post_report_view,
547 this.state.listPostReportsResponse?.post_reports
549 let urcs = UserService.Instance.unreadReportCountSub;
550 if (data.post_report_view.post_report.resolved) {
551 urcs.next(urcs.getValue() - 1n);
553 urcs.next(urcs.getValue() + 1n);
555 this.setState(this.state);
556 } else if (op == UserOperation.ResolveCommentReport) {
557 let data = wsJsonToRes<CommentReportResponse>(msg);
558 updateCommentReportRes(
559 data.comment_report_view,
560 this.state.listCommentReportsResponse?.comment_reports
562 let urcs = UserService.Instance.unreadReportCountSub;
563 if (data.comment_report_view.comment_report.resolved) {
564 urcs.next(urcs.getValue() - 1n);
566 urcs.next(urcs.getValue() + 1n);
568 this.setState(this.state);
569 } else if (op == UserOperation.ResolvePrivateMessageReport) {
570 let data = wsJsonToRes<PrivateMessageReportResponse>(msg);
571 updatePrivateMessageReportRes(
572 data.private_message_report_view,
573 this.state.listPrivateMessageReportsResponse?.private_message_reports
575 let urcs = UserService.Instance.unreadReportCountSub;
576 if (data.private_message_report_view.private_message_report.resolved) {
577 urcs.next(urcs.getValue() - 1n);
579 urcs.next(urcs.getValue() + 1n);
581 this.setState(this.state);