Skip to content

Commit

Permalink
Refactor getCommentContext (#10512)
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielCliftonGuardian authored Feb 9, 2024
1 parent b37a0bd commit f950450
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 58 deletions.
2 changes: 1 addition & 1 deletion dotcom-rendering/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@
"typescript": "5.3.3",
"typescript-json-schema": "0.58.1",
"unified": "10.1.2",
"valibot": "0.26.0",
"valibot": "0.28.1",
"web-vitals": "3.5.1",
"webpack": "5.89.0",
"webpack-assets-manifest": "5.1.0",
Expand Down
21 changes: 14 additions & 7 deletions dotcom-rendering/src/components/Discussion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ import type {
FilterOptions,
SignedInUser,
} from '../lib/discussion';
import { getDiscussion, type reportAbuse } from '../lib/discussionApi';
import {
getCommentContext,
initFiltersFromLocalStorage,
} from '../lib/getCommentContext';
getDiscussion,
type reportAbuse,
} from '../lib/discussionApi';
import { initFiltersFromLocalStorage } from '../lib/discussionFilters';
import { palette as themePalette } from '../palette';
import { Comments } from './Discussion/Comments';
import { Hide } from './Hide';
Expand Down Expand Up @@ -536,10 +537,16 @@ export const Discussion = ({
remapToValidFilters(filters, hashCommentId),
)
.then((context) => {
dispatch({
type: 'updateCommentPage',
commentPage: context.page,
});
if (context.kind === 'ok') {
dispatch({
type: 'updateCommentPage',
commentPage: context.value.page,
});
} else {
console.error(
`getCommentContext - error: ${context.error}`,
);
}
})
.catch((e) =>
console.error(`getCommentContext - error: ${String(e)}`),
Expand Down
12 changes: 12 additions & 0 deletions dotcom-rendering/src/lib/discussion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,3 +389,15 @@ export type CommentForm = {
previewBody: string;
body: string;
};

export const getCommentContextResponseSchema = object({
status: literal('ok'),
commentId: number(),
commentAncestorId: number(),
discussionKey: string(),
discussionWebUrl: string(),
discussionApiUrl: string(),
orderBy: picklist(orderBy),
pageSize: picklist(pageSize),
page: number(),
});
38 changes: 38 additions & 0 deletions dotcom-rendering/src/lib/discussionApi.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import type {
} from './discussion';
import {
discussionApiResponseSchema,
getCommentContextResponseSchema,
parseAbuseResponse,
parseCommentRepliesResponse,
parseCommentResponse,
pickResponseSchema,
postUsernameResponseSchema,
} from './discussion';
import type { CommentContextType } from './discussionFilters';
import type { SignedInWithCookies, SignedInWithOkta } from './identity';
import { getOptionsHeadersWithOkta } from './identity';
import { fetchJSON } from './json';
Expand Down Expand Up @@ -436,3 +438,39 @@ export const getMoreResponses = async (

return parseCommentRepliesResponse(jsonResult.value);
};

const buildParams = (filters: FilterOptions): URLSearchParams => {
return new URLSearchParams({
// Frontend uses the 'recommendations' key to store this options but the api expects
// 'mostRecommended' so we have to map here to support both
orderBy:
filters.orderBy === 'recommendations'
? 'mostRecommended'
: filters.orderBy,
pageSize: String(filters.pageSize),
displayThreaded: String(
filters.threads === 'collapsed' || filters.threads === 'expanded',
),
});
};

export const getCommentContext = async (
ajaxUrl: string,
commentId: number,
filters: FilterOptions,
): Promise<Result<GetDiscussionError, CommentContextType>> => {
const url = joinUrl(ajaxUrl, 'comment', commentId.toString(), 'context');
const params = buildParams(filters);

const jsonResult = await fetchJSON(url + '?' + params.toString());

if (jsonResult.kind === 'error') return jsonResult;

const result = safeParse(getCommentContextResponseSchema, jsonResult.value);

if (!result.success) {
return error('ParsingError');
}

return ok(result.output);
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isOneOf, isString, joinUrl, storage } from '@guardian/libs';
import { isOneOf, isString, storage } from '@guardian/libs';

const orderByTypes = ['newest', 'oldest', 'recommendations'] as const;
const threadTypes = ['collapsed', 'expanded', 'unthreaded'] as const;
Expand All @@ -11,8 +11,8 @@ type PageSizeType = (typeof pageSizeTypes)[number];
/**
* @see http://discussion.guardianapis.com/discussion-api/comment/3519111/context
*/
type CommentContextType = {
status: 'ok' | 'error';
export type CommentContextType = {
status: 'ok';
commentId: number;
commentAncestorId: number;
discussionKey: string;
Expand Down Expand Up @@ -54,46 +54,3 @@ export const initFiltersFromLocalStorage = (): FilterOptions => {
pageSize,
};
};

const buildParams = (filters: FilterOptions) => {
return new URLSearchParams({
// Frontend uses the 'recommendations' key to store this options but the api expects
// 'mostRecommended' so we have to map here to support both
orderBy:
filters.orderBy === 'recommendations'
? 'mostRecommended'
: filters.orderBy,
pageSize: String(filters.pageSize),
displayThreaded: String(
filters.threads === 'collapsed' || filters.threads === 'expanded',
),
});
};

export const getCommentContext = async (
ajaxUrl: string,
commentId: number,
filters: FilterOptions,
): Promise<CommentContextType> => {
const url = joinUrl(ajaxUrl, 'comment', commentId.toString(), 'context');

const params = buildParams(filters);

return fetch(url + '?' + params.toString())
.then((response) => {
if (!response.ok) {
throw Error(
response.statusText ||
`getCommentContext | An api call returned HTTP status ${response.status}`,
);
}
return response;
})
.then((response) => response.json())
.catch((error) => {
window.guardian.modules.sentry.reportError(
error,
'get-comment-page',
);
});
};
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit f950450

Please sign in to comment.