diff --git a/src/core/client/admin/components/ModerateCard/ModerateCardContainer.tsx b/src/core/client/admin/components/ModerateCard/ModerateCardContainer.tsx index e9dc4b5ca..60b130e35 100644 --- a/src/core/client/admin/components/ModerateCard/ModerateCardContainer.tsx +++ b/src/core/client/admin/components/ModerateCard/ModerateCardContainer.tsx @@ -22,7 +22,6 @@ import { ModerateCardContainer_comment, } from "coral-admin/__generated__/ModerateCardContainer_comment.graphql"; import { ModerateCardContainer_settings } from "coral-admin/__generated__/ModerateCardContainer_settings.graphql"; -import { ModerateCardContainer_viewer } from "coral-admin/__generated__/ModerateCardContainer_viewer.graphql"; import BanCommentUserMutation from "./BanCommentUserMutation"; import FeatureCommentMutation from "./FeatureCommentMutation"; @@ -32,7 +31,6 @@ import UnfeatureCommentMutation from "./UnfeatureCommentMutation"; interface Props { comment: ModerateCardContainer_comment; - viewer: ModerateCardContainer_viewer; settings: ModerateCardContainer_settings; approveComment: MutationProp; rejectComment: MutationProp; @@ -74,7 +72,6 @@ const ModerateCardContainer: FunctionComponent = ({ settings, danglingLogic, showStoryInfo, - viewer, match, router, approveComment, @@ -258,7 +255,6 @@ const ModerateCardContainer: FunctionComponent = ({ moderatedBy={ } @@ -365,11 +361,6 @@ const enhanced = withFragmentContainer({ ...MarkersContainer_settings } `, - viewer: graphql` - fragment ModerateCardContainer_viewer on User { - ...ModeratedByContainer_viewer - } - `, })( withRouter( withMutation(BanCommentUserMutation)( diff --git a/src/core/client/admin/components/ModerateCard/ModeratedByContainer.spec.tsx b/src/core/client/admin/components/ModerateCard/ModeratedByContainer.spec.tsx index 2e501d4b0..0bef572a8 100644 --- a/src/core/client/admin/components/ModerateCard/ModeratedByContainer.spec.tsx +++ b/src/core/client/admin/components/ModerateCard/ModeratedByContainer.spec.tsx @@ -24,10 +24,6 @@ it("viewer's username shows on moderation cards moderated by viewer", () => { ], }, }, - viewer: { - id: "viewer", - username: "viewer", - }, onUsernameClicked: (id?: string | null) => { return; }, diff --git a/src/core/client/admin/components/ModerateCard/ModeratedByContainer.tsx b/src/core/client/admin/components/ModerateCard/ModeratedByContainer.tsx index 13483272d..d7c78b100 100644 --- a/src/core/client/admin/components/ModerateCard/ModeratedByContainer.tsx +++ b/src/core/client/admin/components/ModerateCard/ModeratedByContainer.tsx @@ -1,55 +1,88 @@ import { Localized } from "@fluent/react/compat"; -import React, { useCallback } from "react"; +import React, { useCallback, useMemo } from "react"; import { graphql } from "react-relay"; import { withFragmentContainer } from "coral-framework/lib/relay"; import { BaseButton } from "coral-ui/components/v2"; import { ModeratedByContainer_comment } from "coral-admin/__generated__/ModeratedByContainer_comment.graphql"; -import { ModeratedByContainer_viewer } from "coral-admin/__generated__/ModeratedByContainer_viewer.graphql"; import styles from "./ModeratedByContainer.css"; interface Props { - viewer: ModeratedByContainer_viewer; comment: ModeratedByContainer_comment; onUsernameClicked: (id?: string | null) => void; } +const MODERATION_STATUS = ["APPROVED", "REJECTED"]; + +interface ModeratedBy { + id?: string; + username?: string | null; + system?: boolean; +} + +const system: ModeratedBy = { system: true }; + const ModeratedByContainer: React.FunctionComponent = ({ comment, - viewer, onUsernameClicked, }) => { - let moderatedBy: React.ReactElement | null; - let id: string | null = null; - if (comment.statusHistory.edges.length === 0) { - moderatedBy = null; - } else if (comment.statusHistory.edges[0].node.moderator === null) { - moderatedBy = ( - System - ); - } else if (viewer.id === comment.statusHistory.edges[0].node.moderator.id) { - moderatedBy = viewer.username ? <>{viewer.username} : null; - } else { - moderatedBy = <>{comment.statusHistory.edges[0].node.moderator.username}; - id = comment.statusHistory.edges[0].node.moderator.id; - } + const moderatedBy: ModeratedBy | null = useMemo(() => { + // If the comment was just moderated by the viewer, don't display anything. + // This will update once the mutation returns. + if (comment.viewerDidModerate) { + return null; + } + + // If the comment has not been approved or rejected, don't render anything. + if (!MODERATION_STATUS.includes(comment.status)) { + return null; + } + + if (comment.statusHistory.edges.length === 0) { + return system; + } + + // Get the node that was the last moderated by element. + const { + node: { status, moderator }, + } = comment.statusHistory.edges[0]; + if (!MODERATION_STATUS.includes(status)) { + return null; + } + + if (!moderator) { + return system; + } + + return moderator; + }, [comment]); + + const onClick = useCallback(() => { + if (!moderatedBy || !moderatedBy.id) { + return; + } + + onUsernameClicked(moderatedBy.id); + }, [onUsernameClicked, moderatedBy]); if (!moderatedBy) { return null; } - const onClick = useCallback(() => { - onUsernameClicked(id); - }, [onUsernameClicked, comment]); - return (
Moderated By
-
{moderatedBy}
+
+ {moderatedBy.system ? ( + System + ) : ( + moderatedBy.username + )} +
); }; @@ -58,10 +91,12 @@ const enhanced = withFragmentContainer({ comment: graphql` fragment ModeratedByContainer_comment on Comment { id - statusLiveUpdated + status + viewerDidModerate statusHistory(first: 1) { edges { node { + status moderator { id username @@ -71,12 +106,6 @@ const enhanced = withFragmentContainer({ } } `, - viewer: graphql` - fragment ModeratedByContainer_viewer on User { - id - username - } - `, })(ModeratedByContainer); export default enhanced; diff --git a/src/core/client/admin/components/ModerateCard/__snapshots__/ModeratedByContainer.spec.tsx.snap b/src/core/client/admin/components/ModerateCard/__snapshots__/ModeratedByContainer.spec.tsx.snap index d9ec8a8b7..8083d37b3 100644 --- a/src/core/client/admin/components/ModerateCard/__snapshots__/ModeratedByContainer.spec.tsx.snap +++ b/src/core/client/admin/components/ModerateCard/__snapshots__/ModeratedByContainer.spec.tsx.snap @@ -19,11 +19,5 @@ exports[`viewer's username shows on moderation cards moderated by viewer 1`] = ` } } onUsernameClicked={[Function]} - viewer={ - Object { - "id": "viewer", - "username": "viewer", - } - } /> `; diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerAllComments.tsx b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerAllComments.tsx index a79fae682..d2333b003 100644 --- a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerAllComments.tsx +++ b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerAllComments.tsx @@ -11,21 +11,18 @@ import { Button, CallOut, Divider } from "coral-ui/components/v2"; import { UserHistoryDrawerAllComments_settings } from "coral-admin/__generated__/UserHistoryDrawerAllComments_settings.graphql"; import { UserHistoryDrawerAllComments_user } from "coral-admin/__generated__/UserHistoryDrawerAllComments_user.graphql"; -import { UserHistoryDrawerAllComments_viewer } from "coral-admin/__generated__/UserHistoryDrawerAllComments_viewer.graphql"; import { UserHistoryDrawerAllCommentsPaginationQueryVariables } from "coral-admin/__generated__/UserHistoryDrawerAllCommentsPaginationQuery.graphql"; import styles from "./UserHistoryDrawerAllComments.css"; interface Props { user: UserHistoryDrawerAllComments_user; - viewer: UserHistoryDrawerAllComments_viewer; settings: UserHistoryDrawerAllComments_settings; relay: RelayPaginationProp; } const UserHistoryDrawerAllComments: FunctionComponent = ({ user, - viewer, settings, relay, }) => { @@ -61,7 +58,6 @@ const UserHistoryDrawerAllComments: FunctionComponent = ({
false} hideUsername @@ -91,11 +87,6 @@ const enhanced = withPaginationContainer< FragmentVariables >( { - viewer: graphql` - fragment UserHistoryDrawerAllComments_viewer on User { - ...ModerateCardContainer_viewer - } - `, settings: graphql` fragment UserHistoryDrawerAllComments_settings on Settings { ...ModerateCardContainer_settings diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerAllCommentsQuery.tsx b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerAllCommentsQuery.tsx index ae0529d50..ef560d342 100644 --- a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerAllCommentsQuery.tsx +++ b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerAllCommentsQuery.tsx @@ -24,9 +24,6 @@ const UserHistoryDrawerAllCommentsQuery: FunctionComponent = ({ user(id: $userID) { ...UserHistoryDrawerAllComments_user } - viewer { - ...UserHistoryDrawerAllComments_viewer - } settings { ...UserHistoryDrawerAllComments_settings } @@ -57,8 +54,6 @@ const UserHistoryDrawerAllCommentsQuery: FunctionComponent = ({ return ( diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerRejectedComments.tsx b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerRejectedComments.tsx index 8cec4bae5..2b8be0c9a 100644 --- a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerRejectedComments.tsx +++ b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerRejectedComments.tsx @@ -11,21 +11,18 @@ import { Button, CallOut, Divider } from "coral-ui/components/v2"; import { UserHistoryDrawerRejectedComments_settings } from "coral-admin/__generated__/UserHistoryDrawerRejectedComments_settings.graphql"; import { UserHistoryDrawerRejectedComments_user } from "coral-admin/__generated__/UserHistoryDrawerRejectedComments_user.graphql"; -import { UserHistoryDrawerRejectedComments_viewer } from "coral-admin/__generated__/UserHistoryDrawerRejectedComments_viewer.graphql"; import { UserHistoryDrawerRejectedCommentsPaginationQueryVariables } from "coral-admin/__generated__/UserHistoryDrawerRejectedCommentsPaginationQuery.graphql"; import styles from "./UserHistoryDrawerRejectedComments.css"; interface Props { user: UserHistoryDrawerRejectedComments_user; - viewer: UserHistoryDrawerRejectedComments_viewer; settings: UserHistoryDrawerRejectedComments_settings; relay: RelayPaginationProp; } const UserHistoryDrawerRejectedComments: FunctionComponent = ({ user, - viewer, settings, relay, }) => { @@ -63,7 +60,6 @@ const UserHistoryDrawerRejectedComments: FunctionComponent = ({
false} hideUsername @@ -93,11 +89,6 @@ const enhanced = withPaginationContainer< FragmentVariables >( { - viewer: graphql` - fragment UserHistoryDrawerRejectedComments_viewer on User { - ...ModerateCardContainer_viewer - } - `, settings: graphql` fragment UserHistoryDrawerRejectedComments_settings on Settings { ...ModerateCardContainer_settings diff --git a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerRejectedCommentsQuery.tsx b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerRejectedCommentsQuery.tsx index 0471724f4..4cba2b7fa 100644 --- a/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerRejectedCommentsQuery.tsx +++ b/src/core/client/admin/components/UserHistoryDrawer/UserHistoryDrawerRejectedCommentsQuery.tsx @@ -22,9 +22,6 @@ const UserHistoryDrawerRejectedCommentsQuery: FunctionComponent = ({ user(id: $userID) { ...UserHistoryDrawerRejectedComments_user } - viewer { - ...UserHistoryDrawerRejectedComments_viewer - } settings { ...UserHistoryDrawerRejectedComments_settings } @@ -55,8 +52,6 @@ const UserHistoryDrawerRejectedCommentsQuery: FunctionComponent = ({ return ( diff --git a/src/core/client/admin/local/local.graphql b/src/core/client/admin/local/local.graphql index 754d1be5b..921e2e60b 100644 --- a/src/core/client/admin/local/local.graphql +++ b/src/core/client/admin/local/local.graphql @@ -17,6 +17,9 @@ extend type Comment { # If true then Comment came in live. enteredLive: Boolean + + # If true then the Comment status was updated by the viewer. + viewerDidModerate: Boolean } extend type CommentsConnection { diff --git a/src/core/client/admin/mutations/ApproveCommentMutation.ts b/src/core/client/admin/mutations/ApproveCommentMutation.ts index 85b69c2dc..9179ea7ea 100644 --- a/src/core/client/admin/mutations/ApproveCommentMutation.ts +++ b/src/core/client/admin/mutations/ApproveCommentMutation.ts @@ -40,15 +40,7 @@ const ApproveCommentMutation = createMutation( } } } - statusHistory(first: 1) { - edges { - node { - moderator { - username - } - } - } - } + ...ModeratedByContainer_comment } moderationQueues(storyID: $storyID) { unmoderated { @@ -74,7 +66,9 @@ const ApproveCommentMutation = createMutation( storyID: input.storyID, }, optimisticUpdater: store => { - store.get(input.commentID)!.setValue("APPROVED", "status"); + const proxy = store.get(input.commentID)!; + proxy.setValue("APPROVED", "status"); + proxy.setValue(true, "viewerDidModerate"); }, updater: store => { const connections = [ diff --git a/src/core/client/admin/mutations/RejectCommentMutation.ts b/src/core/client/admin/mutations/RejectCommentMutation.ts index 369d7d788..67e61a50b 100644 --- a/src/core/client/admin/mutations/RejectCommentMutation.ts +++ b/src/core/client/admin/mutations/RejectCommentMutation.ts @@ -40,15 +40,7 @@ const RejectCommentMutation = createMutation( } } } - statusHistory(first: 1) { - edges { - node { - moderator { - username - } - } - } - } + ...ModeratedByContainer_comment } moderationQueues(storyID: $storyID) { unmoderated { @@ -74,7 +66,9 @@ const RejectCommentMutation = createMutation( storyID: input.storyID, }, optimisticUpdater: store => { - store.get(input.commentID)!.setValue("REJECTED", "status"); + const proxy = store.get(input.commentID)!; + proxy.setValue("REJECTED", "status"); + proxy.setValue(true, "viewerDidModerate"); }, updater: store => { const connections = [ diff --git a/src/core/client/admin/routes/Moderate/Queue/ApprovedQueueRoute.tsx b/src/core/client/admin/routes/Moderate/Queue/ApprovedQueueRoute.tsx index f9d04761a..30e1d8f82 100644 --- a/src/core/client/admin/routes/Moderate/Queue/ApprovedQueueRoute.tsx +++ b/src/core/client/admin/routes/Moderate/Queue/ApprovedQueueRoute.tsx @@ -37,7 +37,6 @@ export class ApprovedQueueRoute extends React.Component< return ( { hasLoadMore: true, disableLoadMore: false, danglingLogic: () => true, - viewer: { id: "me", username: "Mirai" }, onViewNew: noop, }; const renderer = createRenderer(); @@ -33,7 +32,6 @@ it("renders correctly without load more", () => { hasLoadMore: false, disableLoadMore: false, danglingLogic: () => true, - viewer: { id: "me", username: "Mirai" }, onViewNew: noop, }; const renderer = createRenderer(); diff --git a/src/core/client/admin/routes/Moderate/Queue/Queue.tsx b/src/core/client/admin/routes/Moderate/Queue/Queue.tsx index cb12592c2..7ec90b74d 100644 --- a/src/core/client/admin/routes/Moderate/Queue/Queue.tsx +++ b/src/core/client/admin/routes/Moderate/Queue/Queue.tsx @@ -19,7 +19,6 @@ interface Props { { id: string } & PropTypesOf["comment"] >; settings: PropTypesOf["settings"]; - viewer: PropTypesOf["viewer"]; onLoadMore: () => void; onViewNew?: () => void; hasLoadMore: boolean; @@ -39,7 +38,6 @@ const Queue: FunctionComponent = ({ danglingLogic, emptyElement, allStories, - viewer, viewNewCount, onViewNew, }) => { @@ -136,7 +134,6 @@ const Queue: FunctionComponent = ({ = props => { = props => { ({ settings { ...ModerateCardContainer_settings } - viewer { - ...ModerateCardContainer_viewer - } } `, cacheConfig: { force: true }, diff --git a/src/core/client/admin/test/moderate/__snapshots__/rejectedQueue.spec.tsx.snap b/src/core/client/admin/test/moderate/__snapshots__/rejectedQueue.spec.tsx.snap index a20cc9ce3..7d639ba61 100644 --- a/src/core/client/admin/test/moderate/__snapshots__/rejectedQueue.spec.tsx.snap +++ b/src/core/client/admin/test/moderate/__snapshots__/rejectedQueue.spec.tsx.snap @@ -524,6 +524,27 @@ exports[`renders rejected queue with comments 1`] = `
+
@@ -774,6 +795,27 @@ exports[`renders rejected queue with comments 1`] = ` + @@ -1043,6 +1085,27 @@ exports[`renders rejected queue with comments and load more 1`] = ` + diff --git a/src/core/client/admin/test/moderate/regularQueue.spec.tsx b/src/core/client/admin/test/moderate/regularQueue.spec.tsx index 332fdf17d..1b2c57c5b 100644 --- a/src/core/client/admin/test/moderate/regularQueue.spec.tsx +++ b/src/core/client/admin/test/moderate/regularQueue.spec.tsx @@ -382,7 +382,8 @@ it("approves comment in reported queue", async () => { { node: { id: "mod-action", - author: { + status: GQLCOMMENT_STATUS.APPROVED, + moderator: { id: viewer.id, username: viewer.username, }, @@ -479,7 +480,8 @@ it("rejects comment in reported queue", async () => { { node: { id: "mod-action", - author: { + status: GQLCOMMENT_STATUS.REJECTED, + moderator: { id: viewer.id, username: viewer.username, }, diff --git a/src/core/client/admin/test/moderate/rejectedQueue.spec.tsx b/src/core/client/admin/test/moderate/rejectedQueue.spec.tsx index 57f9ddc9e..7c5415a55 100644 --- a/src/core/client/admin/test/moderate/rejectedQueue.spec.tsx +++ b/src/core/client/admin/test/moderate/rejectedQueue.spec.tsx @@ -248,7 +248,8 @@ it("approves comment in rejected queue", async () => { { node: { id: "mod-action", - author: { + status: GQLCOMMENT_STATUS.APPROVED, + moderator: { id: viewer.id, username: viewer.username, }, diff --git a/src/core/client/admin/test/moderate/singleComment.spec.tsx b/src/core/client/admin/test/moderate/singleComment.spec.tsx index 65df0bef0..9752f892b 100644 --- a/src/core/client/admin/test/moderate/singleComment.spec.tsx +++ b/src/core/client/admin/test/moderate/singleComment.spec.tsx @@ -102,7 +102,8 @@ it("approves single comment", async () => { { node: { id: "mod-action", - author: { + status: GQLCOMMENT_STATUS.APPROVED, + moderator: { id: viewer.id, username: viewer.username, }, @@ -155,6 +156,7 @@ it("rejects single comment", async () => { { node: { id: "mod-action", + status: GQLCOMMENT_STATUS.REJECTED, author: { id: viewer.id, username: viewer.username,