1 import { None, Option, Some } from "@sniptt/monads";
2 import { Component, linkEvent } from "inferno";
8 ListCommentReportsResponse,
10 ListPostReportsResponse,
11 ListPrivateMessageReports,
12 ListPrivateMessageReportsResponse,
15 PrivateMessageReportResponse,
16 PrivateMessageReportView,
20 } from "lemmy-js-client";
21 import { Subscription } from "rxjs";
22 import { i18n } from "../../i18next";
23 import { InitialFetchRequest } from "../../interfaces";
24 import { UserService, WebSocketService } from "../../services";
33 updateCommentReportRes,
35 updatePrivateMessageReportRes,
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";
67 view: CommentReportView | PostReportView | PrivateMessageReportView;
71 interface ReportsState {
72 listCommentReportsResponse: Option<ListCommentReportsResponse>;
73 listPostReportsResponse: Option<ListPostReportsResponse>;
74 listPrivateMessageReportsResponse: Option<ListPrivateMessageReportsResponse>;
75 unreadOrAll: UnreadOrAll;
76 messageType: MessageType;
78 siteRes: GetSiteResponse;
83 export class Reports extends Component<any, ReportsState> {
84 private isoData = setIsoData(
86 ListCommentReportsResponse,
87 ListPostReportsResponse,
88 ListPrivateMessageReportsResponse
90 private subscription: Subscription;
91 private emptyState: ReportsState = {
92 listCommentReportsResponse: None,
93 listPostReportsResponse: None,
94 listPrivateMessageReportsResponse: None,
95 unreadOrAll: UnreadOrAll.Unread,
96 messageType: MessageType.All,
99 siteRes: this.isoData.site_res,
103 constructor(props: any, context: any) {
104 super(props, context);
106 this.state = this.emptyState;
107 this.handlePageChange = this.handlePageChange.bind(this);
109 if (UserService.Instance.myUserInfo.isNone() && isBrowser()) {
110 toast(i18n.t("not_logged_in"), "danger");
111 this.context.router.history.push(`/login`);
114 this.parseMessage = this.parseMessage.bind(this);
115 this.subscription = wsSubscribe(this.parseMessage);
117 // Only fetch the data if coming from another route
118 if (this.isoData.path == this.context.router.route.match.url) {
121 listCommentReportsResponse: Some(
122 this.isoData.routeData[0] as ListCommentReportsResponse
124 listPostReportsResponse: Some(
125 this.isoData.routeData[1] as ListPostReportsResponse
131 listPrivateMessageReportsResponse: Some(
132 this.isoData.routeData[2] as ListPrivateMessageReportsResponse
138 combined: this.buildCombined(),
146 componentWillUnmount() {
148 this.subscription.unsubscribe();
152 get documentTitle(): string {
153 return this.state.siteRes.site_view.match({
155 UserService.Instance.myUserInfo.match({
157 `@${mui.local_user_view.person.name} ${i18n.t("reports")} - ${
168 <div className="container-lg">
169 {this.state.loading ? (
174 <div className="row">
175 <div className="col-12">
177 title={this.documentTitle}
178 path={this.context.router.route.match.url}
182 <h5 className="mb-2">{i18n.t("reports")}</h5>
184 {this.state.messageType == MessageType.All && this.all()}
185 {this.state.messageType == MessageType.CommentReport &&
186 this.commentReports()}
187 {this.state.messageType == MessageType.PostReport &&
189 {this.state.messageType == MessageType.PrivateMessageReport &&
190 this.privateMessageReports()}
192 page={this.state.page}
193 onChange={this.handlePageChange}
202 unreadOrAllRadios() {
204 <div className="btn-group btn-group-toggle flex-wrap mb-2">
206 className={`btn btn-outline-secondary pointer
207 ${this.state.unreadOrAll == UnreadOrAll.Unread && "active"}
212 value={UnreadOrAll.Unread}
213 checked={this.state.unreadOrAll == UnreadOrAll.Unread}
214 onChange={linkEvent(this, this.handleUnreadOrAllChange)}
219 className={`btn btn-outline-secondary pointer
220 ${this.state.unreadOrAll == UnreadOrAll.All && "active"}
225 value={UnreadOrAll.All}
226 checked={this.state.unreadOrAll == UnreadOrAll.All}
227 onChange={linkEvent(this, this.handleUnreadOrAllChange)}
235 messageTypeRadios() {
237 <div className="btn-group btn-group-toggle flex-wrap mb-2">
239 className={`btn btn-outline-secondary pointer
240 ${this.state.messageType == MessageType.All && "active"}
245 value={MessageType.All}
246 checked={this.state.messageType == MessageType.All}
247 onChange={linkEvent(this, this.handleMessageTypeChange)}
252 className={`btn btn-outline-secondary pointer
253 ${this.state.messageType == MessageType.CommentReport && "active"}
258 value={MessageType.CommentReport}
259 checked={this.state.messageType == MessageType.CommentReport}
260 onChange={linkEvent(this, this.handleMessageTypeChange)}
265 className={`btn btn-outline-secondary pointer
266 ${this.state.messageType == MessageType.PostReport && "active"}
271 value={MessageType.PostReport}
272 checked={this.state.messageType == MessageType.PostReport}
273 onChange={linkEvent(this, this.handleMessageTypeChange)}
279 className={`btn btn-outline-secondary pointer
281 this.state.messageType == MessageType.PrivateMessageReport &&
288 value={MessageType.PrivateMessageReport}
290 this.state.messageType == MessageType.PrivateMessageReport
292 onChange={linkEvent(this, this.handleMessageTypeChange)}
303 <div className="mb-2">
304 <span className="mr-3">{this.unreadOrAllRadios()}</span>
305 <span className="mr-3">{this.messageTypeRadios()}</span>
310 commentReportToItemType(r: CommentReportView): ItemType {
312 id: r.comment_report.id,
313 type_: MessageEnum.CommentReport,
315 published: r.comment_report.published,
319 postReportToItemType(r: PostReportView): ItemType {
321 id: r.post_report.id,
322 type_: MessageEnum.PostReport,
324 published: r.post_report.published,
328 privateMessageReportToItemType(r: PrivateMessageReportView): ItemType {
330 id: r.private_message_report.id,
331 type_: MessageEnum.PrivateMessageReport,
333 published: r.private_message_report.published,
337 buildCombined(): ItemType[] {
338 let comments: ItemType[] = this.state.listCommentReportsResponse
339 .map(r => r.comment_reports)
341 .map(r => this.commentReportToItemType(r));
342 let posts: ItemType[] = this.state.listPostReportsResponse
343 .map(r => r.post_reports)
345 .map(r => this.postReportToItemType(r));
346 let privateMessages: ItemType[] =
347 this.state.listPrivateMessageReportsResponse
348 .map(r => r.private_message_reports)
350 .map(r => this.privateMessageReportToItemType(r));
352 return [...comments, ...posts, ...privateMessages].sort((a, b) =>
353 b.published.localeCompare(a.published)
357 renderItemType(i: ItemType) {
359 case MessageEnum.CommentReport:
361 <CommentReport key={i.id} report={i.view as CommentReportView} />
363 case MessageEnum.PostReport:
364 return <PostReport key={i.id} report={i.view as PostReportView} />;
365 case MessageEnum.PrivateMessageReport:
367 <PrivateMessageReport
369 report={i.view as PrivateMessageReportView}
380 {this.state.combined.map(i => (
383 {this.renderItemType(i)}
391 return this.state.listCommentReportsResponse.match({
394 {res.comment_reports.map(cr => (
397 <CommentReport key={cr.comment_report.id} report={cr} />
407 return this.state.listPostReportsResponse.match({
410 {res.post_reports.map(pr => (
413 <PostReport key={pr.post_report.id} report={pr} />
422 privateMessageReports() {
423 return this.state.listPrivateMessageReportsResponse.match({
426 {res.private_message_reports.map(pmr => (
429 <PrivateMessageReport
430 key={pmr.private_message_report.id}
441 handlePageChange(page: number) {
442 this.setState({ page });
446 handleUnreadOrAllChange(i: Reports, event: any) {
447 i.setState({ unreadOrAll: Number(event.target.value), page: 1 });
451 handleMessageTypeChange(i: Reports, event: any) {
452 i.setState({ messageType: Number(event.target.value), page: 1 });
456 static fetchInitialData(req: InitialFetchRequest): Promise<any>[] {
457 let promises: Promise<any>[] = [];
459 let unresolved_only = Some(true);
461 let limit = Some(fetchLimit);
462 let community_id = None;
463 let auth = req.auth.unwrap();
465 let commentReportsForm = new ListCommentReports({
473 promises.push(req.client.listCommentReports(commentReportsForm));
475 let postReportsForm = new ListPostReports({
483 promises.push(req.client.listPostReports(postReportsForm));
486 let privateMessageReportsForm = new ListPrivateMessageReports({
493 req.client.listPrivateMessageReports(privateMessageReportsForm)
501 let unresolved_only = Some(this.state.unreadOrAll == UnreadOrAll.Unread);
502 let community_id = None;
503 let page = Some(this.state.page);
504 let limit = Some(fetchLimit);
506 let commentReportsForm = new ListCommentReports({
512 auth: auth().unwrap(),
514 WebSocketService.Instance.send(
515 wsClient.listCommentReports(commentReportsForm)
518 let postReportsForm = new ListPostReports({
524 auth: auth().unwrap(),
526 WebSocketService.Instance.send(wsClient.listPostReports(postReportsForm));
529 let privateMessageReportsForm = new ListPrivateMessageReports({
533 auth: auth().unwrap(),
535 WebSocketService.Instance.send(
536 wsClient.listPrivateMessageReports(privateMessageReportsForm)
541 parseMessage(msg: any) {
542 let op = wsUserOp(msg);
545 toast(i18n.t(msg.error), "danger");
547 } else if (msg.reconnect) {
549 } else if (op == UserOperation.ListCommentReports) {
550 let data = wsJsonToRes<ListCommentReportsResponse>(
552 ListCommentReportsResponse
554 this.setState({ listCommentReportsResponse: Some(data) });
555 this.setState({ combined: this.buildCombined(), loading: false });
556 // this.sendUnreadCount();
557 window.scrollTo(0, 0);
559 } else if (op == UserOperation.ListPostReports) {
560 let data = wsJsonToRes<ListPostReportsResponse>(
562 ListPostReportsResponse
564 this.setState({ listPostReportsResponse: Some(data) });
565 this.setState({ combined: this.buildCombined(), loading: false });
566 // this.sendUnreadCount();
567 window.scrollTo(0, 0);
569 } else if (op == UserOperation.ListPrivateMessageReports) {
570 let data = wsJsonToRes<ListPrivateMessageReportsResponse>(
572 ListPrivateMessageReportsResponse
574 this.setState({ listPrivateMessageReportsResponse: Some(data) });
575 this.setState({ combined: this.buildCombined(), loading: false });
576 // this.sendUnreadCount();
577 window.scrollTo(0, 0);
579 } else if (op == UserOperation.ResolvePostReport) {
580 let data = wsJsonToRes<PostReportResponse>(msg, PostReportResponse);
582 data.post_report_view,
583 this.state.listPostReportsResponse.map(r => r.post_reports).unwrapOr([])
585 let urcs = UserService.Instance.unreadReportCountSub;
586 if (data.post_report_view.post_report.resolved) {
587 urcs.next(urcs.getValue() - 1);
589 urcs.next(urcs.getValue() + 1);
591 this.setState(this.state);
592 } else if (op == UserOperation.ResolveCommentReport) {
593 let data = wsJsonToRes<CommentReportResponse>(msg, CommentReportResponse);
594 updateCommentReportRes(
595 data.comment_report_view,
596 this.state.listCommentReportsResponse
597 .map(r => r.comment_reports)
600 let urcs = UserService.Instance.unreadReportCountSub;
601 if (data.comment_report_view.comment_report.resolved) {
602 urcs.next(urcs.getValue() - 1);
604 urcs.next(urcs.getValue() + 1);
606 this.setState(this.state);
607 } else if (op == UserOperation.ResolvePrivateMessageReport) {
608 let data = wsJsonToRes<PrivateMessageReportResponse>(
610 PrivateMessageReportResponse
612 updatePrivateMessageReportRes(
613 data.private_message_report_view,
614 this.state.listPrivateMessageReportsResponse
615 .map(r => r.private_message_reports)
618 let urcs = UserService.Instance.unreadReportCountSub;
619 if (data.private_message_report_view.private_message_report.resolved) {
620 urcs.next(urcs.getValue() - 1);
622 urcs.next(urcs.getValue() + 1);
624 this.setState(this.state);