Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse Comment & Abuse responses of the Discussion API #10364

Merged
merged 2 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@ export const AbuseReportForm = ({
authStatus,
})
.then((response) => {
if (response.status !== 'ok') {
if (response.kind === 'error') {
// Fallback to errors returned from the API
setErrors({ ...errors, response: response.message });
setErrors({ ...errors, response: response.error });
} else {
setSuccessMessage('Report submitted');
}
Expand Down
8 changes: 4 additions & 4 deletions dotcom-rendering/src/components/Discussion/Comment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -314,8 +314,8 @@ export const Comment = ({
setError('');

const response = await pickComment(staffUser.authStatus, comment.id);
if (response.status === 'error') {
setError(response.message);
if (response.kind === 'error') {
setError(response.error.message);
} else {
setIsHighlighted(true);
}
Expand All @@ -324,8 +324,8 @@ export const Comment = ({
const unPick = async (staffUser: SignedInUser) => {
setError('');
const response = await unPickComment(staffUser.authStatus, comment.id);
if (response.status === 'error') {
setError(response.message);
if (response.kind === 'error') {
setError(response.error.message);
} else {
setIsHighlighted(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { css } from '@emotion/react';
import { palette as sourcePalette, space } from '@guardian/source-foundations';
import { SvgPlus } from '@guardian/source-react-components';
import { useEffect, useState } from 'react';
import type { comment, reply } from '../../lib/discussionApi';
import { getMoreResponses } from '../../lib/discussionApi';
import type {
CommentResponse,
CommentType,
SignedInUser,
ThreadsType,
Expand All @@ -27,12 +27,8 @@ type Props = {
toggleMuteStatus: (userId: string) => void;
onPermalinkClick: (commentId: number) => void;
onRecommend?: (commentId: number) => Promise<boolean>;
onComment?: (shortUrl: string, body: string) => Promise<CommentResponse>;
onReply?: (
shortUrl: string,
body: string,
parentCommentId: number,
) => Promise<CommentResponse>;
onComment?: ReturnType<typeof comment>;
onReply?: ReturnType<typeof reply>;
onPreview?: (body: string) => Promise<string>;
showPreview: boolean;
setShowPreview: (showPreview: boolean) => void;
Expand Down
134 changes: 65 additions & 69 deletions dotcom-rendering/src/components/Discussion/CommentForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ import {
reply as defaultReply,
} from '../../lib/discussionApi';
import { palette as schemedPalette } from '../../palette';
import type {
CommentResponse,
CommentType,
SignedInUser,
} from '../../types/discussion';
import type { CommentType, SignedInUser } from '../../types/discussion';
import { FirstCommentWelcome } from './FirstCommentWelcome';
import { PillarButton } from './PillarButton';
import { Preview } from './Preview';
Expand All @@ -29,12 +25,8 @@ type Props = {
onAddComment: (response: CommentType) => void;
setCommentBeingRepliedTo?: () => void;
commentBeingRepliedTo?: CommentType;
onComment?: (shortUrl: string, body: string) => Promise<CommentResponse>;
onReply?: (
shortUrl: string,
body: string,
parentCommentId: number,
) => Promise<CommentResponse>;
onComment?: ReturnType<typeof defaultComment>;
onReply?: ReturnType<typeof defaultReply>;
onPreview?: (body: string) => Promise<string>;
showPreview: boolean;
setShowPreview: (showPreview: boolean) => void;
Expand Down Expand Up @@ -325,88 +317,92 @@ export const CommentForm = ({
if (body) {
const comment = onComment ?? defaultComment(user.authStatus);
const reply = onReply ?? defaultReply(user.authStatus);
const response: CommentResponse = commentBeingRepliedTo
const response = commentBeingRepliedTo
? await reply(shortUrl, body, commentBeingRepliedTo.id)
: await comment(shortUrl, body);
// Check response message for error states
if (response.errorCode === 'USERNAME_MISSING') {
// Reader has never posted before and needs to choose a username
setUserNameMissing(true);
} else if (response.errorCode === 'EMPTY_COMMENT_BODY') {
setError('Please write a comment.');
} else if (response.errorCode === 'COMMENT_TOO_LONG') {
setError(
'Your comment must be fewer than 5000 characters long.',
);
} else if (response.errorCode === 'USER_BANNED') {
setError(
'Commenting has been disabled for this account (<a href="/community-faqs#321a">why?</a>).',
);
} else if (response.errorCode === 'IP_THROTTLED') {
setError(
'Commenting has been temporarily blocked for this IP address (<a href="/community-faqs">why?</a>).',
);
} else if (response.errorCode === 'DISCUSSION_CLOSED') {
setError(
'Sorry your comment can not be published as the discussion is now closed for comments.',
);
} else if (response.errorCode === 'PARENT_COMMENT_MODERATED') {
setError(
'Sorry the comment can not be published as the comment you replied to has been moderated since.',
);
} else if (response.errorCode === 'COMMENT_RATE_LIMIT_EXCEEDED') {
setError(
'You can only post one comment every minute. Please try again in a moment.',
);
} else if (response.errorCode === 'INVALID_PROTOCOL') {
setError(`Sorry your comment can not be published as it was not sent over
if (response.kind === 'error') {
if (response.error.code === 'USERNAME_MISSING') {
// Reader has never posted before and needs to choose a username
setUserNameMissing(true);
} else if (response.error.code === 'EMPTY_COMMENT_BODY') {
setError('Please write a comment.');
} else if (response.error.code === 'COMMENT_TOO_LONG') {
setError(
'Your comment must be fewer than 5000 characters long.',
);
} else if (response.error.code === 'USER_BANNED') {
setError(
'Commenting has been disabled for this account (<a href="/community-faqs#321a">why?</a>).',
);
} else if (response.error.code === 'IP_THROTTLED') {
setError(
'Commenting has been temporarily blocked for this IP address (<a href="/community-faqs">why?</a>).',
);
} else if (response.error.code === 'DISCUSSION_CLOSED') {
setError(
'Sorry your comment can not be published as the discussion is now closed for comments.',
);
} else if (response.error.code === 'PARENT_COMMENT_MODERATED') {
setError(
'Sorry the comment can not be published as the comment you replied to has been moderated since.',
);
} else if (
response.error.code === 'COMMENT_RATE_LIMIT_EXCEEDED'
) {
setError(
'You can only post one comment every minute. Please try again in a moment.',
);
} else if (response.error.code === 'INVALID_PROTOCOL') {
setError(`Sorry your comment can not be published as it was not sent over
a secure channel. Please report us this issue using the technical issue link
in the page footer.`);
} else if (response.errorCode === 'AUTH_COOKIE_INVALID') {
setError(
'Sorry, your comment was not published as you are no longer signed in. Please sign in and try again.',
);
} else if (response.errorCode === 'READ-ONLY-MODE') {
setError(`Sorry your comment can not currently be published as
} else if (response.error.code === 'AUTH_COOKIE_INVALID') {
setError(
'Sorry, your comment was not published as you are no longer signed in. Please sign in and try again.',
);
} else if (response.error.code === 'READ-ONLY-MODE') {
setError(`Sorry your comment can not currently be published as
commenting is undergoing maintenance but will be back shortly. Please try
again in a moment.`);
} else if (response.errorCode === 'API_CORS_BLOCKED') {
setError(`Could not post due to your internet settings, which might be
} else if (response.error.code === 'API_CORS_BLOCKED') {
setError(`Could not post due to your internet settings, which might be
controlled by your provider. Please contact your administrator
or disable any proxy servers or VPNs and try again.`);
} else if (response.errorCode === 'API_ERROR') {
setError(`Sorry, there was a problem posting your comment. Please try
} else if (response.error.code === 'API_ERROR') {
setError(`Sorry, there was a problem posting your comment. Please try
another browser or network connection. Reference code `);
} else if (response.errorCode === 'EMAIL_VERIFIED') {
setInfo(
'Sent. Please check your email to verify your email address. Once verified post your comment.',
);
} else if (response.errorCode === 'EMAIL_VERIFIED_FAIL') {
// TODO: Support resending verification email
setError(`We are having technical difficulties. Please try again later or
} else if (response.error.code === 'EMAIL_VERIFIED') {
setInfo(
'Sent. Please check your email to verify your email address. Once verified post your comment.',
);
} else if (response.error.code === 'EMAIL_VERIFIED_FAIL') {
// TODO: Support resending verification email
setError(`We are having technical difficulties. Please try again later or
<a href="#">
<strong>resend the verification</strong></a>.`);
} else if (response.errorCode === 'EMAIL_NOT_VALIDATED') {
// TODO: Support resending verification email
setError(`Please confirm your email address to comment.<br />
} else if (response.error.code === 'EMAIL_NOT_VALIDATED') {
// TODO: Support resending verification email
setError(`Please confirm your email address to comment.<br />
If you can't find the email, we can
<a href="#">
<strong>resend the verification email</strong></a> to your email
address.`);
} else if (response.status === 'ok') {
} else {
setError(
'Sorry, there was a problem posting your comment.',
);
}
} else {
onAddComment(
simulateNewComment(
// response.errorCode is the id of the comment that was created on the server
// it is returned as a string, so we need to cast to an number to be compatable
parseInt(response.message),
response.value,
body,
user.profile,
commentBeingRepliedTo,
),
);
resetForm();
} else {
setError('Sorry, there was a problem posting your comment.');
}
}
};
Expand Down
10 changes: 3 additions & 7 deletions dotcom-rendering/src/components/Discussion/Comments.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import {
textSans,
} from '@guardian/source-foundations';
import { useEffect, useState } from 'react';
import type { comment, reply } from '../../lib/discussionApi';
import { getPicks, initialiseApi } from '../../lib/discussionApi';
import type {
AdditionalHeadersType,
CommentResponse,
CommentType,
FilterOptions,
SignedInUser,
Expand All @@ -32,12 +32,8 @@ type Props = {
onPermalinkClick: (commentId: number) => void;
apiKey: string;
onRecommend?: (commentId: number) => Promise<boolean>;
onComment?: (shortUrl: string, body: string) => Promise<CommentResponse>;
onReply?: (
shortUrl: string,
body: string,
parentCommentId: number,
) => Promise<CommentResponse>;
onComment?: ReturnType<typeof comment>;
onReply?: ReturnType<typeof reply>;
onPreview?: (body: string) => Promise<string>;
onExpand: () => void;
idApiUrl: string;
Expand Down
Loading
Loading