From e2f07f6fa65f52ac88136de98a68c97207d99bd7 Mon Sep 17 00:00:00 2001 From: Kohei Asai Date: Sun, 28 Jun 2020 15:35:28 -0700 Subject: [PATCH] Add useAnswerCreation React Hook function --- hooks/useAnswerCreation.ts | 83 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 hooks/useAnswerCreation.ts diff --git a/hooks/useAnswerCreation.ts b/hooks/useAnswerCreation.ts new file mode 100644 index 0000000..febb2b0 --- /dev/null +++ b/hooks/useAnswerCreation.ts @@ -0,0 +1,83 @@ +import { useApolloClient } from "@apollo/react-hooks"; +import * as React from "react"; +import { AnswerBody } from "@@/models/Answer"; +import { PostId } from "@@/models/Post"; +import useAuthentication from "@@/hooks/useAuthentication"; +import usePost from "@@/hooks/usePost"; +import createAnswer from "@@/repositories/createAnswer"; + +export default function useAnswerCreation({ postId }: { postId: PostId }) { + const apolloClient = useApolloClient(); + const { authenticationToken } = useAuthentication(); + const { updateLocally } = usePost({ postId }); + const [body, setBody] = React.useState(""); + const [ + bodyValidationErrorTypes, + setBodyValidationErrorTypes, + ] = React.useState(validateBody(body)); + const [isSubmitting, setSubmitting] = React.useState(false); + + const _setBody = (body: string) => { + setBodyValidationErrorTypes(validateBody(body)); + setBody(body); + }; + + const submit = async () => { + if (!authenticationToken) { + throw new Error( + "You called useAnswerCreation().submit() with null authentication token. It shouldn't happen here." + ); + } + + setSubmitting(true); + + const answer = await createAnswer({ + postId, + body: body as AnswerBody, + apolloClient, + authenticationToken, + }); + + updateLocally((post) => { + if (!post) { + return post; + } + + return { + ...post, + answers: [answer, ...post.answers], + }; + }); + + _setBody(""); + setSubmitting(false); + }; + + return { + body, + isValid: bodyValidationErrorTypes.length === 0, + bodyValidationErrorTypes, + isSubmitting, + setBody: _setBody, + submit, + }; +} + +function validateBody(body: string): AnswerBodyValidationErrorType[] { + const validationErrorTypes = []; + + if (body.length < 8) { + validationErrorTypes.push(AnswerBodyValidationErrorType.tooShort); + } + + if (body.length > 65535) { + validationErrorTypes.push(AnswerBodyValidationErrorType.tooLong); + } + + return validationErrorTypes; +} + +export enum AnswerBodyValidationErrorType { + tooShort, + tooLong, +}