From 634e5a063d5228473adbf48c925174889291b60f Mon Sep 17 00:00:00 2001 From: Dessalines Date: Mon, 27 Sep 2021 21:16:38 -0400 Subject: [PATCH] A first pass at reporting. Fixes #102 --- package.json | 2 +- src/shared/components/app/navbar.tsx | 210 ++++++++++++------ .../components/comment/comment-node.tsx | 67 ++++++ src/shared/components/common/symbols.tsx | 6 + src/shared/components/community/community.tsx | 12 + src/shared/components/home/home.tsx | 12 + src/shared/components/person/inbox.tsx | 12 + src/shared/components/person/reports.tsx | 1 - src/shared/components/post/post-listing.tsx | 80 ++++++- src/shared/components/post/post.tsx | 16 +- src/shared/routes.ts | 6 + 11 files changed, 347 insertions(+), 77 deletions(-) diff --git a/package.json b/package.json index c2738618..35124b72 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 50bf5fa1..865b72dd 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/common/symbols.tsx b/src/shared/components/common/symbols.tsx index f94bc551..2035d3c4 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 e3420855..1d77d44f 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 ec581c00..a1793ae6 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 d1e80714..05b75ec7 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,6 +763,16 @@ 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")); + } } } diff --git a/src/shared/components/person/reports.tsx b/src/shared/components/person/reports.tsx index 0ecf8f31..2c83ff2a 100644 --- a/src/shared/components/person/reports.tsx +++ b/src/shared/components/person/reports.tsx @@ -104,7 +104,6 @@ export class Reports extends Component { this.state.postReports = this.isoData.routeData[1].post_reports || []; this.state.combined = this.buildCombined(); this.state.loading = false; - console.log(this.isoData.routeData[1]); } else { this.refetch(); } diff --git a/src/shared/components/post/post-listing.tsx b/src/shared/components/post/post-listing.tsx index b2e1f7e0..d61c690b 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 f876ec37..f1a7a8ae 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/routes.ts b/src/shared/routes.ts index 2681b234..ddc3b621 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,