From: Dessalines Date: Tue, 28 Sep 2021 10:38:59 +0000 (-0400) Subject: Reporting (#434) X-Git-Url: http://these/git/%7B%60%24%7BarchiveTodayUrl%7D/%7B%60/feeds/inbox/%24%7BUserService.Instance.auth%7D.xml%60%7D?a=commitdiff_plain;h=06099fee8acaaf0a137eb0bc45c68ad0c16b6476;p=lemmy-ui.git Reporting (#434) * Updating translations. * A first pass at reporting. Fixes #102 --- diff --git a/lemmy-translations b/lemmy-translations index 7dd7b98..9a584ef 160000 --- a/lemmy-translations +++ b/lemmy-translations @@ -1 +1 @@ -Subproject commit 7dd7b98da76477222f9fd9720b4b25e14e3ddc97 +Subproject commit 9a584ef77e7861466bd5f44dd87d3681d4871a60 diff --git a/package.json b/package.json index c273861..35124b7 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "husky": "^7.0.1", "import-sort-style-module": "^6.0.0", "iso-639-1": "^2.1.9", - "lemmy-js-client": "0.12.0", + "lemmy-js-client": "0.12.3-rc.5", "lint-staged": "^11.0.1", "mini-css-extract-plugin": "^2.1.0", "node-fetch": "^2.6.1", diff --git a/src/shared/components/app/navbar.tsx b/src/shared/components/app/navbar.tsx index 50bf5fa..865b72d 100644 --- a/src/shared/components/app/navbar.tsx +++ b/src/shared/components/app/navbar.tsx @@ -8,6 +8,8 @@ import { GetPrivateMessages, GetReplies, GetRepliesResponse, + GetReportCount, + GetReportCountResponse, GetSiteResponse, PrivateMessageResponse, PrivateMessagesResponse, @@ -48,7 +50,8 @@ interface NavbarState { replies: CommentView[]; mentions: CommentView[]; messages: PrivateMessageView[]; - unreadCount: number; + unreadInboxCount: number; + unreadReportCount: number; searchParam: string; toggleSearch: boolean; showDropdown: boolean; @@ -58,11 +61,13 @@ interface NavbarState { export class Navbar extends Component { private wsSub: Subscription; private userSub: Subscription; - private unreadCountSub: Subscription; + private unreadInboxCountSub: Subscription; + private unreadReportCountSub: Subscription; private searchTextField: RefObject; emptyState: NavbarState = { isLoggedIn: !!this.props.site_res.my_user, - unreadCount: 0, + unreadInboxCount: 0, + unreadReportCount: 0, replies: [], mentions: [], messages: [], @@ -117,18 +122,23 @@ export class Navbar extends Component { }); // Subscribe to unread count changes - this.unreadCountSub = UserService.Instance.unreadCountSub.subscribe( - res => { - this.setState({ unreadCount: res }); - } - ); + this.unreadInboxCountSub = + UserService.Instance.unreadInboxCountSub.subscribe(res => { + this.setState({ unreadInboxCount: res }); + }); + // Subscribe to unread report count changes + this.unreadReportCountSub = + UserService.Instance.unreadReportCountSub.subscribe(res => { + this.setState({ unreadReportCount: res }); + }); } } componentWillUnmount() { this.wsSub.unsubscribe(); this.userSub.unsubscribe(); - this.unreadCountSub.unsubscribe(); + this.unreadInboxCountSub.unsubscribe(); + this.unreadReportCountSub.unsubscribe(); } updateUrl() { @@ -177,23 +187,48 @@ export class Navbar extends Component { )} {this.state.isLoggedIn && ( - + + + {UserService.Instance.myUserInfo?.moderates.length > 0 && ( + )} - + )} + )} + {this.state.showReportDialog && ( +
+ + + +
+ )} {this.state.showBanDialog && (
@@ -1043,6 +1087,29 @@ export class CommentNode extends Component { setupTippy(); } + handleShowReportDialog(i: CommentNode) { + i.state.showReportDialog = !i.state.showReportDialog; + i.setState(i.state); + } + + handleReportReasonChange(i: CommentNode, event: any) { + i.state.reportReason = event.target.value; + i.setState(i.state); + } + + handleReportSubmit(i: CommentNode) { + let comment = i.props.node.comment_view.comment; + let form: CreateCommentReport = { + comment_id: comment.id, + reason: i.state.reportReason, + auth: authField(), + }; + WebSocketService.Instance.send(wsClient.createCommentReport(form)); + + i.state.showReportDialog = false; + i.setState(i.state); + } + handleModRemoveShow(i: CommentNode) { i.state.showRemoveDialog = true; i.setState(i.state); diff --git a/src/shared/components/comment/comment_report.tsx b/src/shared/components/comment/comment_report.tsx new file mode 100644 index 0000000..87f6ebc --- /dev/null +++ b/src/shared/components/comment/comment_report.tsx @@ -0,0 +1,107 @@ +import { Component, linkEvent } from "inferno"; +import { T } from "inferno-i18next-dess"; +import { + CommentReportView, + CommentView, + ResolveCommentReport, +} from "lemmy-js-client"; +import { i18n } from "../../i18next"; +import { CommentNode as CommentNodeI } from "../../interfaces"; +import { WebSocketService } from "../../services"; +import { authField, wsClient } from "../../utils"; +import { Icon } from "../common/icon"; +import { PersonListing } from "../person/person-listing"; +import { CommentNode } from "./comment-node"; + +interface CommentReportProps { + report: CommentReportView; +} + +export class CommentReport extends Component { + constructor(props: any, context: any) { + super(props, context); + } + + render() { + let r = this.props.report; + let comment = r.comment; + + // Set the original post data ( a troll could change it ) + comment.content = r.comment_report.original_comment_text; + + let comment_view: CommentView = { + comment, + creator: r.comment_creator, + post: r.post, + community: r.community, + creator_banned_from_community: r.creator_banned_from_community, + counts: r.counts, + subscribed: false, + saved: false, + creator_blocked: false, + my_vote: r.my_vote, + }; + + let node: CommentNodeI = { + comment_view, + }; + + return ( +
+ +
+ {i18n.t("reporter")}: +
+
+ {i18n.t("reason")}: {r.comment_report.reason} +
+ {r.resolver && ( +
+ {r.comment_report.resolved ? ( + + # + + + ) : ( + + # + + + )} +
+ )} + +
+ ); + } + + handleResolveReport(i: CommentReport) { + let form: ResolveCommentReport = { + report_id: i.props.report.comment_report.id, + resolved: !i.props.report.comment_report.resolved, + auth: authField(), + }; + WebSocketService.Instance.send(wsClient.resolveCommentReport(form)); + } +} diff --git a/src/shared/components/common/symbols.tsx b/src/shared/components/common/symbols.tsx index f94bc55..2035d3c 100644 --- a/src/shared/components/common/symbols.tsx +++ b/src/shared/components/common/symbols.tsx @@ -12,6 +12,12 @@ export const SYMBOLS = ( xmlnsXlink="http://www.w3.org/1999/xlink" > + + + + + + diff --git a/src/shared/components/community/community.tsx b/src/shared/components/community/community.tsx index e342085..1d77d44 100644 --- a/src/shared/components/community/community.tsx +++ b/src/shared/components/community/community.tsx @@ -3,6 +3,7 @@ import { AddModToCommunityResponse, BanFromCommunityResponse, BlockPersonResponse, + CommentReportResponse, CommentResponse, CommentView, CommunityResponse, @@ -14,6 +15,7 @@ import { GetPostsResponse, GetSiteResponse, ListingType, + PostReportResponse, PostResponse, PostView, SortType, @@ -549,6 +551,16 @@ export class Community extends Component { } else if (op == UserOperation.BlockPerson) { let data = wsJsonToRes(msg).data; updatePersonBlock(data); + } else if (op == UserOperation.CreatePostReport) { + let data = wsJsonToRes(msg).data; + if (data) { + toast(i18n.t("report_created")); + } + } else if (op == UserOperation.CreateCommentReport) { + let data = wsJsonToRes(msg).data; + if (data) { + toast(i18n.t("report_created")); + } } } } diff --git a/src/shared/components/home/home.tsx b/src/shared/components/home/home.tsx index ec581c0..a1793ae 100644 --- a/src/shared/components/home/home.tsx +++ b/src/shared/components/home/home.tsx @@ -5,6 +5,7 @@ import { AddAdminResponse, BanPersonResponse, BlockPersonResponse, + CommentReportResponse, CommentResponse, CommentView, CommunityView, @@ -16,6 +17,7 @@ import { ListCommunities, ListCommunitiesResponse, ListingType, + PostReportResponse, PostResponse, PostView, SiteResponse, @@ -955,6 +957,16 @@ export class Home extends Component { } else if (op == UserOperation.BlockPerson) { let data = wsJsonToRes(msg).data; updatePersonBlock(data); + } else if (op == UserOperation.CreatePostReport) { + let data = wsJsonToRes(msg).data; + if (data) { + toast(i18n.t("report_created")); + } + } else if (op == UserOperation.CreateCommentReport) { + let data = wsJsonToRes(msg).data; + if (data) { + toast(i18n.t("report_created")); + } } } } diff --git a/src/shared/components/person/inbox.tsx b/src/shared/components/person/inbox.tsx index c18dafa..05b75ec 100644 --- a/src/shared/components/person/inbox.tsx +++ b/src/shared/components/person/inbox.tsx @@ -1,6 +1,7 @@ import { Component, linkEvent } from "inferno"; import { BlockPersonResponse, + CommentReportResponse, CommentResponse, CommentView, GetPersonMentions, @@ -10,6 +11,7 @@ import { GetRepliesResponse, PersonMentionResponse, PersonMentionView, + PostReportResponse, PrivateMessageResponse, PrivateMessagesResponse, PrivateMessageView, @@ -761,11 +763,21 @@ export class Inbox extends Component { } else if (op == UserOperation.BlockPerson) { let data = wsJsonToRes(msg).data; updatePersonBlock(data); + } else if (op == UserOperation.CreatePostReport) { + let data = wsJsonToRes(msg).data; + if (data) { + toast(i18n.t("report_created")); + } + } else if (op == UserOperation.CreateCommentReport) { + let data = wsJsonToRes(msg).data; + if (data) { + toast(i18n.t("report_created")); + } } } sendUnreadCount() { - UserService.Instance.unreadCountSub.next(this.unreadCount()); + UserService.Instance.unreadInboxCountSub.next(this.unreadCount()); } unreadCount(): number { diff --git a/src/shared/components/person/reports.tsx b/src/shared/components/person/reports.tsx new file mode 100644 index 0000000..2c83ff2 --- /dev/null +++ b/src/shared/components/person/reports.tsx @@ -0,0 +1,444 @@ +import { Component, linkEvent } from "inferno"; +import { + CommentReportResponse, + CommentReportView, + ListCommentReports, + ListCommentReportsResponse, + ListPostReports, + ListPostReportsResponse, + PostReportResponse, + PostReportView, + SiteView, + UserOperation, +} from "lemmy-js-client"; +import { Subscription } from "rxjs"; +import { i18n } from "../../i18next"; +import { InitialFetchRequest } from "../../interfaces"; +import { UserService, WebSocketService } from "../../services"; +import { + authField, + fetchLimit, + isBrowser, + setIsoData, + setupTippy, + toast, + updateCommentReportRes, + updatePostReportRes, + wsClient, + wsJsonToRes, + wsSubscribe, + wsUserOp, +} from "../../utils"; +import { CommentReport } from "../comment/comment_report"; +import { HtmlTags } from "../common/html-tags"; +import { Spinner } from "../common/icon"; +import { Paginator } from "../common/paginator"; +import { PostReport } from "../post/post_report"; + +enum UnreadOrAll { + Unread, + All, +} + +enum MessageType { + All, + CommentReport, + PostReport, +} + +enum MessageEnum { + CommentReport, + PostReport, +} + +type ItemType = { + id: number; + type_: MessageEnum; + view: CommentReportView | PostReportView; + published: string; +}; + +interface ReportsState { + unreadOrAll: UnreadOrAll; + messageType: MessageType; + commentReports: CommentReportView[]; + postReports: PostReportView[]; + combined: ItemType[]; + page: number; + site_view: SiteView; + loading: boolean; +} + +export class Reports extends Component { + private isoData = setIsoData(this.context); + private subscription: Subscription; + private emptyState: ReportsState = { + unreadOrAll: UnreadOrAll.Unread, + messageType: MessageType.All, + commentReports: [], + postReports: [], + combined: [], + page: 1, + site_view: this.isoData.site_res.site_view, + loading: true, + }; + + constructor(props: any, context: any) { + super(props, context); + + this.state = this.emptyState; + this.handlePageChange = this.handlePageChange.bind(this); + + if (!UserService.Instance.myUserInfo && isBrowser()) { + toast(i18n.t("not_logged_in"), "danger"); + this.context.router.history.push(`/login`); + } + + this.parseMessage = this.parseMessage.bind(this); + this.subscription = wsSubscribe(this.parseMessage); + + // Only fetch the data if coming from another route + if (this.isoData.path == this.context.router.route.match.url) { + this.state.commentReports = + this.isoData.routeData[0].comment_reports || []; + this.state.postReports = this.isoData.routeData[1].post_reports || []; + this.state.combined = this.buildCombined(); + this.state.loading = false; + } else { + this.refetch(); + } + } + + componentWillUnmount() { + if (isBrowser()) { + this.subscription.unsubscribe(); + } + } + + get documentTitle(): string { + return `@${ + UserService.Instance.myUserInfo.local_user_view.person.name + } ${i18n.t("reports")} - ${this.state.site_view.site.name}`; + } + + render() { + return ( +
+ {this.state.loading ? ( +
+ +
+ ) : ( +
+
+ +
{i18n.t("reports")}
+ {this.selects()} + {this.state.messageType == MessageType.All && this.all()} + {this.state.messageType == MessageType.CommentReport && + this.commentReports()} + {this.state.messageType == MessageType.PostReport && + this.postReports()} + +
+
+ )} +
+ ); + } + + unreadOrAllRadios() { + return ( +
+ + +
+ ); + } + + messageTypeRadios() { + return ( +
+ + + +
+ ); + } + + selects() { + return ( +
+ {this.unreadOrAllRadios()} + {this.messageTypeRadios()} +
+ ); + } + + replyToReplyType(r: CommentReportView): ItemType { + return { + id: r.comment_report.id, + type_: MessageEnum.CommentReport, + view: r, + published: r.comment_report.published, + }; + } + + mentionToReplyType(r: PostReportView): ItemType { + return { + id: r.post_report.id, + type_: MessageEnum.PostReport, + view: r, + published: r.post_report.published, + }; + } + + buildCombined(): ItemType[] { + let comments: ItemType[] = this.state.commentReports.map(r => + this.replyToReplyType(r) + ); + let posts: ItemType[] = this.state.postReports.map(r => + this.mentionToReplyType(r) + ); + + return [...comments, ...posts].sort((a, b) => + b.published.localeCompare(a.published) + ); + } + + renderItemType(i: ItemType) { + switch (i.type_) { + case MessageEnum.CommentReport: + return ( + + ); + case MessageEnum.PostReport: + return ; + default: + return
; + } + } + + all() { + return ( +
+ {this.state.combined.map(i => ( + <> +
+ {this.renderItemType(i)} + + ))} +
+ ); + } + + commentReports() { + return ( +
+ {this.state.commentReports.map(cr => ( + <> +
+ + + ))} +
+ ); + } + + postReports() { + return ( +
+ {this.state.postReports.map(pr => ( + <> +
+ + + ))} +
+ ); + } + + handlePageChange(page: number) { + this.setState({ page }); + this.refetch(); + } + + handleUnreadOrAllChange(i: Reports, event: any) { + i.state.unreadOrAll = Number(event.target.value); + i.state.page = 1; + i.setState(i.state); + i.refetch(); + } + + handleMessageTypeChange(i: Reports, event: any) { + i.state.messageType = Number(event.target.value); + i.state.page = 1; + i.setState(i.state); + i.refetch(); + } + + static fetchInitialData(req: InitialFetchRequest): Promise[] { + let promises: Promise[] = []; + + let commentReportsForm: ListCommentReports = { + // TODO community_id + unresolved_only: true, + page: 1, + limit: fetchLimit, + auth: req.auth, + }; + promises.push(req.client.listCommentReports(commentReportsForm)); + + let postReportsForm: ListPostReports = { + // TODO community_id + unresolved_only: true, + page: 1, + limit: fetchLimit, + auth: req.auth, + }; + promises.push(req.client.listPostReports(postReportsForm)); + + return promises; + } + + refetch() { + let unresolved_only = this.state.unreadOrAll == UnreadOrAll.Unread; + let commentReportsForm: ListCommentReports = { + // TODO community_id + unresolved_only, + page: this.state.page, + limit: fetchLimit, + auth: authField(), + }; + WebSocketService.Instance.send( + wsClient.listCommentReports(commentReportsForm) + ); + + let postReportsForm: ListPostReports = { + // TODO community_id + unresolved_only, + page: this.state.page, + limit: fetchLimit, + auth: authField(), + }; + WebSocketService.Instance.send(wsClient.listPostReports(postReportsForm)); + } + + parseMessage(msg: any) { + let op = wsUserOp(msg); + console.log(msg); + if (msg.error) { + toast(i18n.t(msg.error), "danger"); + return; + } else if (msg.reconnect) { + this.refetch(); + } else if (op == UserOperation.ListCommentReports) { + let data = wsJsonToRes(msg).data; + this.state.commentReports = data.comment_reports; + this.state.combined = this.buildCombined(); + this.state.loading = false; + // this.sendUnreadCount(); + window.scrollTo(0, 0); + this.setState(this.state); + setupTippy(); + } else if (op == UserOperation.ListPostReports) { + let data = wsJsonToRes(msg).data; + this.state.postReports = data.post_reports; + this.state.combined = this.buildCombined(); + this.state.loading = false; + // this.sendUnreadCount(); + window.scrollTo(0, 0); + this.setState(this.state); + setupTippy(); + } else if (op == UserOperation.ResolvePostReport) { + let data = wsJsonToRes(msg).data; + updatePostReportRes(data.post_report_view, this.state.postReports); + let urcs = UserService.Instance.unreadReportCountSub; + if (data.post_report_view.post_report.resolved) { + urcs.next(urcs.getValue() - 1); + } else { + urcs.next(urcs.getValue() + 1); + } + this.setState(this.state); + } else if (op == UserOperation.ResolveCommentReport) { + let data = wsJsonToRes(msg).data; + updateCommentReportRes( + data.comment_report_view, + this.state.commentReports + ); + let urcs = UserService.Instance.unreadReportCountSub; + if (data.comment_report_view.comment_report.resolved) { + urcs.next(urcs.getValue() - 1); + } else { + urcs.next(urcs.getValue() + 1); + } + this.setState(this.state); + } + } +} diff --git a/src/shared/components/post/post-listing.tsx b/src/shared/components/post/post-listing.tsx index b2e1f7e..d61c690 100644 --- a/src/shared/components/post/post-listing.tsx +++ b/src/shared/components/post/post-listing.tsx @@ -8,6 +8,7 @@ import { BlockPerson, CommunityModeratorView, CreatePostLike, + CreatePostReport, DeletePost, LockPost, PersonViewSafe, @@ -62,6 +63,8 @@ interface PostListingState { showAdvanced: boolean; showMoreMobile: boolean; showBody: boolean; + showReportDialog: boolean; + reportReason: string; my_vote: number; score: number; upvotes: number; @@ -96,6 +99,8 @@ export class PostListing extends Component { showAdvanced: false, showMoreMobile: false, showBody: false, + showReportDialog: false, + reportReason: null, my_vote: this.props.post_view.my_vote, score: this.props.post_view.counts.score, upvotes: this.props.post_view.counts.upvotes, @@ -664,14 +669,24 @@ export class PostListing extends Component { {!this.myPost && ( - + <> + + + )} )} @@ -1040,6 +1055,32 @@ export class PostListing extends Component {
)} + {this.state.showReportDialog && ( +
+ + + +
+ )} ); } @@ -1305,6 +1346,29 @@ export class PostListing extends Component { this.setState(this.state); } + handleShowReportDialog(i: PostListing) { + i.state.showReportDialog = !i.state.showReportDialog; + i.setState(this.state); + } + + handleReportReasonChange(i: PostListing, event: any) { + i.state.reportReason = event.target.value; + i.setState(i.state); + } + + handleReportSubmit(i: PostListing, event: any) { + event.preventDefault(); + let form: CreatePostReport = { + post_id: i.props.post_view.post.id, + reason: i.state.reportReason, + auth: authField(), + }; + WebSocketService.Instance.send(wsClient.createPostReport(form)); + + i.state.showReportDialog = false; + i.setState(i.state); + } + handleBlockUserClick(i: PostListing) { let blockUserForm: BlockPerson = { person_id: i.props.post_view.creator.id, diff --git a/src/shared/components/post/post.tsx b/src/shared/components/post/post.tsx index f876ec3..f1a7a8a 100644 --- a/src/shared/components/post/post.tsx +++ b/src/shared/components/post/post.tsx @@ -6,6 +6,7 @@ import { BanFromCommunityResponse, BanPersonResponse, BlockPersonResponse, + CommentReportResponse, CommentResponse, CommunityResponse, GetCommunityResponse, @@ -14,6 +15,7 @@ import { GetSiteResponse, ListingType, MarkCommentAsRead, + PostReportResponse, PostResponse, PostView, Search, @@ -245,8 +247,8 @@ export class Post extends Component { auth: authField(), }; WebSocketService.Instance.send(wsClient.markCommentAsRead(form)); - UserService.Instance.unreadCountSub.next( - UserService.Instance.unreadCountSub.value - 1 + UserService.Instance.unreadInboxCountSub.next( + UserService.Instance.unreadInboxCountSub.value - 1 ); } } @@ -619,6 +621,16 @@ export class Post extends Component { } else if (op == UserOperation.BlockPerson) { let data = wsJsonToRes(msg).data; updatePersonBlock(data); + } else if (op == UserOperation.CreatePostReport) { + let data = wsJsonToRes(msg).data; + if (data) { + toast(i18n.t("report_created")); + } + } else if (op == UserOperation.CreateCommentReport) { + let data = wsJsonToRes(msg).data; + if (data) { + toast(i18n.t("report_created")); + } } } } diff --git a/src/shared/components/post/post_report.tsx b/src/shared/components/post/post_report.tsx new file mode 100644 index 0000000..f2e1734 --- /dev/null +++ b/src/shared/components/post/post_report.tsx @@ -0,0 +1,99 @@ +import { Component, linkEvent } from "inferno"; +import { T } from "inferno-i18next-dess"; +import { PostReportView, PostView, ResolvePostReport } from "lemmy-js-client"; +import { i18n } from "../../i18next"; +import { WebSocketService } from "../../services"; +import { authField, wsClient } from "../../utils"; +import { Icon } from "../common/icon"; +import { PersonListing } from "../person/person-listing"; +import { PostListing } from "./post-listing"; + +interface PostReportProps { + report: PostReportView; +} + +export class PostReport extends Component { + constructor(props: any, context: any) { + super(props, context); + } + + render() { + let r = this.props.report; + let post = r.post; + + // Set the original post data ( a troll could change it ) + post.name = r.post_report.original_post_name; + post.url = r.post_report.original_post_url; + post.body = r.post_report.original_post_body; + let pv: PostView = { + post, + creator: r.post_creator, + community: r.community, + creator_banned_from_community: r.creator_banned_from_community, + counts: r.counts, + subscribed: false, + saved: false, + read: false, + creator_blocked: false, + my_vote: r.my_vote, + }; + + return ( +
+ +
+ {i18n.t("reporter")}: +
+
+ {i18n.t("reason")}: {r.post_report.reason} +
+ {r.resolver && ( +
+ {r.post_report.resolved ? ( + + # + + + ) : ( + + # + + + )} +
+ )} + +
+ ); + } + + handleResolveReport(i: PostReport) { + let form: ResolvePostReport = { + report_id: i.props.report.post_report.id, + resolved: !i.props.report.post_report.resolved, + auth: authField(), + }; + WebSocketService.Instance.send(wsClient.resolvePostReport(form)); + } +} diff --git a/src/shared/routes.ts b/src/shared/routes.ts index 2681b23..ddc3b62 100644 --- a/src/shared/routes.ts +++ b/src/shared/routes.ts @@ -12,6 +12,7 @@ import { Signup } from "./components/home/signup"; import { Modlog } from "./components/modlog"; import { Inbox } from "./components/person/inbox"; import { Profile } from "./components/person/profile"; +import { Reports } from "./components/person/reports"; import { Settings } from "./components/person/settings"; import { CreatePost } from "./components/post/create-post"; import { Post } from "./components/post/post"; @@ -122,6 +123,11 @@ export const routes: IRoutePropsWithFetch[] = [ component: AdminSettings, fetchInitialData: req => AdminSettings.fetchInitialData(req), }, + { + path: `/reports`, + component: Reports, + fetchInitialData: req => Reports.fetchInitialData(req), + }, { path: `/search/q/:q/type/:type/sort/:sort/listing_type/:listing_type/community_id/:community_id/creator_id/:creator_id/page/:page`, component: Search, diff --git a/src/shared/services/UserService.ts b/src/shared/services/UserService.ts index c9351ef..0c87f7d 100644 --- a/src/shared/services/UserService.ts +++ b/src/shared/services/UserService.ts @@ -16,9 +16,10 @@ export class UserService { public myUserInfo: MyUserInfo; public claims: Claims; public jwtSub: Subject = new Subject(); - public unreadCountSub: BehaviorSubject = new BehaviorSubject( - 0 - ); + public unreadInboxCountSub: BehaviorSubject = + new BehaviorSubject(0); + public unreadReportCountSub: BehaviorSubject = + new BehaviorSubject(0); private constructor() { if (this.auth) { diff --git a/src/shared/utils.ts b/src/shared/utils.ts index ed644c6..9ea21fd 100644 --- a/src/shared/utils.ts +++ b/src/shared/utils.ts @@ -2,6 +2,7 @@ import emojiShortName from "emoji-short-name"; import { BlockCommunityResponse, BlockPersonResponse, + CommentReportView, CommentView, CommunityBlockView, CommunityView, @@ -13,6 +14,7 @@ import { MyUserInfo, PersonBlockView, PersonViewSafe, + PostReportView, PostView, PrivateMessageView, Search, @@ -1055,6 +1057,26 @@ export function editPostRes(data: PostView, post: PostView) { } } +export function updatePostReportRes( + data: PostReportView, + reports: PostReportView[] +) { + let found = reports.find(p => p.post.id == data.post.id); + if (found) { + found.post_report = data.post_report; + } +} + +export function updateCommentReportRes( + data: CommentReportView, + reports: CommentReportView[] +) { + let found = reports.find(c => c.comment.id == data.comment.id); + if (found) { + found.comment_report = data.comment_report; + } +} + export function commentsToFlatNodes(comments: CommentView[]): CommentNodeI[] { let nodes: CommentNodeI[] = []; for (let comment of comments) { diff --git a/yarn.lock b/yarn.lock index 284e2c1..2d7eec8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4709,10 +4709,10 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" -lemmy-js-client@0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.12.0.tgz#2337aca9d8b38d92908d7f7a9479f0066a9eaeae" - integrity sha512-PSebUBkojM7OUlfSXKQhL4IcYKaKF+Xj2G0+pybaCvP9sJvviy32qHUi9BQeIhRHXgw8ILRH0Y+xZGKu0a3wvQ== +lemmy-js-client@0.12.3-rc.5: + version "0.12.3-rc.5" + resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.12.3-rc.5.tgz#26bc2d8443c5ab2bea1ed73697b202592fd00e15" + integrity sha512-3Rs1G7b/MYhQkMYJqBgQ+piSE+anYa+C2tr1DqY7+JrO1vbepu2+GyDg3jjzPuoZ3GPPOWYtKJU5pt9GqLb1lg== levn@^0.4.1: version "0.4.1"