Skip to content

Commit

Permalink
Merge 7b3cf40 into 4755649
Browse files Browse the repository at this point in the history
  • Loading branch information
MrOrz committed Jan 23, 2022
2 parents 4755649 + 7b3cf40 commit b413028
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 16 deletions.
50 changes: 50 additions & 0 deletions components/ActionMenu/ReportAbuseMenuItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { t } from 'ttag';
import MenuItem from '@material-ui/core/MenuItem';
import { makeStyles } from '@material-ui/core/styles';

import { getSpamReportUrl } from 'constants/urls';
import useCurrentUser from 'lib/useCurrentUser';

const useStyles = makeStyles({
link: {
color: 'inherit',
textDecoration: 'none',
},
});

/**
*
* @param {string} itemUserId - the author's user ID of the item
*/
export function useCanReportAbuse(itemUserId) {
const currentUser = useCurrentUser();
return currentUser && currentUser.id !== itemUserId;
}

/**
* @param {object} props
* @param {string} props.userId - spammer's user ID
* @param {'replyRequest' | 'articleReplyFeedback' | 'reply'} props.itemType - reported spam item type
* @param {string} props.itemId - reply ID for reply; article ID for replyRequest; article ID,reply ID (separated in comma) for article reply feedback.
*
* @returns {string} Pre-filled URL to the google form that reports spam.
*/
function ReportAbuseMenuItem(props) {
const classes = useStyles();
const canReportAbuse = useCanReportAbuse(props.userId);

if (!canReportAbuse) return null;

return (
<a
className={classes.link}
href={getSpamReportUrl(props)}
target="_blank"
rel="noopener noreferrer"
>
<MenuItem>{t`Report abuse`}</MenuItem>
</a>
);
}

export default ReportAbuseMenuItem;
3 changes: 3 additions & 0 deletions components/ActionMenu/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
import ActionMenu from './ActionMenu';
export default ActionMenu;

import ReportAbuseMenuItem, { useCanReportAbuse } from './ReportAbuseMenuItem';
export { ReportAbuseMenuItem, useCanReportAbuse };
4 changes: 4 additions & 0 deletions components/ArticleReply/ArticleReply.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,14 @@ const ArticleReplyData = gql`
}
...ArticleReplySummaryData
...ArticleReplyFeedbackControlData
...ReplyActionsData
}
${Hyperlinks.fragments.HyperlinkData}
${ArticleReplyFeedbackControl.fragments.ArticleReplyFeedbackControlData}
${ReplyInfo.fragments.replyInfo}
${Avatar.fragments.AvatarData}
${ArticleReplySummary.fragments.ArticleReplySummaryData}
${ReplyActions.fragments.ReplyActionsData}
`;

const ArticleReplyForUser = gql`
Expand All @@ -71,9 +73,11 @@ const ArticleReplyForUser = gql`
replyId
canUpdateStatus
...ArticleReplyFeedbackControlDataForUser
...ReplyActionsDataForUser
}
${ArticleReplyFeedbackControl.fragments
.ArticleReplyFeedbackControlDataForUser}
${ReplyActions.fragments.ReplyActionsDataForUser}
`;

const ArticleReply = React.memo(({ articleReply }) => {
Expand Down
61 changes: 48 additions & 13 deletions components/ArticleReply/ReplyActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,27 @@ import gql from 'graphql-tag';
import { useMutation } from '@apollo/react-hooks';
import { t } from 'ttag';

import ActionMenu from 'components/ActionMenu';
import ActionMenu, {
ReportAbuseMenuItem,
useCanReportAbuse,
} from 'components/ActionMenu';
import { MenuItem } from '@material-ui/core';

const ReplyActionsData = gql`
fragment ReplyActionsData on ArticleReply {
articleId
replyId
userId
status
}
`;

const ReplyActionsDataForUser = gql`
fragment ReplyActionsDataForUser on ArticleReply {
canUpdateStatus
}
`;

const UPDATE_ARTICLE_REPLY_STATUS = gql`
mutation UpdateArticleReplyStatus(
$articleId: String!
Expand All @@ -17,14 +35,17 @@ const UPDATE_ARTICLE_REPLY_STATUS = gql`
replyId: $replyId
status: $status
) {
articleId
replyId
status
...ReplyActionsData
...ReplyActionsDataForUser
}
${ReplyActionsData}
${ReplyActionsDataForUser}
}
`;

const ReplyActions = ({ articleReply }) => {
const canReportAbuse = useCanReportAbuse(articleReply.userId);

const [
updateArticleReplyStatus,
{ loading: updatingArticleReplyStatus },
Expand All @@ -50,20 +71,34 @@ const ReplyActions = ({ articleReply }) => {
});
}, [updateArticleReplyStatus]);

