diff --git a/src/components/post-form/post-form.tsx b/src/components/post-form/post-form.tsx index 5b397d2f..10229218 100644 --- a/src/components/post-form/post-form.tsx +++ b/src/components/post-form/post-form.tsx @@ -1,111 +1,19 @@ import { useCallback, useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useLocation, useNavigate, useParams } from 'react-router-dom'; -import { - Comment, - PublishCommentOptions, - setAccount, - useAccount, - useAccountComment, - useComment, - useEditedComment, - usePublishComment, - useSubplebbit, -} from '@plebbit/plebbit-react-hooks'; -import { create } from 'zustand'; -import { alertChallengeVerificationFailed } from '../../lib/utils/challenge-utils'; +import { Comment, setAccount, useAccount, useAccountComment, useComment, useEditedComment, usePublishComment, useSubplebbit } from '@plebbit/plebbit-react-hooks'; import { getHasThumbnail, getLinkMediaInfo } from '../../lib/utils/media-utils'; import { formatMarkdown } from '../../lib/utils/post-utils'; import { isValidURL } from '../../lib/utils/url-utils'; import { isAllView, isDescriptionView, isPostPageView, isRulesView, isSubscriptionsView } from '../../lib/utils/view-utils'; import { useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits'; import usePublishReply from '../../hooks/use-publish-reply'; -import useChallengesStore from '../../stores/use-challenges-store'; import styles from './post-form.module.css'; import _ from 'lodash'; import useIsSubplebbitOffline from '../../hooks/use-is-subplebbit-offline'; import useFetchGifFirstFrame from '../../hooks/use-fetch-gif-first-frame'; import useAnonMode from '../../hooks/use-anon-mode'; - -type SubmitState = { - author?: any | undefined; - displayName?: string | undefined; - signer?: any | undefined; - subplebbitAddress: string | undefined; - title: string | undefined; - content: string | undefined; - link: string | undefined; - spoiler: boolean | undefined; - publishCommentOptions: PublishCommentOptions; - setSubmitStore: (data: Partial) => void; - resetSubmitStore: () => void; -}; - -const { addChallenge } = useChallengesStore.getState(); - -const useSubmitStore = create((set) => ({ - author: undefined, - displayName: undefined, - signer: undefined, - subplebbitAddress: undefined, - title: undefined, - content: undefined, - link: undefined, - spoiler: undefined, - publishCommentOptions: {}, - setSubmitStore: ({ author, displayName, signer, subplebbitAddress, title, content, link, spoiler }) => - set((state) => { - const nextState = { ...state }; - if (author !== undefined) nextState.author = author; - if (displayName !== undefined) nextState.displayName = displayName; - if (signer !== undefined) nextState.signer = signer; - if (subplebbitAddress !== undefined) nextState.subplebbitAddress = subplebbitAddress; - if (title !== undefined) nextState.title = title || undefined; - if (content !== undefined) nextState.content = content || undefined; - if (link !== undefined) nextState.link = link || undefined; - if (spoiler !== undefined) nextState.spoiler = spoiler || undefined; - - const publishCommentOptions: PublishCommentOptions = { - subplebbitAddress: nextState.subplebbitAddress, - title: nextState.title, - content: nextState.content, - link: nextState.link, - spoiler: nextState.spoiler, - onChallenge: (...args: any) => addChallenge(args), - onChallengeVerification: alertChallengeVerificationFailed, - onError: (error: Error) => { - console.error(error); - alert(error.message); - }, - }; - - if (nextState.signer) { - publishCommentOptions.signer = nextState.signer; - } - - if (nextState.author || nextState.displayName) { - publishCommentOptions.author = { - ...nextState.author, - displayName: nextState.displayName, - }; - } - - nextState.publishCommentOptions = publishCommentOptions; - return nextState; - }), - resetSubmitStore: () => - set({ - author: undefined, - displayName: undefined, - signer: undefined, - subplebbitAddress: undefined, - title: undefined, - content: undefined, - link: undefined, - spoiler: undefined, - publishCommentOptions: {}, - }), -})); +import usePublishPostStore from '../../stores/use-publish-post-store'; export const LinkTypePreviewer = ({ link }: { link: string }) => { const { t } = useTranslation(); @@ -128,14 +36,14 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid: const author = account?.author || {}; const { displayName } = author || {}; const [url, setUrl] = useState(''); - const { publishCommentOptions, setSubmitStore, resetSubmitStore } = useSubmitStore(); + const { publishCommentOptions, setPublishPostStore, resetPublishPostStore } = usePublishPostStore(); const { index, publishComment } = usePublishComment(publishCommentOptions); useEffect(() => { if (displayName) { - setSubmitStore({ displayName }); + setPublishPostStore({ displayName }); } - }, [displayName, setSubmitStore]); + }, [displayName, setPublishPostStore]); const textRef = useRef(null); const urlRef = useRef(null); @@ -170,7 +78,7 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid: if (!hasCalledAnonAddressRef.current) { hasCalledAnonAddressRef.current = true; const newSigner = (await getNewSigner()) || {}; - setSubmitStore({ + setPublishPostStore({ signer: newSigner, author: { address: newSigner.address, @@ -179,7 +87,7 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid: }); } } else { - setSubmitStore({ + setPublishPostStore({ signer: undefined, author: { address: account?.author?.address, @@ -187,7 +95,7 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid: }, }); } - }, [anonMode, getNewSigner, account, setSubmitStore, displayName]); + }, [anonMode, getNewSigner, account, setPublishPostStore, displayName]); const onPublishPost = () => { const currentTitle = subjectRef.current?.value.trim() || ''; @@ -228,19 +136,19 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid: const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress; useEffect(() => { if (subplebbitAddress) { - setSubmitStore({ subplebbitAddress }); + setPublishPostStore({ subplebbitAddress }); } - }, [subplebbitAddress, setSubmitStore]); + }, [subplebbitAddress, setPublishPostStore]); // redirect to pending page when pending comment is created const navigate = useNavigate(); useEffect(() => { if (typeof index === 'number') { - resetSubmitStore(); + resetPublishPostStore(); resetFields(); navigate(`/profile/${index}`); } - }, [index, resetSubmitStore, navigate]); + }, [index, resetPublishPostStore, navigate]); // in post page, publish a reply to the post const isInPostView = isPostPageView(location.pathname, params); @@ -274,7 +182,7 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid: const handleContentChange = (e: React.ChangeEvent) => { const formattedContent = formatMarkdown(e.target.value); - isInPostView ? setPublishReplyOptions({ content: formattedContent }) : setSubmitStore({ content: formattedContent }); + isInPostView ? setPublishReplyOptions({ content: formattedContent }) : setPublishPostStore({ content: formattedContent }); }; const onPublishReply = () => { @@ -327,7 +235,7 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid: if (isInPostView) { setPublishReplyOptions({ displayName: e.target.value || undefined }); } else { - setSubmitStore({ displayName: e.target.value || undefined }); + setPublishPostStore({ displayName: e.target.value || undefined }); } }} /> @@ -342,7 +250,7 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid: type='text' ref={subjectRef} onChange={(e) => { - setSubmitStore({ title: e.target.value || undefined }); + setPublishPostStore({ title: e.target.value || undefined }); }} /> @@ -366,7 +274,7 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid: ref={urlRef} onChange={(e) => { setUrl(e.target.value); - isInPostView ? setPublishReplyOptions({ link: e.target.value || undefined }) : setSubmitStore({ link: e.target.value || undefined }); + isInPostView ? setPublishReplyOptions({ link: e.target.value || undefined }) : setPublishPostStore({ link: e.target.value || undefined }); }} /> {url && } @@ -379,7 +287,7 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid: @@ -390,7 +298,7 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid: {t('board')} - setPublishPostStore({ subplebbitAddress: e.target.value })} value={subplebbitAddress}> {isInAllView && defaultSubplebbitAddresses.map((address: string) => ( diff --git a/src/hooks/use-publish-reply.ts b/src/hooks/use-publish-reply.ts index c3961868..337d7ce1 100644 --- a/src/hooks/use-publish-reply.ts +++ b/src/hooks/use-publish-reply.ts @@ -1,102 +1,14 @@ import { useCallback } from 'react'; -import { ChallengeVerification, Comment, PublishCommentOptions, useAccount, usePublishComment } from '@plebbit/plebbit-react-hooks'; -import { create } from 'zustand'; -import { alertChallengeVerificationFailed } from '../lib/utils/challenge-utils'; -import useChallengesStore from '../stores/use-challenges-store'; +import { useAccount, usePublishComment } from '@plebbit/plebbit-react-hooks'; import useAnonMode from './use-anon-mode'; +import usePublishReplyStore, { SetReplyStoreData } from '../stores/use-publish-reply-store'; -type SetReplyStoreData = { - subplebbitAddress: string; - parentCid: string; - author?: any; - displayName?: string; - content: string; - link?: string; - signer?: any; - spoiler: boolean; -}; - -type ReplyState = { - author: { [parentCid: string]: any | undefined }; - displayName: { [parentCid: string]: string | undefined }; - content: { [parentCid: string]: string | undefined }; - link: { [parentCid: string]: string | undefined }; - signer: { [parentCid: string]: any | undefined }; - spoiler: { [parentCid: string]: boolean | undefined }; - publishCommentOptions: { [parentCid: string]: PublishCommentOptions | undefined }; - setReplyStore: (data: SetReplyStoreData) => void; - resetReplyStore: (parentCid: string) => void; -}; - -const { addChallenge } = useChallengesStore.getState(); - -const useReplyStore = create((set) => ({ - author: {}, - displayName: {}, - content: {}, - link: {}, - signer: {}, - spoiler: {}, - publishCommentOptions: {}, - - setReplyStore: (data: SetReplyStoreData) => - set((state) => { - const { subplebbitAddress, parentCid, author, displayName, content, link, signer, spoiler } = data; - const updatedAuthor = displayName ? { ...author, displayName } : author; - - const publishCommentOptions: PublishCommentOptions = { - subplebbitAddress, - parentCid, - content, - link, - spoiler, - onChallenge: (...args: any) => addChallenge(args), - onChallengeVerification: (challengeVerification: ChallengeVerification, comment: Comment) => { - alertChallengeVerificationFailed(challengeVerification, comment); - }, - onError: (error: Error) => { - console.error(error); - alert(error.message); - }, - }; - - if (updatedAuthor) { - publishCommentOptions.author = updatedAuthor; - } - - if (signer) { - publishCommentOptions.signer = signer; - } - - return { - author: { ...state.author, [parentCid]: updatedAuthor }, - displayName: { ...state.displayName, [parentCid]: displayName }, - content: { ...state.content, [parentCid]: content }, - link: { ...state.link, [parentCid]: link }, - signer: { ...state.signer, [parentCid]: signer }, - spoiler: { ...state.spoiler, [parentCid]: spoiler }, - publishCommentOptions: { ...state.publishCommentOptions, [parentCid]: publishCommentOptions }, - }; - }), - - resetReplyStore: (parentCid) => - set((state) => ({ - author: { ...state.author, [parentCid]: undefined }, - displayName: { ...state.displayName, [parentCid]: undefined }, - content: { ...state.content, [parentCid]: undefined }, - link: { ...state.link, [parentCid]: undefined }, - signer: { ...state.signer, [parentCid]: undefined }, - spoiler: { ...state.spoiler, [parentCid]: undefined }, - publishCommentOptions: { ...state.publishCommentOptions, [parentCid]: undefined }, - })), -})); - -const useReply = ({ cid, subplebbitAddress }: { cid: string; subplebbitAddress: string }) => { +const usePublishReply = ({ cid, subplebbitAddress }: { cid: string; subplebbitAddress: string }) => { const parentCid = cid; const account = useAccount(); const { anonMode } = useAnonMode(); - const { author, signer, content, link, spoiler, publishCommentOptions } = useReplyStore((state) => ({ + const { author, signer, content, link, spoiler, publishCommentOptions } = usePublishReplyStore((state) => ({ author: state.author[parentCid] || (account?.author ? { displayName: account.author.displayName || undefined } : undefined), displayName: state.displayName[parentCid] || account?.author?.displayName, signer: state.signer[parentCid], @@ -106,8 +18,8 @@ const useReply = ({ cid, subplebbitAddress }: { cid: string; subplebbitAddress: publishCommentOptions: state.publishCommentOptions[parentCid], })); - const setReplyStore = useReplyStore((state) => state.setReplyStore); - const resetReplyStore = useReplyStore((state) => state.resetReplyStore); + const setReplyStore = usePublishReplyStore((state) => state.setReplyStore); + const resetReplyStore = usePublishReplyStore((state) => state.resetReplyStore); const setPublishReplyOptions = useCallback( (options: Partial) => { @@ -151,4 +63,4 @@ const useReply = ({ cid, subplebbitAddress }: { cid: string; subplebbitAddress: return { setPublishReplyOptions, resetPublishReplyOptions, replyIndex: index, publishReply: publishComment, setReplyStore }; }; -export default useReply; +export default usePublishReply; diff --git a/src/stores/use-publish-post-store.ts b/src/stores/use-publish-post-store.ts new file mode 100644 index 00000000..a96b141b --- /dev/null +++ b/src/stores/use-publish-post-store.ts @@ -0,0 +1,86 @@ +import { PublishCommentOptions } from '@plebbit/plebbit-react-hooks'; +import { create } from 'zustand'; +import { alertChallengeVerificationFailed } from '../lib/utils/challenge-utils'; +import useChallengesStore from './use-challenges-store'; + +type SubmitState = { + author?: any | undefined; + displayName?: string | undefined; + signer?: any | undefined; + subplebbitAddress: string | undefined; + title: string | undefined; + content: string | undefined; + link: string | undefined; + spoiler: boolean | undefined; + publishCommentOptions: PublishCommentOptions; + setPublishPostStore: (data: Partial) => void; + resetPublishPostStore: () => void; +}; + +const { addChallenge } = useChallengesStore.getState(); + +const usePublishPostStore = create((set) => ({ + author: undefined, + displayName: undefined, + signer: undefined, + subplebbitAddress: undefined, + title: undefined, + content: undefined, + link: undefined, + spoiler: undefined, + publishCommentOptions: {}, + setPublishPostStore: ({ author, displayName, signer, subplebbitAddress, title, content, link, spoiler }) => + set((state) => { + const nextState = { ...state }; + if (author !== undefined) nextState.author = author; + if (displayName !== undefined) nextState.displayName = displayName; + if (signer !== undefined) nextState.signer = signer; + if (subplebbitAddress !== undefined) nextState.subplebbitAddress = subplebbitAddress; + if (title !== undefined) nextState.title = title || undefined; + if (content !== undefined) nextState.content = content || undefined; + if (link !== undefined) nextState.link = link || undefined; + if (spoiler !== undefined) nextState.spoiler = spoiler || undefined; + + const publishCommentOptions: PublishCommentOptions = { + subplebbitAddress: nextState.subplebbitAddress, + title: nextState.title, + content: nextState.content, + link: nextState.link, + spoiler: nextState.spoiler, + onChallenge: (...args: any) => addChallenge(args), + onChallengeVerification: alertChallengeVerificationFailed, + onError: (error: Error) => { + console.error(error); + alert(error.message); + }, + }; + + if (nextState.signer) { + publishCommentOptions.signer = nextState.signer; + } + + if (nextState.author || nextState.displayName) { + publishCommentOptions.author = { + ...nextState.author, + displayName: nextState.displayName, + }; + } + + nextState.publishCommentOptions = publishCommentOptions; + return nextState; + }), + resetPublishPostStore: () => + set({ + author: undefined, + displayName: undefined, + signer: undefined, + subplebbitAddress: undefined, + title: undefined, + content: undefined, + link: undefined, + spoiler: undefined, + publishCommentOptions: {}, + }), +})); + +export default usePublishPostStore; diff --git a/src/stores/use-publish-reply-store.ts b/src/stores/use-publish-reply-store.ts new file mode 100644 index 00000000..fe8d06e8 --- /dev/null +++ b/src/stores/use-publish-reply-store.ts @@ -0,0 +1,92 @@ +import { ChallengeVerification, Comment, PublishCommentOptions } from '@plebbit/plebbit-react-hooks'; +import { create } from 'zustand'; +import { alertChallengeVerificationFailed } from '../lib/utils/challenge-utils'; +import useChallengesStore from './use-challenges-store'; + +export type SetReplyStoreData = { + subplebbitAddress: string; + parentCid: string; + author?: any; + displayName?: string; + content: string; + link?: string; + signer?: any; + spoiler: boolean; +}; + +type ReplyState = { + author: { [parentCid: string]: any | undefined }; + displayName: { [parentCid: string]: string | undefined }; + content: { [parentCid: string]: string | undefined }; + link: { [parentCid: string]: string | undefined }; + signer: { [parentCid: string]: any | undefined }; + spoiler: { [parentCid: string]: boolean | undefined }; + publishCommentOptions: { [parentCid: string]: PublishCommentOptions | undefined }; + setReplyStore: (data: SetReplyStoreData) => void; + resetReplyStore: (parentCid: string) => void; +}; + +const { addChallenge } = useChallengesStore.getState(); + +const usePublishReplyStore = create((set) => ({ + author: {}, + displayName: {}, + content: {}, + link: {}, + signer: {}, + spoiler: {}, + publishCommentOptions: {}, + + setReplyStore: (data: SetReplyStoreData) => + set((state) => { + const { subplebbitAddress, parentCid, author, displayName, content, link, signer, spoiler } = data; + const updatedAuthor = displayName ? { ...author, displayName } : author; + + const publishCommentOptions: PublishCommentOptions = { + subplebbitAddress, + parentCid, + content, + link, + spoiler, + onChallenge: (...args: any) => addChallenge(args), + onChallengeVerification: (challengeVerification: ChallengeVerification, comment: Comment) => { + alertChallengeVerificationFailed(challengeVerification, comment); + }, + onError: (error: Error) => { + console.error(error); + alert(error.message); + }, + }; + + if (updatedAuthor) { + publishCommentOptions.author = updatedAuthor; + } + + if (signer) { + publishCommentOptions.signer = signer; + } + + return { + author: { ...state.author, [parentCid]: updatedAuthor }, + displayName: { ...state.displayName, [parentCid]: displayName }, + content: { ...state.content, [parentCid]: content }, + link: { ...state.link, [parentCid]: link }, + signer: { ...state.signer, [parentCid]: signer }, + spoiler: { ...state.spoiler, [parentCid]: spoiler }, + publishCommentOptions: { ...state.publishCommentOptions, [parentCid]: publishCommentOptions }, + }; + }), + + resetReplyStore: (parentCid) => + set((state) => ({ + author: { ...state.author, [parentCid]: undefined }, + displayName: { ...state.displayName, [parentCid]: undefined }, + content: { ...state.content, [parentCid]: undefined }, + link: { ...state.link, [parentCid]: undefined }, + signer: { ...state.signer, [parentCid]: undefined }, + spoiler: { ...state.spoiler, [parentCid]: undefined }, + publishCommentOptions: { ...state.publishCommentOptions, [parentCid]: undefined }, + })), +})); + +export default usePublishReplyStore;