From b29c87e038ed581fcea48e7f0ee847f66ab25dcd Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Wed, 3 Apr 2024 05:53:38 +0800 Subject: [PATCH 1/6] fix: making a comment through header actions --- .../src/components/comments/CommentInputPage.tsx | 2 ++ .../fields/MarkdownInput/CommentMarkdownInput.tsx | 14 +++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/shared/src/components/comments/CommentInputPage.tsx b/packages/shared/src/components/comments/CommentInputPage.tsx index 285554c97b..068daa57ff 100644 --- a/packages/shared/src/components/comments/CommentInputPage.tsx +++ b/packages/shared/src/components/comments/CommentInputPage.tsx @@ -144,9 +144,11 @@ const CommentInputPage = ({ showSubmit={false} showUserAvatar={false} onChange={setValue} + mutateRef={mutateRef} style={{ height: `${styleHeight}px`, }} + onCommented={router.back} /> {shouldShowCta && ( ({ - mutateComment, - isLoading, - isSuccess, - })); + useImperativeHandle( + mutateRef, + () => ({ + mutateComment, + isLoading, + isSuccess, + }), + [mutateComment, isLoading, isSuccess], + ); const onSubmitForm: FormEventHandler = (e) => { e.preventDefault(); From def34c952c2d5630e9065de2022b2ea7573a7906 Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Wed, 3 Apr 2024 06:25:01 +0800 Subject: [PATCH 2/6] refactor: unnecessary hooks --- .../comments/CommentInputOrPage.tsx | 15 ++++++++- .../components/comments/CommentInputPage.tsx | 28 +++++++--------- .../MarkdownInput/CommentMarkdownInput.tsx | 33 +++++-------------- 3 files changed, 34 insertions(+), 42 deletions(-) diff --git a/packages/shared/src/components/comments/CommentInputOrPage.tsx b/packages/shared/src/components/comments/CommentInputOrPage.tsx index ae134dc81a..4d92a2c825 100644 --- a/packages/shared/src/components/comments/CommentInputOrPage.tsx +++ b/packages/shared/src/components/comments/CommentInputOrPage.tsx @@ -5,6 +5,7 @@ import { CommentMarkdownInputProps, } from '../fields/MarkdownInput/CommentMarkdownInput'; import { ViewSize, useViewSize } from '../../hooks'; +import { useMutateComment } from '../../hooks/post/useMutateComment'; interface CommentInputOrPageProps extends Omit { @@ -23,6 +24,12 @@ export default function CommentInputOrPage({ }: CommentInputOrPageProps): ReactElement { const isMobile = useViewSize(ViewSize.MobileL); const router = useRouter(); + const mutateCommentResult = useMutateComment({ + post: props.post, + editCommentId: props.editCommentId, + parentCommentId: props.parentCommentId, + onCommented: props.onCommented, + }); if (isMobile) { const commentId = props.editCommentId ?? 'new'; @@ -44,5 +51,11 @@ export default function CommentInputOrPage({ return null; } - return ; + return ( + + ); } diff --git a/packages/shared/src/components/comments/CommentInputPage.tsx b/packages/shared/src/components/comments/CommentInputPage.tsx index 068daa57ff..480a81d388 100644 --- a/packages/shared/src/components/comments/CommentInputPage.tsx +++ b/packages/shared/src/components/comments/CommentInputPage.tsx @@ -1,15 +1,9 @@ -import React, { - ReactElement, - useEffect, - useMemo, - useRef, - useState, -} from 'react'; +import React, { ReactElement, useEffect, useMemo, useState } from 'react'; import classNames from 'classnames'; import { useRouter } from 'next/router'; import { FormWrapper } from '../fields/form'; import { CommentMarkdownInput } from '../fields/MarkdownInput/CommentMarkdownInput'; -import { UseMutateCommentResult } from '../../hooks/post/useMutateComment'; +import { useMutateComment } from '../../hooks/post/useMutateComment'; import { useVisualViewport } from '../../hooks/utils/useVisualViewport'; import { COMMENT_BY_ID_WITH_POST_QUERY } from '../../graphql/comments'; import useCommentById from '../../hooks/comments/useCommentById'; @@ -36,7 +30,6 @@ const CommentInputPage = ({ editCommentId, replyCommentId, }: Props): ReactElement => { - const [value, setValue] = useState(''); const [styleHeight, setStyleHeight] = useState('auto'); const { user } = useAuthContext(); const router = useRouter(); @@ -65,8 +58,13 @@ const CommentInputPage = ({ () => comment?.parent?.id ?? replyCommentId, [comment, replyCommentId], ); - const mutateRef = useRef(); - const { mutateComment, isLoading, isSuccess } = mutateRef?.current ?? {}; + const mutateCommentResult = useMutateComment({ + post, + editCommentId, + parentCommentId, + onCommented: router.back, + }); + const { isLoading, isSuccess } = mutateCommentResult; const { height } = useVisualViewport(); const replyHeight = height > 0 ? replySize : 0; @@ -100,7 +98,7 @@ const CommentInputPage = ({ return (
{ await onSubmitted(); - mutateComment(value); }, loading: isLoading, disabled: isSuccess, @@ -143,12 +140,11 @@ const CommentInputPage = ({ }} showSubmit={false} showUserAvatar={false} - onChange={setValue} - mutateRef={mutateRef} + mutateCommentResult={mutateCommentResult} style={{ height: `${styleHeight}px`, }} - onCommented={router.back} + formProps={{ id: 'write-comment' }} /> {shouldShowCta && ( void; - mutateRef?: React.MutableRefObject; + mutateCommentResult?: UseMutateCommentResult; + formProps?: FormHTMLAttributes; } export function CommentMarkdownInput({ post, - parentCommentId, initialContent, replyTo, editCommentId, className = {}, style, - onCommented, onChange, showSubmit = true, showUserAvatar = true, - mutateRef, + mutateCommentResult, + formProps = {}, }: CommentMarkdownInputProps): ReactElement { const postId = post?.id; const sourceId = post?.source?.id; const markdownRef = useRef(); - const { mutateComment, isLoading, isSuccess } = useMutateComment({ - post, - editCommentId, - parentCommentId, - onCommented, - }); - useImperativeHandle( - mutateRef, - () => ({ - mutateComment, - isLoading, - isSuccess, - }), - [mutateComment, isLoading, isSuccess], - ); - + const { mutateComment, isLoading, isSuccess } = mutateCommentResult; const onSubmitForm: FormEventHandler = (e) => { e.preventDefault(); @@ -96,6 +78,7 @@ export function CommentMarkdownInput({ return (
Date: Wed, 3 Apr 2024 06:33:38 +0800 Subject: [PATCH 3/6] fix: avoid re-commenting --- packages/shared/src/hooks/post/useMutateComment.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/shared/src/hooks/post/useMutateComment.ts b/packages/shared/src/hooks/post/useMutateComment.ts index 9b5f359e2e..b6c8a813f2 100644 --- a/packages/shared/src/hooks/post/useMutateComment.ts +++ b/packages/shared/src/hooks/post/useMutateComment.ts @@ -152,10 +152,15 @@ export const useMutateComment = ({ isLoading: isCommenting, isSuccess, } = useMutation( - (variables) => - requestMethod(graphqlUrl, mutation, variables, { + (variables) => { + if (isCommenting || isSuccess) { + return Promise.resolve(null); + } + + return requestMethod(graphqlUrl, mutation, variables, { requestKey: JSON.stringify(key), - }), + }); + }, { onSuccess: (data) => onSuccess(data?.comment), }, From 35beed1268f1de351a131707e24586ab3a01bf53 Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Wed, 3 Apr 2024 06:42:00 +0800 Subject: [PATCH 4/6] refactor: usage of context --- .../comments/CommentInputOrPage.tsx | 9 +- .../components/comments/CommentInputPage.tsx | 128 +++++++++--------- .../MarkdownInput/CommentMarkdownInput.tsx | 8 +- .../src/contexts/WriteCommentContext.ts | 13 ++ 4 files changed, 86 insertions(+), 72 deletions(-) create mode 100644 packages/shared/src/contexts/WriteCommentContext.ts diff --git a/packages/shared/src/components/comments/CommentInputOrPage.tsx b/packages/shared/src/components/comments/CommentInputOrPage.tsx index 4d92a2c825..2b152d7c9f 100644 --- a/packages/shared/src/components/comments/CommentInputOrPage.tsx +++ b/packages/shared/src/components/comments/CommentInputOrPage.tsx @@ -6,6 +6,7 @@ import { } from '../fields/MarkdownInput/CommentMarkdownInput'; import { ViewSize, useViewSize } from '../../hooks'; import { useMutateComment } from '../../hooks/post/useMutateComment'; +import { WriteCommentContext } from '../../contexts/WriteCommentContext'; interface CommentInputOrPageProps extends Omit { @@ -52,10 +53,8 @@ export default function CommentInputOrPage({ } return ( - + + + ); } diff --git a/packages/shared/src/components/comments/CommentInputPage.tsx b/packages/shared/src/components/comments/CommentInputPage.tsx index 480a81d388..071812f16f 100644 --- a/packages/shared/src/components/comments/CommentInputPage.tsx +++ b/packages/shared/src/components/comments/CommentInputPage.tsx @@ -12,6 +12,7 @@ import { Switch } from '../fields/Switch'; import { useNotificationToggle } from '../../hooks/notifications'; import { NotificationPromptSource } from '../../lib/analytics'; import { Post } from '../../graphql/posts'; +import { WriteCommentContext } from '../../contexts/WriteCommentContext'; // statically defined heights of various containers that // affect final height of the input container @@ -96,71 +97,72 @@ const CommentInputPage = ({ }, [isEdit, isReply, comment, user?.id]); return ( -
- { - await onSubmitted(); - }, - loading: isLoading, - disabled: isSuccess, - }} - className={{ - container: 'flex-1 first:!border-none', - header: 'sticky top-0 z-2 w-full bg-background-default', - }} - > - {isReply && comment && ( -
- Reply to - - {comment.author?.username} - -
- )} - +
+ { + await onSubmitted(); + }, + loading: isLoading, + disabled: isSuccess, }} - showSubmit={false} - showUserAvatar={false} - mutateCommentResult={mutateCommentResult} - style={{ - height: `${styleHeight}px`, + className={{ + container: 'flex-1 first:!border-none', + header: 'sticky top-0 z-2 w-full bg-background-default', }} - formProps={{ id: 'write-comment' }} - /> - {shouldShowCta && ( - - Receive updates when other members engage - - )} - -
+ > + {isReply && comment && ( +
+ Reply to + + {comment.author?.username} + +
+ )} + + {shouldShowCta && ( + + Receive updates when other members engage + + )} +
+
+ ); }; diff --git a/packages/shared/src/components/fields/MarkdownInput/CommentMarkdownInput.tsx b/packages/shared/src/components/fields/MarkdownInput/CommentMarkdownInput.tsx index 5b7deccd5c..a83290c700 100644 --- a/packages/shared/src/components/fields/MarkdownInput/CommentMarkdownInput.tsx +++ b/packages/shared/src/components/fields/MarkdownInput/CommentMarkdownInput.tsx @@ -12,7 +12,7 @@ import MarkdownInput, { MarkdownRef } from './index'; import { Comment } from '../../../graphql/comments'; import { formToJson } from '../../../lib/form'; import { Post } from '../../../graphql/posts'; -import { UseMutateCommentResult } from '../../../hooks/post/useMutateComment'; +import { useWriteCommentContext } from '../../../contexts/WriteCommentContext'; export interface CommentClassName { container?: string; @@ -37,7 +37,6 @@ export interface CommentMarkdownInputProps { showSubmit?: boolean; showUserAvatar?: boolean; onChange?: (value: string) => void; - mutateCommentResult?: UseMutateCommentResult; formProps?: FormHTMLAttributes; } @@ -51,13 +50,14 @@ export function CommentMarkdownInput({ onChange, showSubmit = true, showUserAvatar = true, - mutateCommentResult, formProps = {}, }: CommentMarkdownInputProps): ReactElement { const postId = post?.id; const sourceId = post?.source?.id; const markdownRef = useRef(); - const { mutateComment, isLoading, isSuccess } = mutateCommentResult; + const { + mutateCommentResult: { mutateComment, isLoading, isSuccess }, + } = useWriteCommentContext(); const onSubmitForm: FormEventHandler = (e) => { e.preventDefault(); diff --git a/packages/shared/src/contexts/WriteCommentContext.ts b/packages/shared/src/contexts/WriteCommentContext.ts new file mode 100644 index 0000000000..e645bed711 --- /dev/null +++ b/packages/shared/src/contexts/WriteCommentContext.ts @@ -0,0 +1,13 @@ +import { createContext, useContext } from 'react'; +import { UseMutateCommentResult } from '../hooks/post/useMutateComment'; + +interface WriteCommentContextProp { + mutateCommentResult: UseMutateCommentResult; +} + +export const WriteCommentContext = createContext({ + mutateCommentResult: null, +}); + +export const useWriteCommentContext = (): WriteCommentContextProp => + useContext(WriteCommentContext); From cbe607e9f7215ad8751555a984ae186d342e14de Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Wed, 3 Apr 2024 06:51:00 +0800 Subject: [PATCH 5/6] refactor: placement of checks --- .../fields/MarkdownInput/CommentMarkdownInput.tsx | 8 ++++++++ packages/shared/src/hooks/post/useMutateComment.ts | 11 +++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/shared/src/components/fields/MarkdownInput/CommentMarkdownInput.tsx b/packages/shared/src/components/fields/MarkdownInput/CommentMarkdownInput.tsx index a83290c700..1aba8835f6 100644 --- a/packages/shared/src/components/fields/MarkdownInput/CommentMarkdownInput.tsx +++ b/packages/shared/src/components/fields/MarkdownInput/CommentMarkdownInput.tsx @@ -61,12 +61,20 @@ export function CommentMarkdownInput({ const onSubmitForm: FormEventHandler = (e) => { e.preventDefault(); + if (isLoading || isSuccess) { + return null; + } + const { content } = formToJson<{ content: string }>(e.currentTarget); return mutateComment(content); }; const onKeyboardSubmit: FormEventHandler = (e) => { + if (isLoading || isSuccess) { + return null; + } + const content = e.currentTarget.value; return mutateComment(content); diff --git a/packages/shared/src/hooks/post/useMutateComment.ts b/packages/shared/src/hooks/post/useMutateComment.ts index b6c8a813f2..9b5f359e2e 100644 --- a/packages/shared/src/hooks/post/useMutateComment.ts +++ b/packages/shared/src/hooks/post/useMutateComment.ts @@ -152,15 +152,10 @@ export const useMutateComment = ({ isLoading: isCommenting, isSuccess, } = useMutation( - (variables) => { - if (isCommenting || isSuccess) { - return Promise.resolve(null); - } - - return requestMethod(graphqlUrl, mutation, variables, { + (variables) => + requestMethod(graphqlUrl, mutation, variables, { requestKey: JSON.stringify(key), - }); - }, + }), { onSuccess: (data) => onSuccess(data?.comment), }, From 378e727ffc8aa6983c2416ff8e49726206e1e6b9 Mon Sep 17 00:00:00 2001 From: Lee Hansel Solevilla Date: Wed, 3 Apr 2024 06:51:33 +0800 Subject: [PATCH 6/6] refactor: prop name --- .../shared/src/components/comments/CommentInputOrPage.tsx | 4 +++- packages/shared/src/components/comments/CommentInputPage.tsx | 4 +++- .../components/fields/MarkdownInput/CommentMarkdownInput.tsx | 2 +- packages/shared/src/contexts/WriteCommentContext.ts | 4 ++-- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/shared/src/components/comments/CommentInputOrPage.tsx b/packages/shared/src/components/comments/CommentInputOrPage.tsx index 2b152d7c9f..d7549a2fbb 100644 --- a/packages/shared/src/components/comments/CommentInputOrPage.tsx +++ b/packages/shared/src/components/comments/CommentInputOrPage.tsx @@ -53,7 +53,9 @@ export default function CommentInputOrPage({ } return ( - + ); diff --git a/packages/shared/src/components/comments/CommentInputPage.tsx b/packages/shared/src/components/comments/CommentInputPage.tsx index 071812f16f..fe94752fa3 100644 --- a/packages/shared/src/components/comments/CommentInputPage.tsx +++ b/packages/shared/src/components/comments/CommentInputPage.tsx @@ -97,7 +97,9 @@ const CommentInputPage = ({ }, [isEdit, isReply, comment, user?.id]); return ( - +
(); const { - mutateCommentResult: { mutateComment, isLoading, isSuccess }, + mutateComment: { mutateComment, isLoading, isSuccess }, } = useWriteCommentContext(); const onSubmitForm: FormEventHandler = (e) => { e.preventDefault(); diff --git a/packages/shared/src/contexts/WriteCommentContext.ts b/packages/shared/src/contexts/WriteCommentContext.ts index e645bed711..20114a54e6 100644 --- a/packages/shared/src/contexts/WriteCommentContext.ts +++ b/packages/shared/src/contexts/WriteCommentContext.ts @@ -2,11 +2,11 @@ import { createContext, useContext } from 'react'; import { UseMutateCommentResult } from '../hooks/post/useMutateComment'; interface WriteCommentContextProp { - mutateCommentResult: UseMutateCommentResult; + mutateComment: UseMutateCommentResult; } export const WriteCommentContext = createContext({ - mutateCommentResult: null, + mutateComment: null, }); export const useWriteCommentContext = (): WriteCommentContextProp =>