if (!articleReply.canUpdateStatus) return null;
if (!articleReply.canUpdateStatus && !canReportAbuse) return null;

return (
<ActionMenu>
<MenuItem
disabled={updatingArticleReplyStatus}
onClick={
articleReply.status === 'NORMAL' ? handleDelete : handleRestore
}
>
{articleReply.status === 'NORMAL' ? t`Delete` : t`Restore`}
</MenuItem>
{articleReply.canUpdateStatus && (
<MenuItem
disabled={updatingArticleReplyStatus}
onClick={
articleReply.status === 'NORMAL' ? handleDelete : handleRestore
}
>
{articleReply.status === 'NORMAL' ? t`Delete` : t`Restore`}
</MenuItem>
)}
{canReportAbuse && (
<ReportAbuseMenuItem
itemId={articleReply.replyId}
itemType="reply"
userId={articleReply.userId}
/>
)}
</ActionMenu>
);
};

ReplyActions.fragments = {
ReplyActionsData,
ReplyActionsDataForUser,
};

export default ReplyActions;
23 changes: 20 additions & 3 deletions components/ReplyRequestReason/ReplyRequestReason.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import React from 'react';
import gql from 'graphql-tag';
import PropTypes from 'prop-types';
import { useMutation } from '@apollo/react-hooks';
import { makeStyles } from '@material-ui/core/styles';
import { Box, Button } from '@material-ui/core';

import { ThumbUpIcon, ThumbDownIcon } from 'components/icons';
import Avatar from 'components/AppLayout/Widgets/Avatar';
import gql from 'graphql-tag';
import PropTypes from 'prop-types';
import ActionMenu, {
ReportAbuseMenuItem,
useCanReportAbuse,
} from 'components/ActionMenu';

const useStyles = makeStyles(theme => ({
root: {
Expand Down Expand Up @@ -77,7 +82,7 @@ const UPDATE_VOTE = gql`
${ReplyRequestInfo}
`;

function ReplyRequestReason({ replyRequest }) {
function ReplyRequestReason({ replyRequest, articleId }) {
const {
id: replyRequestId,
reason: replyRequestReason,
Expand All @@ -87,6 +92,7 @@ function ReplyRequestReason({ replyRequest }) {
user,
} = replyRequest;

const canReportAbuse = useCanReportAbuse(user.id);
const [voteReason, { loading }] = useMutation(UPDATE_VOTE);
const handleVote = vote => {
voteReason({ variables: { vote, replyRequestId } });
Expand Down Expand Up @@ -132,6 +138,17 @@ function ReplyRequestReason({ replyRequest }) {
</Box>
</Box>
</Box>
{canReportAbuse && (
<Box pl={2} alignSelf="flex-start">
<ActionMenu>
<ReportAbuseMenuItem
itemId={articleId}
itemType="replyRequest"
userId={user.id}
/>
</ActionMenu>
</Box>
)}
</div>
);
}
Expand Down
13 changes: 13 additions & 0 deletions constants/urls.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,16 @@ export const FACEBOOK_SHARE_URL_PREFIX =

export const DONATION_URL =
'https://ocf.neticrm.tw/civicrm/contribute/transact?id=48';

/**
* @param {object} params
* @param {string} params.userId - spammer's user ID
* @param {'replyRequest' | 'articleReplyFeedback' | 'reply'} params.itemType - reported spam item type
* @param {string} params.itemId - reply ID for reply; article ID for replyRequest; article ID,reply ID (separated in comma) for article reply feedback.
*
* @returns {string} Pre-filled URL to the google form that reports spam.
*/
export const getSpamReportUrl = ({ userId, itemType, itemId }) => {
// Prefilled URL as constant, manually edited to become template string
return `https://docs.google.com/forms/d/e/1FAIpQLSf7d8xCAz682vR3WLRVTxqqbWiFXLd6ShZpOnsXXTmAbPFcUA/viewform?usp=pp_url&entry.1302713624=${userId}&entry.192715150=${itemId}&entry.511781180=${itemType}&entry.1691230719=${location.href}`;
};

0 comments on commit b413028

Please sign in to comment.