import { useCallback, useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useLocation, useNavigate, useParams } from 'react-router-dom'; 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 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'; import usePublishPostStore from '../../stores/use-publish-post-store'; export const LinkTypePreviewer = ({ link }: { link: string }) => { const { t } = useTranslation(); const mediaInfo = getLinkMediaInfo(link); let type = mediaInfo?.type; const gifFrameUrl = useFetchGifFirstFrame(mediaInfo?.url); if (type === 'gif' && gifFrameUrl !== null) { type = t('animated_gif'); } else if (type === 'gif' && gifFrameUrl === null) { type = t('gif'); } return isValidURL(link) ? type : t('invalid_url'); }; const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid: string }) => { const { t } = useTranslation(); const account = useAccount(); const author = account?.author || {}; const { displayName } = author || {}; const [url, setUrl] = useState(''); const { publishCommentOptions, setPublishPostStore, resetPublishPostStore } = usePublishPostStore(); const { index, publishComment } = usePublishComment(publishCommentOptions); const textRef = useRef(null); const urlRef = useRef(null); const subjectRef = useRef(null); const location = useLocation(); const isInAllView = isAllView(location.pathname, useParams()); const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const subscriptions = account?.subscriptions || []; const defaultSubplebbitAddresses = useDefaultSubplebbitAddresses(); const { anonMode, getNewSigner, getExistingSigner } = useAnonMode(postCid); const comment = useComment({ commentCid: postCid }); const address = comment?.author?.address; const resetFields = () => { if (textRef.current) { textRef.current.value = ''; } if (urlRef.current) { urlRef.current.value = ''; } if (subjectRef.current) { subjectRef.current.value = ''; } }; const hasCalledAnonAddressRef = useRef(false); const getAnonAddressForPost = useCallback(async () => { if (anonMode) { if (!hasCalledAnonAddressRef.current) { hasCalledAnonAddressRef.current = true; const newSigner = (await getNewSigner()) || {}; setPublishPostStore({ signer: newSigner, author: { address: newSigner.address, displayName: displayName || undefined, }, }); } } else { setPublishPostStore({ signer: undefined, author: { address: account?.author?.address, displayName: displayName || undefined, }, }); } }, [anonMode, getNewSigner, account, setPublishPostStore, displayName]); const onPublishPost = () => { const currentTitle = subjectRef.current?.value.trim() || ''; const currentContent = textRef.current?.value.trim() || ''; const currentUrl = urlRef.current?.value.trim() || ''; if (!currentTitle && !currentContent && !currentUrl) { alert(t('empty_comment_alert')); return; } if (currentUrl && !isValidURL(currentUrl)) { alert(t('invalid_url_alert')); return; } if ((isInAllView || isInSubscriptionsView) && !publishCommentOptions.subplebbitAddress) { alert(t('no_board_selected_warning')); return; } if (!isInPostView) { const linkMediaInfo = getLinkMediaInfo(currentUrl); const hasThumbnail = getHasThumbnail(linkMediaInfo, currentUrl); if (!hasThumbnail) { const confirmMessage = t('missing_link_confirm'); if (!window.confirm(confirmMessage)) { return; } } } publishComment(); }; const params = useParams(); const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any }); const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress; useEffect(() => { if (subplebbitAddress) { setPublishPostStore({ subplebbitAddress }); } }, [subplebbitAddress, setPublishPostStore]); // redirect to pending page when pending comment is created const navigate = useNavigate(); useEffect(() => { if (typeof index === 'number') { resetPublishPostStore(); resetFields(); navigate(`/profile/${index}`); } }, [index, resetPublishPostStore, navigate]); // in post page, publish a reply to the post const isInPostView = isPostPageView(location.pathname, params); const cid = params?.commentCid as string; const { setPublishReplyOptions, resetPublishReplyOptions, replyIndex, publishReply } = usePublishReply({ cid, subplebbitAddress }); const getAnonAddressForReply = useCallback(async () => { if (anonMode && !hasCalledAnonAddressRef.current) { hasCalledAnonAddressRef.current = true; const existingSigner = await getExistingSigner(address); if (existingSigner) { setPublishReplyOptions({ signer: existingSigner, author: { address: existingSigner.address, displayName: displayName || undefined, }, }); } else { const newSigner = await getNewSigner(); setPublishReplyOptions({ signer: newSigner, author: { address: newSigner.address, displayName: displayName || undefined, }, }); } } }, [address, getExistingSigner, getNewSigner, setPublishReplyOptions, anonMode, displayName]); const handleContentChange = (e: React.ChangeEvent) => { const formattedContent = formatMarkdown(e.target.value); isInPostView ? setPublishReplyOptions({ content: formattedContent }) : setPublishPostStore({ content: formattedContent }); }; const onPublishReply = () => { const currentContent = textRef.current?.value.trim() || ''; const currentUrl = urlRef.current?.value.trim() || ''; if (!currentContent && !currentUrl) { alert(t('empty_comment_alert')); return; } if (currentUrl && !isValidURL(currentUrl)) { alert(t('invalid_url_alert')); return; } publishReply(); }; useEffect(() => { if (typeof replyIndex === 'number') { resetPublishReplyOptions(); resetFields(); closeForm(); } }, [replyIndex, resetPublishReplyOptions, closeForm]); useEffect(() => { if (anonMode) { if (isInPostView) { getAnonAddressForReply(); } else { getAnonAddressForPost(); } } }, [anonMode, getAnonAddressForPost, getAnonAddressForReply, isInPostView]); return ( {!isInPostView && ( )}
{t('name')} { setAccount({ ...account, author: { ...account?.author, displayName: e.target.value } }); if (isInPostView) { setPublishReplyOptions({ displayName: e.target.value || undefined }); } else { setPublishPostStore({ displayName: e.target.value || undefined }); } }} /> {isInPostView && }
{t('subject')} { setPublishPostStore({ title: e.target.value || undefined }); }} />
{t('comment')}